summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/luapplib/ppload.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luapplib/ppload.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/luapplib/ppload.c116
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;
}