...
|
...
|
@@ -79,7 +79,8 @@ enum pdf_flag {
|
79
|
79
|
UNKNOWN_FILTER,
|
80
|
80
|
HAS_OPENACTION,
|
81
|
81
|
BAD_STREAMLEN,
|
82
|
|
- ENCRYPTED_PDF
|
|
82
|
+ ENCRYPTED_PDF,
|
|
83
|
+ LINEARIZED_PDF /* not bad, just as flag */
|
83
|
84
|
};
|
84
|
85
|
|
85
|
86
|
static int xrefCheck(const char *xref, const char *eof)
|
...
|
...
|
@@ -117,6 +118,7 @@ enum objflags {
|
117
|
117
|
OBJ_FILTER_DCT,
|
118
|
118
|
OBJ_FILTER_JPX,
|
119
|
119
|
OBJ_FILTER_CRYPT,
|
|
120
|
+ OBJ_FILTER_UNKNOWN,
|
120
|
121
|
OBJ_JAVASCRIPT,
|
121
|
122
|
OBJ_OPENACTION,
|
122
|
123
|
OBJ_HASFILTERS,
|
...
|
...
|
@@ -659,6 +661,7 @@ enum objstate {
|
659
|
659
|
STATE_FILTER,
|
660
|
660
|
STATE_JAVASCRIPT,
|
661
|
661
|
STATE_OPENACTION,
|
|
662
|
+ STATE_LINEARIZED,
|
662
|
663
|
STATE_ANY /* for actions table below */
|
663
|
664
|
};
|
664
|
665
|
|
...
|
...
|
@@ -682,7 +685,9 @@ static struct pdfname_action pdfname_actions[] = {
|
682
|
682
|
{"JPXDecode", OBJ_FILTER_JPX, STATE_FILTER, STATE_FILTER},
|
683
|
683
|
{"Crypt", OBJ_FILTER_CRYPT, STATE_FILTER, STATE_NONE},
|
684
|
684
|
{"Standard", OBJ_FILTER_CRYPT, STATE_FILTER, STATE_FILTER},
|
685
|
|
- {"Sig", OBJ_SIGNED, STATE_NONE, STATE_NONE},
|
|
685
|
+ {"Sig", OBJ_SIGNED, STATE_ANY, STATE_NONE},
|
|
686
|
+ {"V", OBJ_SIGNED, STATE_ANY, STATE_NONE},
|
|
687
|
+ {"Linearized", OBJ_DICT, STATE_NONE, STATE_LINEARIZED},
|
686
|
688
|
{"Filter", OBJ_HASFILTERS, STATE_ANY, STATE_FILTER},
|
687
|
689
|
{"JavaScript", OBJ_JAVASCRIPT, STATE_S, STATE_JAVASCRIPT},
|
688
|
690
|
{"Length", OBJ_DICT, STATE_FILTER, STATE_NONE},
|
...
|
...
|
@@ -712,7 +717,7 @@ static void handle_pdfname(struct pdf_struct *pdf, struct pdf_obj *obj,
|
712
|
712
|
* we don't need them anyway */
|
713
|
713
|
!(obj->flags & KNOWN_FILTERS)) {
|
714
|
714
|
cli_dbgmsg("cli_pdf: unknown filter %s\n", pdfname);
|
715
|
|
- pdfobj_flag(pdf, obj, UNKNOWN_FILTER);
|
|
715
|
+ obj->flags |= 1 << OBJ_FILTER_UNKNOWN;
|
716
|
716
|
}
|
717
|
717
|
return;
|
718
|
718
|
}
|
...
|
...
|
@@ -815,6 +820,10 @@ static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
815
|
815
|
pdfname[i] = '\0';
|
816
|
816
|
|
817
|
817
|
handle_pdfname(pdf, obj, pdfname, escapes, &objstate);
|
|
818
|
+ if (objstate == STATE_LINEARIZED) {
|
|
819
|
+ pdfobj_flag(pdf, obj, LINEARIZED_PDF);
|
|
820
|
+ objstate = STATE_NONE;
|
|
821
|
+ }
|
818
|
822
|
if (objstate == STATE_JAVASCRIPT ||
|
819
|
823
|
objstate == STATE_OPENACTION) {
|
820
|
824
|
if (objstate == STATE_OPENACTION)
|
...
|
...
|
@@ -847,6 +856,10 @@ static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
847
|
847
|
objstate = STATE_NONE;
|
848
|
848
|
}
|
849
|
849
|
}
|
|
850
|
+ if (obj->flags & ((1 << OBJ_SIGNED) | KNOWN_FILTERS))
|
|
851
|
+ obj->flags &= ~(1 << OBJ_FILTER_UNKNOWN);
|
|
852
|
+ if (obj->flags & (1 << OBJ_FILTER_UNKNOWN))
|
|
853
|
+ pdfobj_flag(pdf, obj, UNKNOWN_FILTER);
|
850
|
854
|
cli_dbgmsg("cli_pdf: %u %u obj flags: %02x\n", obj->id>>8, obj->id&0xff, obj->flags);
|
851
|
855
|
}
|
852
|
856
|
|
...
|
...
|
@@ -978,7 +991,8 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
|
978
|
978
|
}
|
979
|
979
|
|
980
|
980
|
if (pdf.flags & (1 << ENCRYPTED_PDF))
|
981
|
|
- pdf.flags &= ~ (1 << BAD_FLATESTART) | (1 << BAD_STREAMSTART);
|
|
981
|
+ pdf.flags &= ~ ((1 << BAD_FLATESTART) | (1 << BAD_STREAMSTART) |
|
|
982
|
+ (1 << BAD_ASCIIDECODE));
|
982
|
983
|
|
983
|
984
|
if (pdf.flags) {
|
984
|
985
|
cli_dbgmsg("cli_pdf: flags 0x%02x\n", pdf.flags);
|
...
|
...
|
@@ -988,6 +1002,9 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
|
988
|
988
|
rc = CL_VIRUS;
|
989
|
989
|
}
|
990
|
990
|
#if 0
|
|
991
|
+ /* TODO: find both trailers, and /Encrypt settings */
|
|
992
|
+ if (pdf.flags & (1 << LINEARIZED_PDF))
|
|
993
|
+ pdf.flags &= ~ (1 << BAD_ASCIIDECODE);
|
991
|
994
|
if (pdf.flags &
|
992
|
995
|
((1 << BAD_PDF_TOOMANYOBJS) | (1 << BAD_STREAM_FILTERS) |
|
993
|
996
|
(1<<BAD_FLATE) | (1<<BAD_ASCIIDECODE)|
|