|
|
@ -873,6 +873,9 @@ static void handle_pdfname(struct pdf_struct *pdf, struct pdf_obj *obj, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char *pdf_readstring(const char *q0, int len, const char *key, unsigned *slen); |
|
|
|
|
|
|
|
static int pdf_readint(const char *q0, int len, const char *key); |
|
|
|
|
|
|
|
static const char *pdf_getdict(const char *q0, int* len, const char *key); |
|
|
|
static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj) |
|
|
|
static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj) |
|
|
|
{ |
|
|
|
{ |
|
|
|
/* enough to hold common pdf names, we don't need all the names */ |
|
|
|
/* enough to hold common pdf names, we don't need all the names */ |
|
|
@ -948,8 +951,17 @@ static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj) |
|
|
|
|
|
|
|
|
|
|
|
handle_pdfname(pdf, obj, pdfname, escapes, &objstate); |
|
|
|
handle_pdfname(pdf, obj, pdfname, escapes, &objstate); |
|
|
|
if (objstate == STATE_LINEARIZED) { |
|
|
|
if (objstate == STATE_LINEARIZED) { |
|
|
|
|
|
|
|
long trailer_end, trailer; |
|
|
|
pdfobj_flag(pdf, obj, LINEARIZED_PDF); |
|
|
|
pdfobj_flag(pdf, obj, LINEARIZED_PDF); |
|
|
|
objstate = STATE_NONE; |
|
|
|
objstate = STATE_NONE; |
|
|
|
|
|
|
|
trailer_end = pdf_readint(q, dict_length, "/H"); |
|
|
|
|
|
|
|
trailer = trailer_end - 1024; |
|
|
|
|
|
|
|
if (trailer < 0) trailer = 0; |
|
|
|
|
|
|
|
q2 = pdf->map + trailer; |
|
|
|
|
|
|
|
cli_dbgmsg("cli_pdf: looking for trailer in linearized pdf: %d - %d\n", trailer, trailer_end); |
|
|
|
|
|
|
|
pdf->fileID = pdf_readstring(q2, trailer_end - trailer, "/ID", &pdf->fileIDlen); |
|
|
|
|
|
|
|
if (pdf->fileID) |
|
|
|
|
|
|
|
cli_dbgmsg("found fileID\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
if (objstate == STATE_LAUNCHACTION) |
|
|
|
if (objstate == STATE_LAUNCHACTION) |
|
|
|
pdfobj_flag(pdf, obj, HAS_LAUNCHACTION); |
|
|
|
pdfobj_flag(pdf, obj, HAS_LAUNCHACTION); |
|
|
@ -1319,14 +1331,17 @@ static void pdf_handle_enc(struct pdf_struct *pdf) |
|
|
|
char *O, *U; |
|
|
|
char *O, *U; |
|
|
|
const char *q, *q2; |
|
|
|
const char *q, *q2; |
|
|
|
|
|
|
|
|
|
|
|
if (pdf->enc_objid == ~0u || !pdf->fileID) |
|
|
|
if (pdf->enc_objid == ~0u) |
|
|
|
return; |
|
|
|
return; |
|
|
|
obj = find_obj(pdf, pdf->objs, pdf->enc_objid); |
|
|
|
if (!pdf->fileID) { |
|
|
|
if (!obj) |
|
|
|
cli_dbgmsg("cli_pdf: pdf_handle_enc no file ID\n"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
required_flags = (1 << OBJ_HASFILTERS) | (1 << OBJ_FILTER_STANDARD); |
|
|
|
} |
|
|
|
if (!(obj->flags & required_flags)) |
|
|
|
obj = find_obj(pdf, pdf->objs, pdf->enc_objid); |
|
|
|
|
|
|
|
if (!obj) { |
|
|
|
|
|
|
|
cli_dbgmsg("cli_pdf: can't find encrypted object %d %d\n", pdf->enc_objid>>8, pdf->enc_objid&0xff); |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
len = obj_size(pdf, obj, 1); |
|
|
|
len = obj_size(pdf, obj, 1); |
|
|
|
q = pdf->map + obj->start; |
|
|
|
q = pdf->map + obj->start; |
|
|
|
|
|
|
|
|
|
|
@ -1338,21 +1353,25 @@ static void pdf_handle_enc(struct pdf_struct *pdf) |
|
|
|
cli_dbgmsg("cli_pdf: invalid P\n"); |
|
|
|
cli_dbgmsg("cli_pdf: invalid P\n"); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
length = pdf_readint(q, len, "/Length"); |
|
|
|
|
|
|
|
if (length == ~0u) |
|
|
|
|
|
|
|
length = 40; |
|
|
|
|
|
|
|
if (length < 40) { |
|
|
|
|
|
|
|
cli_dbgmsg("cli_pdf: invalid length: %d\n", length); |
|
|
|
|
|
|
|
length = 40; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
q2 = cli_memstr(q, len, "/Standard", 9); |
|
|
|
q2 = cli_memstr(q, len, "/Standard", 9); |
|
|
|
if (!q2) { |
|
|
|
if (!q2) { |
|
|
|
cli_dbgmsg("cli_pdf: /Standard not found\n"); |
|
|
|
cli_dbgmsg("cli_pdf: /Standard not found\n"); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
len -= q2-q; |
|
|
|
/* we can have both of these:
|
|
|
|
q = q2; |
|
|
|
* /AESV2/Length /Standard/Length |
|
|
|
|
|
|
|
* /Length /Standard |
|
|
|
|
|
|
|
* make sure we don't mistake AES's length for Standard's */ |
|
|
|
|
|
|
|
length = pdf_readint(q2, len - (q2 - q), "/Length"); |
|
|
|
|
|
|
|
if (length == ~0u) |
|
|
|
|
|
|
|
length = pdf_readint(q, len, "/Length"); |
|
|
|
|
|
|
|
if (length == ~0u) |
|
|
|
|
|
|
|
length = 40; |
|
|
|
|
|
|
|
if (length < 40) { |
|
|
|
|
|
|
|
cli_dbgmsg("cli_pdf: invalid length: %d\n", length); |
|
|
|
|
|
|
|
length = 40; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
R = pdf_readint(q, len, "/R"); |
|
|
|
R = pdf_readint(q, len, "/R"); |
|
|
|
if (R == ~0u) { |
|
|
|
if (R == ~0u) { |
|
|
|