mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2026-04-09 13:32:31 +02:00
Fix repaired xref stream offsets and support indirect Contents arrays for pages.
This commit is contained in:
@@ -9,6 +9,8 @@ v1.6.2 - YYYY-MM-DD
|
||||
- Added missing range checks to `pdfioArrayCopy` and `pdfioDictCopy`.
|
||||
- Refactored PDF encryption code to fix unlocking with certain files.
|
||||
- Improved xref table loop detection (Issue #148)
|
||||
- Fixed xref reconstruction for objects lacking a `Type` value.
|
||||
- Fixed `pdfioPageOpenStream` for indirect `Contents` arrays.
|
||||
- Fixed an error propagation bug when reading too-long values (Issue #146)
|
||||
- Fixed a Clang warning.
|
||||
|
||||
|
||||
@@ -2621,19 +2621,19 @@ repair_xref(
|
||||
|
||||
_pdfioTokenFlush(&tb);
|
||||
|
||||
if (type && !strcmp(line, "stream"))
|
||||
if (!strcmp(line, "stream"))
|
||||
{
|
||||
// Possible object or XRef stream...
|
||||
obj->stream_offset = _pdfioFileTell(pdf);
|
||||
|
||||
if (!strcmp(type, "ObjStm") && num_sobjs < (sizeof(sobjs) / sizeof(sobjs[0])))
|
||||
if (type && !strcmp(type, "ObjStm") && num_sobjs < (sizeof(sobjs) / sizeof(sobjs[0])))
|
||||
{
|
||||
PDFIO_DEBUG("repair_xref: Object stream...\n");
|
||||
sobjs[num_sobjs] = obj;
|
||||
num_sobjs ++;
|
||||
}
|
||||
|
||||
if (!strcmp(type, "XRef") && !pdf->trailer_dict)
|
||||
if (type && !strcmp(type, "XRef") && !pdf->trailer_dict)
|
||||
{
|
||||
// Save the trailer dictionary...
|
||||
pdfio_obj_t *encrypt_obj;
|
||||
|
||||
@@ -547,6 +547,8 @@ pdfioObjOpenStream(pdfio_obj_t *obj, // I - Object
|
||||
pdfio_stream_t *st; // Stream
|
||||
|
||||
|
||||
PDFIO_DEBUG("pdfioObjOpenStream(obj=%p(%lu), decode=%s)\n", (void *)obj, obj ? (unsigned long)obj->number : 0, decode ? "true" : "false");
|
||||
|
||||
// Range check input...
|
||||
if (!obj)
|
||||
return (NULL);
|
||||
@@ -566,7 +568,10 @@ pdfioObjOpenStream(pdfio_obj_t *obj, // I - Object
|
||||
|
||||
// No stream if there is no dict or offset to a stream...
|
||||
if (obj->value.type != PDFIO_VALTYPE_DICT || !obj->stream_offset)
|
||||
{
|
||||
PDFIO_DEBUG("pdfioObjOpenStream: value.type=%d, stream_offset=%ld\n", obj->value.type, (long)obj->stream_offset);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Open the stream...
|
||||
if ((st = _pdfioStreamOpen(obj, decode)) != NULL)
|
||||
|
||||
25
pdfio-page.c
25
pdfio-page.c
@@ -105,6 +105,10 @@ pdfioPageOpenStream(
|
||||
static _pdfio_value_t * // O - Value or NULL on error
|
||||
get_contents(pdfio_obj_t *page) // I - Page object
|
||||
{
|
||||
_pdfio_value_t *contents; // Contents value
|
||||
pdfio_obj_t *obj; // Contents object
|
||||
|
||||
|
||||
// Range check input...
|
||||
if (!page)
|
||||
return (NULL);
|
||||
@@ -119,5 +123,24 @@ get_contents(pdfio_obj_t *page) // I - Page object
|
||||
if (page->value.type != PDFIO_VALTYPE_DICT)
|
||||
return (NULL);
|
||||
|
||||
return (_pdfioDictGetValue(page->value.value.dict, "Contents"));
|
||||
contents = _pdfioDictGetValue(page->value.value.dict, "Contents");
|
||||
|
||||
if (contents->type == PDFIO_VALTYPE_INDIRECT)
|
||||
{
|
||||
// See if the indirect object is a stream or an array of indirect object
|
||||
// references...
|
||||
if ((obj = pdfioFileFindObj(page->pdf, contents->value.indirect.number)) != NULL)
|
||||
{
|
||||
if (obj->value.type == PDFIO_VALTYPE_NONE)
|
||||
{
|
||||
if (!_pdfioObjLoad(obj))
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (obj->value.type == PDFIO_VALTYPE_ARRAY)
|
||||
contents = &(obj->value);
|
||||
}
|
||||
}
|
||||
|
||||
return (contents);
|
||||
}
|
||||
|
||||
@@ -552,10 +552,13 @@ do_test_file(const char *filename, // I - PDF filename
|
||||
|
||||
if (!pdfioDictGetRect(dict, "MediaBox", &media_box))
|
||||
{
|
||||
if ((obj = pdfioDictGetObj(dict, "Parent")) != NULL)
|
||||
pdfio_obj_t *parent; // Parent object
|
||||
|
||||
while ((parent = pdfioDictGetObj(dict, "Parent")) != NULL)
|
||||
{
|
||||
dict = pdfioObjGetDict(obj);
|
||||
pdfioDictGetRect(dict, "MediaBox", &media_box);
|
||||
dict = pdfioObjGetDict(parent);
|
||||
if (pdfioDictGetRect(dict, "MediaBox", &media_box))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user