diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luapplib/ppload.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/luapplib/ppload.c | 116 |
1 files changed, 80 insertions, 36 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luapplib/ppload.c b/Build/source/texk/web2c/luatexdir/luapplib/ppload.c index 0ad286e5769..14b8bca1992 100644 --- a/Build/source/texk/web2c/luatexdir/luapplib/ppload.c +++ b/Build/source/texk/web2c/luatexdir/luapplib/ppload.c @@ -70,7 +70,7 @@ const char ppname_byte_lookup[] = { (ppname)(ghost + 1)) -#if defined __arm__ || defined __ARM__ || defined ARM || defined __ARM || defined __arm || defined __ARM_ARCH ||defined __aarch64__ +#if ARM_COMPLIANT #define ppname_set_alter_ego(name, ghost, ego) do {\ ppname temp;\ ppname *temp1;\ @@ -82,7 +82,7 @@ const char ppname_byte_lookup[] = { #define ppname_set_alter_ego(name, ghost, ego) (*((ppname *)(name + (ghost)->size + 1)) = ego) #endif -#if defined __arm__ || defined __ARM__ || defined ARM || defined __ARM || defined __arm || defined __ARM_ARCH ||defined __aarch64__ +#if ARM_COMPLIANT #define ppname_get_alter_ego(name) (*((ppname *)( (void*)(name + ppname_size(name) + 1)))) #else #define ppname_get_alter_ego(name) (*((ppname *)(name + ppname_size(name) + 1))) @@ -114,11 +114,13 @@ static ppname ppscan_name (iof *I, ppheap **pheap) O = ppheap_buffer(pheap, sizeof(_ppname), PPNAME_INIT); for (p = encoded, e = encoded + ghost1->size; p < e; ++p) { - if (*p == '#' && p + 2 < e ){ + if (*p == '#' && p + 2 < e) { v1 = base16_value(p[1]); v2 = base16_value(p[2]); iof_put(O, ((v1<<4)+v2)); - }else + p += 2; + } + else iof_put(O, *p); } decoded = ppname_flush_with_ego(O, ghost2, size, 0|PPNAME_DECODED); @@ -151,11 +153,13 @@ static ppname ppscan_exec (iof *I, ppheap **pheap, int first) O = ppheap_buffer(pheap, sizeof(_ppname), PPNAME_INIT); for (p = encoded, e = encoded + ghost1->size; p < e; ++p) { - if (*p == '#' && p + 2 < e ){ + if (*p == '#' && p + 2 < e) { v1 = base16_value(p[1]); v2 = base16_value(p[2]); iof_put(O, ((v1<<4)+v2)); - }else + p += 2; + } + else iof_put(O, *p); } decoded = ppname_flush_with_ego(O, ghost2, size, PPNAME_EXEC|PPNAME_DECODED); @@ -221,14 +225,14 @@ ppname ppname_encoded (ppname name) -#if defined __arm__ || defined __ARM__ || defined ARM || defined __ARM || defined __arm || defined __ARM_ARCH ||defined __aarch64__ +#if ARM_COMPLIANT #define ppstring_set_alter_ego(string, ghost, ego) (*((ppstring *)((void *)(string + (ghost)->size + 1))) = ego) #else #define ppstring_set_alter_ego(string, ghost, ego) (*((ppstring *)(string + (ghost)->size + 1)) = ego) #endif -#if defined __arm__ || defined __ARM__ || defined ARM || defined __ARM || defined __arm || defined __ARM_ARCH ||defined __aarch64__ +#if ARM_COMPLIANT #define ppstring_get_alter_ego(string) (*((ppstring *)((void *)(string + ppstring_size(string) + 1)))) #else #define ppstring_get_alter_ego(string) (*((ppstring *)(string + ppstring_size(string) + 1))) @@ -1391,14 +1395,18 @@ static int ppscan_start_stream (iof *I, ppdoc *pdf, size_t *streamoffset) int c; ppscan_find(I); if (ppscan_key(I, "stream")) - { // skip 1 or 2 whites (here we shouldn't just gobble all blanks) + { // PJ20180912 bugfix: we were gobbling white characters (also null byte), while "stream" may be followed by EOL + // pdf spec page 60: "CARRIAGE RETURN and a LINE FEED or just a LINE FEED, and not by a CARRIAGE RETURN alone" c = iof_char(I); - if (ignored_char(c)) + if (c == 0x0D) { - c = iof_next(I); - if (ignored_char(c)) + if (iof_next(I) == 0x0A) // should be ++I->pos; } + else if (c == 0x0A) + { + ++I->pos; + } *streamoffset = ppdoc_reader_tell(pdf, I); return 1; } @@ -1557,12 +1565,7 @@ static ppxref * ppxref_load_stream (iof *I, ppdoc *pdf, size_t xrefoffset) if (obj->type != PPDICT || !ppscan_start_stream(I, pdf, &streamoffset)) return NULL; xrefstream = ppstream_create(pdf, obj->dict, streamoffset); - /* All normal streams go through ppstream_info(), but it makes no sense for trailer stream (no crypt allowed, no refs yet). - So we just record the length and informative flag. Here we have to expect that /Length and /Filter are not indirects. */ - if (!ppdict_get_uint(obj->dict, "Length", &xrefstream->length)) - return NULL; - if (ppdict_get_obj(obj->dict, "Filter") != NULL) - xrefstream->flags |= PPSTREAM_COMPRESSED; + ppstream_info(xrefstream, pdf); if ((fieldwidths = ppdict_get_array(xrefstream->dict, "W")) != NULL) { if (!pparray_get_uint(fieldwidths, 0, &w1)) w1 = 0; @@ -1776,23 +1779,34 @@ Here is the proc: - estimate object length to avoid fread-ing more than necessary (not perfect but enough) - fseek() to the proper offset, fread() entry data or its part - parse the object with ppscan_obj(I, pdf, xref), where xref is not necessarily top pdf->xref - - save the actual ref->length (not sure if we need that?) + (since v0.98 xref actually no longer matters, see xref_find() notes) + - save the actual ref->length (not used so far, but we keep that so..) - make a stream if a dict is followed by "stream" keyword, also save the stream offset - free the list + +PJ2080916: Luigi and Hans fixeed a bug (rev 6491); a document having a stream with /Length being +a reference, that was stored in /ObjStm, and therefore not yet resolved when caching /Length key +value as stream->offset (ppstream_info()). At the end, references were resolved propertly, but +the stream was no readable; stream->offset == 0. In rev6491 ObjStm streams are loaded before +others streams. */ static int ppdoc_load_objstm (ppstream *stream, ppdoc *pdf, ppxref *xref); +#define ppref_is_objstm(ref, stream, type) \ + ((ref)->xref->trailer.type == PPSTREAM && (type = ppdict_get_name((stream)->dict, "Type")) != NULL && ppname_is(type, "ObjStm")) + + static void ppdoc_load_entries (ppdoc *pdf) { size_t objects, sectionindex, refnumber, offindex; + size_t streams = 0, object_streams = 0, redundant_indirections = 0; ppnum linearized; ppref **offmap, **pref, *ref; ppxref *xref; ppxsec *xsec; ppobj *obj; ppname type; - int redundant_indirection = 0; ppcrypt *crypt; ppstream *stream; @@ -1835,34 +1849,65 @@ static void ppdoc_load_entries (ppdoc *pdf) if (offindex == 1 && ppdict_get_num(obj->dict, "Linearized", &linearized)) // /Linearized value is a version number, default 1.0 pdf->flags |= PPDOC_LINEARIZED; break; + case PPSTREAM: + ++streams; + if (ppref_is_objstm(ref, obj->stream, type)) + ++object_streams; + break; case PPREF: - redundant_indirection = 1; + ++redundant_indirections; break; default: break; } - // if pdf->crypt crypt->ref = NULL } - /* refs pointngs refs? cut. */ - if (redundant_indirection) + /* cut references pointing to references (rare). doing for all effectively cuts all insane chains */ + for (pref = offmap; redundant_indirections > 0; ) + { + ref = *pref++; + if (ref->object.type == PPREF) + { + --redundant_indirections; + ref->object = ref->object.ref->object; + } + } + + /* load pdf 1.5 object streams _before_ other streams */ + for (pref = offmap; object_streams > 0; ) { - for (offindex = 0, pref = offmap; offindex < objects; ++offindex) + ref = *pref++; + obj = &ref->object; + if (obj->type != PPSTREAM) + continue; + stream = obj->stream; + if (ppref_is_objstm(ref, stream, type)) { - ref = *pref++; - if (ref->object.type == PPREF) - ref->object = ref->object.ref->object; // doing for all effectively cuts all insane chains + --object_streams; + if (crypt != NULL) + { + ppcrypt_start_ref(crypt, ref); + ppstream_info(stream, pdf); + ppcrypt_end_ref(crypt); + } + else + { + ppstream_info(stream, pdf); + } + if (!ppdoc_load_objstm(stream, pdf, ref->xref)) + loggerf("invalid objects stream %s at offset " PPSIZEF, ppref_str(ref->number, ref->version), ref->offset); + } } - /* now handle streams; update stream info (eg. /Length), load pdf 1.5 object streams - we could do earlier but then we would need to struggle with indirects */ - for (offindex = 0, pref = offmap; offindex < objects; ++offindex) + /* now handle other streams */ + for (pref = offmap; streams > 0; ) { ref = *pref++; obj = &ref->object; if (obj->type != PPSTREAM) continue; + --streams; stream = obj->stream; if (crypt != NULL) { @@ -1874,9 +1919,6 @@ static void ppdoc_load_entries (ppdoc *pdf) { ppstream_info(stream, pdf); } - if (ref->xref->trailer.type == PPSTREAM && (type = ppdict_get_name(stream->dict, "Type")) != NULL && ppname_is(type, "ObjStm")) // somewhat dummy.. - if (!ppdoc_load_objstm(stream, pdf, ref->xref)) - loggerf("invalid objects stream %s at offset " PPSIZEF, ppref_str(ref->number, ref->version), ref->offset); } pp_free(offmap); } @@ -1899,7 +1941,7 @@ ppobj * ppdoc_load_entry (ppdoc *pdf, ppref *ref) return &ref->object; // PPNONE } stack = &pdf->stack; - xref = ref->xref; // to resolve indirects properly + xref = ref->xref; if ((obj = ppscan_obj(I, pdf, xref)) == NULL) { loggerf("invalid %s object at offset " PPSIZEF, ppref_str(ref->number, ref->version), ref->offset); @@ -2232,8 +2274,10 @@ scan_array: dict = o->dict; if ((kids = pppage_node(dict, &count, &type)) != NULL) { - if (index <= count) + if (index <= count) { + index = count - index + 1; goto scan_array; + } index -= count; continue; } |