diff --git a/pdf.c b/pdf.c index e130384ca2cd590b79079e4537f3d9c72a29ad3f..43108585e86bd1da1e7475b540b0d98329130a5b 100644 --- a/pdf.c +++ b/pdf.c @@ -638,6 +638,8 @@ HParser *p_pdfdbg; HParser *p_startxref; HParser *p_xref; HParser *p_objdef; +HParser *p_a85string; +HParser *p_ahexstream; /* continuations for h_bind() */ HParser *kstream(HAllocator *, const HParsedToken *, void *); @@ -848,6 +850,36 @@ init_parser(struct Env *aux) /* debug parser to consume as much as possible */ H_RULE(pdfdbg, SEQ(header, h_many(tail), body, OPT(xr_td), OPT(startxr))); + /* Parser for Ascii85Decode */ + H_RULE(a85eod, SEQ(h_ch('~'), OPT(h_many(lwchar)), h_ch('>'))); + H_ARULE(a85zero, h_ch('z')); + H_ARULE(a85digit, h_ch_range('!', 'u')); + + /* Line whitespace can occur between any digit and has to be ignored, */ + /* Comments are not allowed inside streams, and % character should cause + * a parse error. */ + #define MANY_LWS(X) h_many(CHX(lws, X)) + + /* This encoding of zero is not allowed */ + H_RULE(a85fiveexcl, h_repeat_n(MANY_LWS(h_ch('!')), 5)); + H_VARULE(a85fivedigits, SEQ(h_and(h_not(a85fiveexcl)), h_repeat_n(MANY_LWS(a85digit), 5))); + H_ARULE(a85group, CHX(a85zero, a85fivedigits)); + + H_VARULE(a85partial2group, h_repeat_n(MANY_LWS(a85digit), 2)); + H_VARULE(a85partial3group, h_repeat_n(MANY_LWS(a85digit), 3)); + H_VARULE(a85partial4group, h_repeat_n(MANY_LWS(a85digit), 4)); + H_ARULE(a85partialgroup, CHX(a85partial4group, a85partial3group, a85partial4group)); + + H_RULE(a85string, SEQ(h_many(a85group), OPT(a85partialgroup), IGN(a85eod))); + + /* AsciiHexDecode parser */ + H_RULE(ahexeod, h_ch('>')); + H_RULE(hdigitpair, SEQ(OPT(h_many(lwchar)), hdigit, OPT(h_many(lwchar)), hdigit)); + H_ARULE(ahextruncated, SEQ(hdigit, OPT(h_many(lwchar)), ahexeod)); + + H_RULE(hs_end, CHX(hdigitpair, ahextruncated)); + H_RULE(hexstream, SEQ(h_many(hdigitpair), hs_end)); + /* global parser variables */ p_pdf = pdf; @@ -855,6 +887,8 @@ init_parser(struct Env *aux) p_startxref = startxr; p_xref = CHX(xr_td, xrstm); p_objdef = objdef; + p_a85string = a85string; + p_ahexstream = hexstream; p_fail = h_nothing_p(); p_epsilon = epsilon; @@ -1224,19 +1258,8 @@ HParseResult * ASCIIHexDecode(const Dict *parms, HBytes b, HParser *p) { HParseResult *res; - H_RULE(lwchar, IN(LWCHARS)); - H_ARULE(digit, h_ch_range('0', '9')); - H_ARULE(hlower, h_ch_range('a', 'f')); - H_ARULE(hupper, h_ch_range('A', 'F')); - H_RULE(ahexeod, h_ch('>')); - H_RULE(hdigit, CHX(digit, hlower, hupper)); - H_RULE(hdigitpair, SEQ(OPT(h_many(lwchar)), hdigit, OPT(h_many(lwchar)), hdigit)); - H_ARULE(ahextruncated, SEQ(hdigit, OPT(h_many(lwchar)), ahexeod)); - H_RULE(hs_end, CHX(hdigitpair, ahextruncated)); - H_RULE(hexstream, SEQ(h_many(hdigitpair), hs_end)); - - res = h_parse(hexstream, b.token, b.len); + res = h_parse(p_ahexstream, b.token, b.len); if(!res) { fprintf(stderr, "parse error in ASCIIHexDecode filter\n"); @@ -1254,33 +1277,8 @@ HParseResult* ASCII85Decode(const Dict *parms, HBytes b, HParser *p) { HParseResult *res; - H_RULE(lwchar, IN(LWCHARS)); - - H_RULE(a85eod, SEQ(h_ch('~'), OPT(h_many(lwchar)), h_ch('>'))); - H_ARULE(a85zero, h_ch('z')); - H_ARULE(a85digit, h_ch_range('!', 'u')); - - /* Line whitespace can occur between any digit and has to be ignored, */ - /* Comments are not allowed inside streams, and % character should cause - * a parse error. */ - H_RULE(lws, IGN(h_many(IGN(lwchar)))); - #define MANY_LWS(X) h_many(CHX(lws, X)) - - /* This encoding of zero is not allowed */ - H_RULE(a85fiveexcl, h_repeat_n(MANY_LWS(h_ch('!')), 5)); - H_VARULE(a85fivedigits, SEQ(h_and(h_not(a85fiveexcl)), h_repeat_n(MANY_LWS(a85digit), 5))); - - H_ARULE(a85group, CHX(a85zero, a85fivedigits)); - - H_VARULE(a85partial2group, h_repeat_n(MANY_LWS(a85digit), 2)); - H_VARULE(a85partial3group, h_repeat_n(MANY_LWS(a85digit), 3)); - H_VARULE(a85partial4group, h_repeat_n(MANY_LWS(a85digit), 4)); - - H_ARULE(a85partialgroup, CHX(a85partial4group, a85partial3group, a85partial4group)); - - H_RULE(a85string, SEQ(h_many(a85group), OPT(a85partialgroup), IGN(a85eod))); - res = h_parse(a85string, b.token, b.len); + res = h_parse(p_a85string, b.token, b.len); if(!res) { fprintf(stderr, "parse error in ASCII85Decode filter\n");