...
|
...
|
@@ -873,6 +873,9 @@ static void handle_pdfname(struct pdf_struct *pdf, struct pdf_obj *obj,
|
873
|
873
|
}
|
874
|
874
|
}
|
875
|
875
|
|
|
876
|
+static char *pdf_readstring(const char *q0, int len, const char *key, unsigned *slen);
|
|
877
|
+static int pdf_readint(const char *q0, int len, const char *key);
|
|
878
|
+static const char *pdf_getdict(const char *q0, int* len, const char *key);
|
876
|
879
|
static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
877
|
880
|
{
|
878
|
881
|
/* 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)
|
948
|
948
|
|
949
|
949
|
handle_pdfname(pdf, obj, pdfname, escapes, &objstate);
|
950
|
950
|
if (objstate == STATE_LINEARIZED) {
|
|
951
|
+ long trailer_end, trailer;
|
951
|
952
|
pdfobj_flag(pdf, obj, LINEARIZED_PDF);
|
952
|
953
|
objstate = STATE_NONE;
|
|
954
|
+ trailer_end = pdf_readint(q, dict_length, "/H");
|
|
955
|
+ trailer = trailer_end - 1024;
|
|
956
|
+ if (trailer < 0) trailer = 0;
|
|
957
|
+ q2 = pdf->map + trailer;
|
|
958
|
+ cli_dbgmsg("cli_pdf: looking for trailer in linearized pdf: %d - %d\n", trailer, trailer_end);
|
|
959
|
+ pdf->fileID = pdf_readstring(q2, trailer_end - trailer, "/ID", &pdf->fileIDlen);
|
|
960
|
+ if (pdf->fileID)
|
|
961
|
+ cli_dbgmsg("found fileID\n");
|
953
|
962
|
}
|
954
|
963
|
if (objstate == STATE_LAUNCHACTION)
|
955
|
964
|
pdfobj_flag(pdf, obj, HAS_LAUNCHACTION);
|
...
|
...
|
@@ -1319,14 +1331,17 @@ static void pdf_handle_enc(struct pdf_struct *pdf)
|
1319
|
1319
|
char *O, *U;
|
1320
|
1320
|
const char *q, *q2;
|
1321
|
1321
|
|
1322
|
|
- if (pdf->enc_objid == ~0u || !pdf->fileID)
|
|
1322
|
+ if (pdf->enc_objid == ~0u)
|
1323
|
1323
|
return;
|
1324
|
|
- obj = find_obj(pdf, pdf->objs, pdf->enc_objid);
|
1325
|
|
- if (!obj)
|
|
1324
|
+ if (!pdf->fileID) {
|
|
1325
|
+ cli_dbgmsg("cli_pdf: pdf_handle_enc no file ID\n");
|
1326
|
1326
|
return;
|
1327
|
|
- required_flags = (1 << OBJ_HASFILTERS) | (1 << OBJ_FILTER_STANDARD);
|
1328
|
|
- if (!(obj->flags & required_flags))
|
|
1327
|
+ }
|
|
1328
|
+ obj = find_obj(pdf, pdf->objs, pdf->enc_objid);
|
|
1329
|
+ if (!obj) {
|
|
1330
|
+ cli_dbgmsg("cli_pdf: can't find encrypted object %d %d\n", pdf->enc_objid>>8, pdf->enc_objid&0xff);
|
1329
|
1331
|
return;
|
|
1332
|
+ }
|
1330
|
1333
|
len = obj_size(pdf, obj, 1);
|
1331
|
1334
|
q = pdf->map + obj->start;
|
1332
|
1335
|
|
...
|
...
|
@@ -1338,21 +1353,25 @@ static void pdf_handle_enc(struct pdf_struct *pdf)
|
1338
|
1338
|
cli_dbgmsg("cli_pdf: invalid P\n");
|
1339
|
1339
|
break;
|
1340
|
1340
|
}
|
1341
|
|
- length = pdf_readint(q, len, "/Length");
|
1342
|
|
- if (length == ~0u)
|
1343
|
|
- length = 40;
|
1344
|
|
- if (length < 40) {
|
1345
|
|
- cli_dbgmsg("cli_pdf: invalid length: %d\n", length);
|
1346
|
|
- length = 40;
|
1347
|
|
- }
|
1348
|
1341
|
|
1349
|
1342
|
q2 = cli_memstr(q, len, "/Standard", 9);
|
1350
|
1343
|
if (!q2) {
|
1351
|
1344
|
cli_dbgmsg("cli_pdf: /Standard not found\n");
|
1352
|
1345
|
break;
|
1353
|
1346
|
}
|
1354
|
|
- len -= q2-q;
|
1355
|
|
- q = q2;
|
|
1347
|
+ /* we can have both of these:
|
|
1348
|
+ * /AESV2/Length /Standard/Length
|
|
1349
|
+ * /Length /Standard
|
|
1350
|
+ * make sure we don't mistake AES's length for Standard's */
|
|
1351
|
+ length = pdf_readint(q2, len - (q2 - q), "/Length");
|
|
1352
|
+ if (length == ~0u)
|
|
1353
|
+ length = pdf_readint(q, len, "/Length");
|
|
1354
|
+ if (length == ~0u)
|
|
1355
|
+ length = 40;
|
|
1356
|
+ if (length < 40) {
|
|
1357
|
+ cli_dbgmsg("cli_pdf: invalid length: %d\n", length);
|
|
1358
|
+ length = 40;
|
|
1359
|
+ }
|
1356
|
1360
|
|
1357
|
1361
|
R = pdf_readint(q, len, "/R");
|
1358
|
1362
|
if (R == ~0u) {
|