From 9e2f3aba10d95d2d31dcc042fb2fed47ac73d97f Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Thu, 23 Jan 2025 15:27:22 -0500 Subject: [PATCH] Fix reading of compressed object streams (Issue #92) --- CHANGES.md | 1 + pdfio-file.c | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 493dde3..bf57e42 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ v1.4.1 - YYYY-MM-DD - Fixed handling of the Info object (Issue #87) - Fixed opening of PDF files less than 1024 bytes in length (Issue #87) - Fixed potential `NULL` dereference when reading (Issue #89) +- Fixed reading of compressed object streams (Issue #92) v1.4.0 - 2024-12-26 diff --git a/pdfio-file.c b/pdfio-file.c index efd9c7d..8625c8e 100644 --- a/pdfio-file.c +++ b/pdfio-file.c @@ -1517,6 +1517,7 @@ load_obj_stream(pdfio_obj_t *obj) // I - Object to load cur_obj, // Current object num_objs = 0; // Number of objects pdfio_obj_t *objs[16384]; // Objects + int count; // Count of objects PDFIO_DEBUG("load_obj_stream(obj=%p(%d))\n", obj, (int)obj->number); @@ -1528,12 +1529,17 @@ load_obj_stream(pdfio_obj_t *obj) // I - Object to load return (false); } + count = (int)pdfioDictGetNumber(pdfioObjGetDict(obj), "N"); + + PDFIO_DEBUG("load_obj_stream: N=%d\n", count); + _pdfioTokenInit(&tb, obj->pdf, (_pdfio_tconsume_cb_t)pdfioStreamConsume, (_pdfio_tpeek_cb_t)pdfioStreamPeek, st); // Read the object numbers from the beginning of the stream... - while (_pdfioTokenGet(&tb, buffer, sizeof(buffer))) + while (count > 0 && _pdfioTokenGet(&tb, buffer, sizeof(buffer))) { // Stop if this isn't an object number... + PDFIO_DEBUG("load_obj_stream: %s\n", buffer); if (!isdigit(buffer[0] & 255)) break; @@ -1556,21 +1562,19 @@ load_obj_stream(pdfio_obj_t *obj) // I - Object to load // Skip offset _pdfioTokenGet(&tb, buffer, sizeof(buffer)); PDFIO_DEBUG("load_obj_stream: %ld at offset %s\n", (long)number, buffer); + + // One less compressed object... + count --; } - if (!buffer[0]) - { - pdfioStreamClose(st); - return (false); - } - - _pdfioTokenPush(&tb, buffer); + PDFIO_DEBUG("load_obj_stream: num_objs=%lu\n", (unsigned long)num_objs); // Read the objects themselves... for (cur_obj = 0; cur_obj < num_objs; cur_obj ++) { if (!_pdfioValueRead(obj->pdf, obj, &tb, &(objs[cur_obj]->value), 0)) { + _pdfioFileError(obj->pdf, "Unable to read compressed object."); pdfioStreamClose(st); return (false); } @@ -1720,7 +1724,7 @@ load_xref( pdfio_stream_t *st; // Stream unsigned char buffer[32]; // Read buffer size_t num_sobjs = 0, // Number of object streams - sobjs[8192]; // Object streams to load + sobjs[16384]; // Object streams to load pdfio_obj_t *current; // Current object if ((number = strtoimax(line, &ptr, 10)) < 1)