Browse code

Some more fixes for signed/encrypted pdfs.

Török Edvin authored on 2010/07/31 02:26:59
Showing 1 changed files
... ...
@@ -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)|