...
|
...
|
@@ -299,6 +299,7 @@ int pdf_findobj_in_objstm(struct pdf_struct *pdf, struct objstm_struct *objstm,
|
299
|
299
|
cl_error_t status = CL_EPARSE;
|
300
|
300
|
struct pdf_obj *obj = NULL;
|
301
|
301
|
unsigned long objid = 0, objsize = 0, objoff = 0;
|
|
302
|
+ long temp_long = 0;
|
302
|
303
|
const char *index = NULL;
|
303
|
304
|
size_t bytes_remaining = 0;
|
304
|
305
|
|
...
|
...
|
@@ -323,12 +324,17 @@ int pdf_findobj_in_objstm(struct pdf_struct *pdf, struct objstm_struct *objstm,
|
323
|
323
|
obj->objstm = objstm;
|
324
|
324
|
|
325
|
325
|
/* objstm->current_pair points directly to the obj id */
|
326
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(index, bytes_remaining, 0, 10, &objid)) {
|
|
326
|
+ if (CL_SUCCESS != cli_strntol_wrap(index, bytes_remaining, 0, 10, &temp_long)) {
|
327
|
327
|
/* Failed to find objid */
|
328
|
328
|
cli_dbgmsg("pdf_findobj_in_objstm: Failed to find objid for obj in object stream\n");
|
329
|
329
|
status = CL_EPARSE;
|
330
|
330
|
goto done;
|
|
331
|
+ } else if (temp_long < 0) {
|
|
332
|
+ cli_dbgmsg("pdf_findobj_in_objstm: Encountered invalid negative objid (%ld).\n", temp_long);
|
|
333
|
+ status = CL_EPARSE;
|
|
334
|
+ goto done;
|
331
|
335
|
}
|
|
336
|
+ objid = (unsigned long)temp_long;
|
332
|
337
|
|
333
|
338
|
/* Find the obj offset that appears just after the obj id*/
|
334
|
339
|
while ((index < objstm->streambuf + objstm->streambuf_len) && isdigit(*index)) {
|
...
|
...
|
@@ -338,12 +344,17 @@ int pdf_findobj_in_objstm(struct pdf_struct *pdf, struct objstm_struct *objstm,
|
338
|
338
|
index = findNextNonWS(index, objstm->streambuf + objstm->first);
|
339
|
339
|
bytes_remaining = objstm->streambuf + objstm->streambuf_len - index;
|
340
|
340
|
|
341
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(index, bytes_remaining, 0, 10, &objoff)) {
|
|
341
|
+ if (CL_SUCCESS != cli_strntol_wrap(index, bytes_remaining, 0, 10, &temp_long)) {
|
342
|
342
|
/* Failed to find obj offset */
|
343
|
343
|
cli_dbgmsg("pdf_findobj_in_objstm: Failed to find obj offset for obj in object stream\n");
|
344
|
344
|
status = CL_EPARSE;
|
345
|
345
|
goto done;
|
|
346
|
+ } else if (temp_long < 0) {
|
|
347
|
+ cli_dbgmsg("pdf_findobj_in_objstm: Encountered invalid negative obj offset (%ld).\n", temp_long);
|
|
348
|
+ status = CL_EPARSE;
|
|
349
|
+ goto done;
|
346
|
350
|
}
|
|
351
|
+ objoff = (unsigned long)temp_long;
|
347
|
352
|
|
348
|
353
|
if ((size_t)objstm->first + (size_t)objoff > objstm->streambuf_len) {
|
349
|
354
|
/* Alleged obj location is further than the length of the stream */
|
...
|
...
|
@@ -382,12 +393,17 @@ int pdf_findobj_in_objstm(struct pdf_struct *pdf, struct objstm_struct *objstm,
|
382
|
382
|
index = objstm->streambuf + objstm->current_pair;
|
383
|
383
|
bytes_remaining = objstm->streambuf + objstm->streambuf_len - index;
|
384
|
384
|
|
385
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(index, bytes_remaining, 0, 10, &next_objid)) {
|
|
385
|
+ if (CL_SUCCESS != cli_strntol_wrap(index, bytes_remaining, 0, 10, &temp_long)) {
|
386
|
386
|
/* Failed to find objid for next obj */
|
387
|
387
|
cli_dbgmsg("pdf_findobj_in_objstm: Failed to find next objid for obj in object stream though there should be {%u} more.\n", objstm->n - objstm->nobjs_found);
|
388
|
388
|
status = CL_EPARSE;
|
389
|
389
|
goto done;
|
|
390
|
+ } else if (temp_long < 0) {
|
|
391
|
+ cli_dbgmsg("pdf_findobj_in_objstm: Encountered invalid negative objid (%ld).\n", temp_long);
|
|
392
|
+ status = CL_EPARSE;
|
|
393
|
+ goto done;
|
390
|
394
|
}
|
|
395
|
+ next_objid = (unsigned long)temp_long;
|
391
|
396
|
|
392
|
397
|
/* Find the obj offset that appears just after the obj id*/
|
393
|
398
|
while ((index < objstm->streambuf + objstm->streambuf_len) && isdigit(*index)) {
|
...
|
...
|
@@ -397,13 +413,19 @@ int pdf_findobj_in_objstm(struct pdf_struct *pdf, struct objstm_struct *objstm,
|
397
|
397
|
index = findNextNonWS(index, objstm->streambuf + objstm->first);
|
398
|
398
|
bytes_remaining = objstm->streambuf + objstm->streambuf_len - index;
|
399
|
399
|
|
400
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(index, bytes_remaining, 0, 10, &next_objoff)) {
|
|
400
|
+ if (CL_SUCCESS != cli_strntol_wrap(index, bytes_remaining, 0, 10, &temp_long)) {
|
401
|
401
|
/* Failed to find obj offset for next obj */
|
402
|
402
|
cli_dbgmsg("pdf_findobj_in_objstm: Failed to find next obj offset for obj in object stream though there should be {%u} more.\n", objstm->n - objstm->nobjs_found);
|
403
|
403
|
status = CL_EPARSE;
|
404
|
404
|
goto done;
|
|
405
|
+ } else if (temp_long < 0) {
|
|
406
|
+ cli_dbgmsg("pdf_findobj_in_objstm: Encountered invalid negative obj offset (%ld).\n", temp_long);
|
|
407
|
+ status = CL_EPARSE;
|
|
408
|
+ goto done;
|
405
|
409
|
}
|
406
|
|
- else if (next_objoff <= objoff) {
|
|
410
|
+ next_objoff = (unsigned long)temp_long;
|
|
411
|
+
|
|
412
|
+ if (next_objoff <= objoff) {
|
407
|
413
|
/* Failed to find obj offset for next obj */
|
408
|
414
|
cli_dbgmsg("pdf_findobj_in_objstm: Found next obj offset for obj in object stream but it's less than or equal to the current one!\n");
|
409
|
415
|
status = CL_EPARSE;
|
...
|
...
|
@@ -481,6 +503,7 @@ cl_error_t pdf_findobj(struct pdf_struct *pdf)
|
481
|
481
|
struct pdf_obj *obj = NULL;
|
482
|
482
|
off_t bytesleft;
|
483
|
483
|
unsigned long genid, objid;
|
|
484
|
+ long temp_long;
|
484
|
485
|
|
485
|
486
|
pdf->nobjs++;
|
486
|
487
|
pdf->objs = cli_realloc2(pdf->objs, sizeof(struct pdf_obj*) * pdf->nobjs);
|
...
|
...
|
@@ -539,20 +562,26 @@ cl_error_t pdf_findobj(struct pdf_struct *pdf)
|
539
|
539
|
while (q > start && isdigit(*q))
|
540
|
540
|
q--;
|
541
|
541
|
|
542
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(q, (size_t)(bytesleft + (q2-q)), 0, 10, &genid)) {
|
|
542
|
+ if (CL_SUCCESS != cli_strntol_wrap(q, (size_t)(bytesleft + (q2 - q)), 0, 10, &temp_long)) {
|
543
|
543
|
cli_dbgmsg("pdf_findobj: Failed to parse object genid (# objects found: %u)\n", pdf->nobjs);
|
544
|
544
|
/* Failed to parse, probably not a real object. Skip past the "obj" thing, and continue. */
|
545
|
545
|
pdf->offset = q2 + 4 - pdf->map;
|
546
|
546
|
status = CL_EPARSE;
|
547
|
547
|
goto done;
|
|
548
|
+ } else if (temp_long < 0) {
|
|
549
|
+ cli_dbgmsg("pdf_findobj: Encountered invalid negative obj genid (%ld).\n", temp_long);
|
|
550
|
+ pdf->offset = q2 + 4 - pdf->map;
|
|
551
|
+ status = CL_EPARSE;
|
|
552
|
+ goto done;
|
548
|
553
|
}
|
|
554
|
+ genid = (unsigned long)temp_long;
|
549
|
555
|
|
550
|
556
|
/* Find the object id (objid) that appers before the genid */
|
551
|
557
|
q = findNextNonWSBack(q-1,start);
|
552
|
558
|
while (q > start && isdigit(*q))
|
553
|
559
|
q--;
|
554
|
560
|
|
555
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(q, (size_t)(bytesleft + (q2-q)), 0, 10, &objid)) {
|
|
561
|
+ if (CL_SUCCESS != cli_strntol_wrap(q, (size_t)(bytesleft + (q2 - q)), 0, 10, &temp_long)) {
|
556
|
562
|
/*
|
557
|
563
|
* PDFs with multiple revisions will have %%EOF before the end of the file,
|
558
|
564
|
* followed by the next revision of the PDF. If this is the case, we can
|
...
|
...
|
@@ -581,15 +610,27 @@ cl_error_t pdf_findobj(struct pdf_struct *pdf)
|
581
|
581
|
goto done;
|
582
|
582
|
}
|
583
|
583
|
/* Try again, with offset slightly adjusted */
|
584
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(q, (size_t)(bytesleft + (q2-q)), 0, 10, &objid)) {
|
|
584
|
+ if (CL_SUCCESS != cli_strntol_wrap(q, (size_t)(bytesleft + (q2 - q)), 0, 10, &temp_long)) {
|
585
|
585
|
cli_dbgmsg("pdf_findobj: Failed to parse object objid (# objects found: %u)\n", pdf->nobjs);
|
586
|
586
|
/* Still failed... Probably not a real object. Skip past the "obj" thing, and continue. */
|
587
|
587
|
pdf->offset = q2 + 4 - pdf->map;
|
588
|
588
|
status = CL_EPARSE;
|
589
|
589
|
goto done;
|
|
590
|
+ } else if (temp_long < 0) {
|
|
591
|
+ cli_dbgmsg("pdf_findobj: Encountered invalid negative objid (%ld).\n", temp_long);
|
|
592
|
+ pdf->offset = q2 + 4 - pdf->map;
|
|
593
|
+ status = CL_EPARSE;
|
|
594
|
+ goto done;
|
590
|
595
|
}
|
|
596
|
+
|
591
|
597
|
cli_dbgmsg("pdf_findobj: There appears to be an additional revision. Continuing to parse...\n");
|
|
598
|
+ } else if (temp_long < 0) {
|
|
599
|
+ cli_dbgmsg("pdf_findobj: Encountered invalid negative objid (%ld).\n", temp_long);
|
|
600
|
+ pdf->offset = q2 + 4 - pdf->map;
|
|
601
|
+ status = CL_EPARSE;
|
|
602
|
+ goto done;
|
592
|
603
|
}
|
|
604
|
+ objid = (unsigned long)temp_long;
|
593
|
605
|
|
594
|
606
|
/*
|
595
|
607
|
* Ok so we have the objid, genid, and "obj" string.
|
...
|
...
|
@@ -845,7 +886,7 @@ static size_t find_length(struct pdf_struct *pdf, struct pdf_obj *obj, const cha
|
845
|
845
|
size_t length = 0;
|
846
|
846
|
const char *obj_start = dict_start;
|
847
|
847
|
size_t bytes_remaining = dict_len;
|
848
|
|
- unsigned long length_ul = 0;
|
|
848
|
+ long temp_long = 0;
|
849
|
849
|
const char *index;
|
850
|
850
|
|
851
|
851
|
if (bytes_remaining < 8) {
|
...
|
...
|
@@ -881,11 +922,14 @@ static size_t find_length(struct pdf_struct *pdf, struct pdf_obj *obj, const cha
|
881
|
881
|
|
882
|
882
|
/* Read the value. This could either be the direct length value,
|
883
|
883
|
or the object id of the indirect object that has the length */
|
884
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(index, bytes_remaining, 0, 10, &length_ul)) {
|
885
|
|
- cli_dbgmsg("find_length: failed to parse object length\n");
|
|
884
|
+ if (CL_SUCCESS != cli_strntol_wrap(index, bytes_remaining, 0, 10, &temp_long)) {
|
|
885
|
+ cli_dbgmsg("find_length: failed to parse object length or objid\n");
|
|
886
|
+ return 0;
|
|
887
|
+ } else if (temp_long < 0) {
|
|
888
|
+ cli_dbgmsg("find_length: Encountered invalid negative object length or objid (%ld).\n", temp_long);
|
886
|
889
|
return 0;
|
887
|
890
|
}
|
888
|
|
- length = length_ul; /* length or maybe object id */
|
|
891
|
+ length = (size_t)temp_long; /* length or maybe object id */
|
889
|
892
|
|
890
|
893
|
/*
|
891
|
894
|
* Keep parsing, skipping past the first integer that might have been what we wanted.
|
...
|
...
|
@@ -903,10 +947,14 @@ static size_t find_length(struct pdf_struct *pdf, struct pdf_obj *obj, const cha
|
903
|
903
|
index++;
|
904
|
904
|
bytes_remaining--;
|
905
|
905
|
|
906
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(index, bytes_remaining, 0, 10, &genid)) {
|
|
906
|
+ if (CL_SUCCESS != cli_strntol_wrap(index, bytes_remaining, 0, 10, &temp_long)) {
|
907
|
907
|
cli_dbgmsg("find_length: failed to parse object genid\n");
|
908
|
908
|
return 0;
|
|
909
|
+ } else if (temp_long < 0) {
|
|
910
|
+ cli_dbgmsg("find_length: Encountered invalid negative object genid (%ld).\n", temp_long);
|
|
911
|
+ return 0;
|
909
|
912
|
}
|
|
913
|
+ genid = (unsigned long)temp_long;
|
910
|
914
|
|
911
|
915
|
while((bytes_remaining > 0) && isdigit(*index)) {
|
912
|
916
|
index++;
|
...
|
...
|
@@ -949,11 +997,15 @@ static size_t find_length(struct pdf_struct *pdf, struct pdf_obj *obj, const cha
|
949
|
949
|
}
|
950
|
950
|
bytes_remaining -= index - indirect_obj_start;
|
951
|
951
|
|
952
|
|
- /* Found the value, so lets parse it as an unsigned long */
|
953
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(index, bytes_remaining, 0, 10, &length)) {
|
|
952
|
+ /* Found the value, so lets parse it as a long, but prohibit negative lengths. */
|
|
953
|
+ if (CL_SUCCESS != cli_strntol_wrap(index, bytes_remaining, 0, 10, &temp_long)) {
|
954
|
954
|
cli_dbgmsg("find_length: failed to parse object length from indirect object\n");
|
955
|
955
|
return 0;
|
|
956
|
+ } else if (temp_long < 0) {
|
|
957
|
+ cli_dbgmsg("find_length: Encountered invalid negative obj length (%ld).\n", temp_long);
|
|
958
|
+ return 0;
|
956
|
959
|
}
|
|
960
|
+ length = (size_t)temp_long;
|
957
|
961
|
}
|
958
|
962
|
}
|
959
|
963
|
|
...
|
...
|
@@ -1983,6 +2035,7 @@ static void pdf_parse_encrypt(struct pdf_struct *pdf, const char *enc, int len)
|
1983
|
1983
|
const char *q, *q2;
|
1984
|
1984
|
unsigned long objid;
|
1985
|
1985
|
unsigned long genid;
|
|
1986
|
+ long temp_long;
|
1986
|
1987
|
|
1987
|
1988
|
if (len >= 16 && !strncmp(enc, "/EncryptMetadata", 16)) {
|
1988
|
1989
|
q = cli_memstr(enc+16, len-16, "/Encrypt", 8);
|
...
|
...
|
@@ -2001,10 +2054,15 @@ static void pdf_parse_encrypt(struct pdf_struct *pdf, const char *enc, int len)
|
2001
|
2001
|
len -= q2 - q;
|
2002
|
2002
|
q = q2;
|
2003
|
2003
|
|
2004
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(q2, (size_t)len, 0, 10, &objid)) {
|
|
2004
|
+ if (CL_SUCCESS != cli_strntol_wrap(q2, (size_t)len, 0, 10, &temp_long)) {
|
2005
|
2005
|
cli_dbgmsg("pdf_parse_encrypt: Found Encrypt dictionary but failed to parse objid\n");
|
2006
|
2006
|
return;
|
|
2007
|
+ } else if (temp_long < 0) {
|
|
2008
|
+ cli_dbgmsg("pdf_parse_encrypt: Encountered invalid negative objid (%ld).\n", temp_long);
|
|
2009
|
+ return;
|
2007
|
2010
|
}
|
|
2011
|
+ objid = (unsigned long)temp_long;
|
|
2012
|
+
|
2008
|
2013
|
objid = objid << 8;
|
2009
|
2014
|
q2 = pdf_nextobject(q, len);
|
2010
|
2015
|
if (!q2 || !isdigit(*q2))
|
...
|
...
|
@@ -2012,10 +2070,15 @@ static void pdf_parse_encrypt(struct pdf_struct *pdf, const char *enc, int len)
|
2012
|
2012
|
len -= q2 - q;
|
2013
|
2013
|
q = q2;
|
2014
|
2014
|
|
2015
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(q2, (size_t)len, 0, 10, &genid)) {
|
|
2015
|
+ if (CL_SUCCESS != cli_strntol_wrap(q2, (size_t)len, 0, 10, &temp_long)) {
|
2016
|
2016
|
cli_dbgmsg("pdf_parse_encrypt: Found Encrypt dictionary but failed to parse genid\n");
|
2017
|
2017
|
return;
|
|
2018
|
+ } else if (temp_long < 0) {
|
|
2019
|
+ cli_dbgmsg("pdf_parse_encrypt: Encountered invalid negative genid (%ld).\n", temp_long);
|
|
2020
|
+ return;
|
2018
|
2021
|
}
|
|
2022
|
+ genid = (unsigned long)temp_long;
|
|
2023
|
+
|
2019
|
2024
|
objid |= genid & 0xff;
|
2020
|
2025
|
q2 = pdf_nextobject(q, len);
|
2021
|
2026
|
if (!q2 || *q2 != 'R')
|
...
|
...
|
@@ -2061,6 +2124,11 @@ void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
2061
|
2061
|
json_object *pdfobj=NULL, *jsonobj=NULL;
|
2062
|
2062
|
#endif
|
2063
|
2063
|
|
|
2064
|
+ if (NULL == pdf || NULL == obj) {
|
|
2065
|
+ cli_warnmsg("pdf_parseobj: invalid arguments\n");
|
|
2066
|
+ return;
|
|
2067
|
+ }
|
|
2068
|
+
|
2064
|
2069
|
if (obj->objstm) {
|
2065
|
2070
|
if ((size_t)obj->start > obj->objstm->streambuf_len) {
|
2066
|
2071
|
cli_dbgmsg("pdf_parseobj: %u %u obj: obj start (%u) is greater than size of object stream (%zu).\n",
|
...
|
...
|
@@ -2112,7 +2180,23 @@ void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
2112
|
2112
|
return;
|
2113
|
2113
|
}
|
2114
|
2114
|
|
|
2115
|
+ /*
|
|
2116
|
+ * Opening `<` for object's dictionary may be back 1 character,
|
|
2117
|
+ * provided q is not at the start of the buffer (it shouldn't be).
|
|
2118
|
+ */
|
|
2119
|
+ if (obj->objstm) {
|
|
2120
|
+ if (obj->objstm->streambuf == q) {
|
|
2121
|
+ q3 = memchr(q, '<', nextobj - q);
|
|
2122
|
+ } else {
|
2115
|
2123
|
q3 = memchr(q-1, '<', nextobj-q+1);
|
|
2124
|
+ }
|
|
2125
|
+ } else {
|
|
2126
|
+ if (pdf->map == q) {
|
|
2127
|
+ q3 = memchr(q, '<', nextobj - q);
|
|
2128
|
+ } else {
|
|
2129
|
+ q3 = memchr(q - 1, '<', nextobj - q + 1);
|
|
2130
|
+ }
|
|
2131
|
+ }
|
2116
|
2132
|
nextobj++;
|
2117
|
2133
|
bytesleft--;
|
2118
|
2134
|
q = nextobj;
|
...
|
...
|
@@ -2297,13 +2381,19 @@ void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
2297
|
2297
|
const char * q2_old = NULL;
|
2298
|
2298
|
unsigned long objid;
|
2299
|
2299
|
unsigned long genid;
|
|
2300
|
+ long temp_long;
|
2300
|
2301
|
|
2301
|
2302
|
dict_remaining -= (off_t)(q2 - q);
|
2302
|
2303
|
|
2303
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(q2, (size_t)dict_remaining, 0, 10, &objid)) {
|
|
2304
|
+ if (CL_SUCCESS != cli_strntol_wrap(q2, (size_t)dict_remaining, 0, 10, &temp_long)) {
|
2304
|
2305
|
cli_dbgmsg("pdf_parseobj: failed to parse object objid\n");
|
2305
|
2306
|
return;
|
|
2307
|
+ } else if (temp_long < 0) {
|
|
2308
|
+ cli_dbgmsg("pdf_parseobj: Encountered invalid negative genid (%ld).\n", temp_long);
|
|
2309
|
+ return;
|
2306
|
2310
|
}
|
|
2311
|
+ objid = (unsigned long)temp_long;
|
|
2312
|
+
|
2307
|
2313
|
objid = objid << 8;
|
2308
|
2314
|
|
2309
|
2315
|
while (isdigit(*q2))
|
...
|
...
|
@@ -2313,10 +2403,15 @@ void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
2313
|
2313
|
q2 = pdf_nextobject(q2, dict_remaining);
|
2314
|
2314
|
if (q2 && isdigit(*q2)) {
|
2315
|
2315
|
dict_remaining -= (off_t)(q2 - q2_old);
|
2316
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(q2, (size_t)dict_remaining, 0, 10, &genid)) {
|
|
2316
|
+ if (CL_SUCCESS != cli_strntol_wrap(q2, (size_t)dict_remaining, 0, 10, &temp_long)) {
|
2317
|
2317
|
cli_dbgmsg("pdf_parseobj: failed to parse object genid\n");
|
2318
|
2318
|
return;
|
|
2319
|
+ } else if (temp_long < 0) {
|
|
2320
|
+ cli_dbgmsg("pdf_parseobj: Encountered invalid negative genid (%ld).\n", temp_long);
|
|
2321
|
+ return;
|
2319
|
2322
|
}
|
|
2323
|
+ genid = (unsigned long)temp_long;
|
|
2324
|
+
|
2320
|
2325
|
objid |= genid & 0xff;
|
2321
|
2326
|
|
2322
|
2327
|
q2 = pdf_nextobject(q2, dict_remaining);
|
...
|
...
|
@@ -3045,6 +3140,11 @@ cl_error_t pdf_find_and_parse_objs_in_objstm(struct pdf_struct *pdf, struct objs
|
3045
|
3045
|
|
3046
|
3046
|
struct pdf_obj* obj = NULL;
|
3047
|
3047
|
|
|
3048
|
+ if ((NULL == objstm) || (NULL == objstm->streambuf)) {
|
|
3049
|
+ status = CL_EARG;
|
|
3050
|
+ goto done;
|
|
3051
|
+ }
|
|
3052
|
+
|
3048
|
3053
|
char* current_pair = objstm->streambuf;
|
3049
|
3054
|
char* current_obj = objstm->streambuf + objstm->first;
|
3050
|
3055
|
|
...
|
...
|
@@ -3242,6 +3342,7 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
|
3242
|
3242
|
off_t versize = size > 1032 ? 1032 : size;
|
3243
|
3243
|
off_t map_off, bytesleft;
|
3244
|
3244
|
unsigned long xref;
|
|
3245
|
+ long temp_long;
|
3245
|
3246
|
const char *pdfver, *tmp, *start, *eofmap, *q, *eof;
|
3246
|
3247
|
unsigned i, alerts = 0;
|
3247
|
3248
|
unsigned int objs_found = 0;
|
...
|
...
|
@@ -3383,11 +3484,14 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
|
3383
|
3383
|
|
3384
|
3384
|
while (q < eof && (*q == ' ' || *q == '\n' || *q == '\r')) { q++; }
|
3385
|
3385
|
|
3386
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(q, q - eofmap + map_off, 0, 10, &xref)) {
|
|
3386
|
+ if (CL_SUCCESS != cli_strntol_wrap(q, q - eofmap + map_off, 0, 10, &temp_long)) {
|
3387
|
3387
|
cli_dbgmsg("cli_pdf: failed to parse PDF trailer xref\n");
|
3388
|
3388
|
pdf.flags |= 1 << BAD_PDF_TRAILER;
|
3389
|
|
- }
|
3390
|
|
- else {
|
|
3389
|
+ } else if (temp_long < 0) {
|
|
3390
|
+ cli_dbgmsg("cli_pdf: Encountered invalid negative PDF trailer xref (%ld).\n", temp_long);
|
|
3391
|
+ pdf.flags |= 1 << BAD_PDF_TRAILER;
|
|
3392
|
+ } else {
|
|
3393
|
+ xref = (unsigned long)temp_long;
|
3391
|
3394
|
bytesleft = map->len - offset - xref;
|
3392
|
3395
|
if (bytesleft > 4096)
|
3393
|
3396
|
bytesleft = 4096;
|
...
|
...
|
@@ -4133,6 +4237,7 @@ static void Pages_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname
|
4133
|
4133
|
const char *begin;
|
4134
|
4134
|
unsigned int objsize;
|
4135
|
4135
|
unsigned long npages=0, count;
|
|
4136
|
+ long temp_long;
|
4136
|
4137
|
struct pdf_array_node *node;
|
4137
|
4138
|
json_object *pdfobj;
|
4138
|
4139
|
size_t countsize = 0;
|
...
|
...
|
@@ -4185,10 +4290,16 @@ static void Pages_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfname
|
4185
|
4185
|
countsize = (obj->objstm) ? (size_t)(obj->start + obj->objstm->streambuf + objsize - begin)
|
4186
|
4186
|
: (size_t)(obj->start + pdf->map + objsize - begin);
|
4187
|
4187
|
|
4188
|
|
- if ((CL_SUCCESS != cli_strntoul_wrap(begin, countsize, 0, 10, &count)) ||
|
4189
|
|
- (count != npages)) {
|
|
4188
|
+ if (CL_SUCCESS != cli_strntol_wrap(begin, countsize, 0, 10, &temp_long)) {
|
|
4189
|
+ cli_jsonbool(pdfobj, "IncorrectPagesCount", 1);
|
|
4190
|
+ } else if (temp_long < 0) {
|
|
4191
|
+ cli_jsonbool(pdfobj, "IncorrectPagesCount", 1);
|
|
4192
|
+ } else {
|
|
4193
|
+ count = (unsigned long)temp_long;
|
|
4194
|
+ if (count != npages) {
|
4190
|
4195
|
cli_jsonbool(pdfobj, "IncorrectPagesCount", 1);
|
4191
|
4196
|
}
|
|
4197
|
+ }
|
4192
|
4198
|
|
4193
|
4199
|
cleanup:
|
4194
|
4200
|
pdf_free_array(array);
|
...
|
...
|
@@ -4201,6 +4312,7 @@ static void Colors_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfnam
|
4201
|
4201
|
cli_ctx *ctx = pdf->ctx;
|
4202
|
4202
|
json_object *colorsobj, *pdfobj;
|
4203
|
4203
|
unsigned long ncolors;
|
|
4204
|
+ long temp_long;
|
4204
|
4205
|
char *p1;
|
4205
|
4206
|
const char *objstart = (obj->objstm) ? (const char *)(obj->start + obj->objstm->streambuf)
|
4206
|
4207
|
: (const char *)(obj->start + pdf->map);
|
...
|
...
|
@@ -4232,8 +4344,12 @@ static void Colors_cb(struct pdf_struct *pdf, struct pdf_obj *obj, struct pdfnam
|
4232
|
4232
|
if ((size_t)(p1 - objstart) == objsize)
|
4233
|
4233
|
return;
|
4234
|
4234
|
|
4235
|
|
- if (CL_SUCCESS != cli_strntoul_wrap(p1, (size_t)((p1 - objstart) - objsize), 0, 10, &ncolors))
|
|
4235
|
+ if (CL_SUCCESS != cli_strntol_wrap(p1, (size_t)((p1 - objstart) - objsize), 0, 10, &temp_long)) {
|
|
4236
|
+ return;
|
|
4237
|
+ } else if (temp_long < 0) {
|
4236
|
4238
|
return;
|
|
4239
|
+ }
|
|
4240
|
+ ncolors = (unsigned long)temp_long;
|
4237
|
4241
|
|
4238
|
4242
|
/* We only care if the number of colors > 2**24 */
|
4239
|
4243
|
if (ncolors < 1<<24)
|