diff --git a/pdf.c b/pdf.c index 6a74caf4c91c7989ed17f411da9840cd9435e1ca..dd6855686b3efc46c94b7d1113c6962714182231 100644 --- a/pdf.c +++ b/pdf.c @@ -97,8 +97,14 @@ validate_eq_uint(HParseResult *p, void *u) * auxiliary global data structure needed by the parser */ struct Env { + const char *infile; const char *input; size_t sz; + + const HParsedToken **xrefs; + size_t nxrefs; + const HParsedToken **objs; + size_t nobjs; }; @@ -459,6 +465,13 @@ act_ks_bytes(const HParseResult *p, void *env) return H_MAKE_BYTES(bs->token + offset, bs->len); } +const HParsedToken * +resolve(struct Env *aux, const HParsedToken *v) +{ + // XXX look up in cross-reference table + return v; +} + /* * This continuation takes the stream dictionary (as first element of x) and * should return a parser that consumes exactly the bytes that make up the @@ -475,10 +488,10 @@ kstream(HAllocator *mm__, const HParsedToken *x, void *env) /* look for the Length entry */ v = dictentry(dict, "Length"); + v = resolve(aux, v); /* resolve indirect references */ if (v == NULL || v->token_type != TT_SINT || v->sint < 0) goto fail; sz = (size_t)v->sint; - // XXX support indirect objects for the Length value! //fprintf(stderr, "parsing stream object, length %zu.\n", sz); // XXX debug @@ -1061,14 +1074,38 @@ end: return xrefs; } +/* allocate space for the cross-reference table */ +void alloc_xreftable(struct Env *aux) +{ + const HParsedToken *v; + size_t n; + + if (aux->nxrefs == 0) + return; + + v = dictentry(H_INDEX_SEQ(aux->xrefs[0], 1), "Size"); + if (v == NULL || v->token_type != TT_SINT || v->sint < 0) { + fprintf(stderr, "%s: invalid /Size in xref section\n", + aux->infile); + return; + } + n = v->sint; + + if (n > SIZE_MAX / sizeof(HParsedToken *)) + errx(1, "malloc: size would overflow"); + aux->objs = malloc(n * sizeof(HParsedToken *)); + if (aux->objs == NULL) + err(1, "malloc"); + aux->nobjs = n; +} + int main(int argc, char *argv[]) { struct Env aux; HParseResult *res = NULL; - const HParsedToken **xrefs; const uint8_t *input; - size_t sz, nxrefs; + size_t sz; int fd; /* command line handling */ @@ -1090,16 +1127,17 @@ main(int argc, char *argv[]) err(1, "mmap"); /* build parsers */ - aux = (struct Env){input, sz}; + aux = (struct Env){infile, input, sz}; init_parser(&aux); /* parse all cross-reference sections and trailer dictionaries */ - xrefs = parse_xrefs(input, sz, &nxrefs); + aux.xrefs = parse_xrefs(input, sz, &aux.nxrefs); // XXX debug - //fprintf(stderr, "%s: %zu xref sections parsed\n", infile, nxrefs); - //for (size_t i = 0; i < nxrefs; i++) - // h_pprintln(stderr, xrefs[i]); - (void)xrefs; // shut up, gcc + //fprintf(stderr, "%s: %zu xref sections parsed\n", infile, aux.nxrefs); + //for (size_t i = 0; i < aux.nxrefs; i++) + // h_pprintln(stderr, aux.xrefs[i]); + + alloc_xreftable(&aux); /* run the main parser */ res = h_parse(p_pdf, input, sz);