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`.
|
- Added missing range checks to `pdfioArrayCopy` and `pdfioDictCopy`.
|
||||||
- Refactored PDF encryption code to fix unlocking with certain files.
|
- Refactored PDF encryption code to fix unlocking with certain files.
|
||||||
- Improved xref table loop detection (Issue #148)
|
- 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 an error propagation bug when reading too-long values (Issue #146)
|
||||||
- Fixed a Clang warning.
|
- Fixed a Clang warning.
|
||||||
|
|
||||||
|
|||||||
@@ -2621,19 +2621,19 @@ repair_xref(
|
|||||||
|
|
||||||
_pdfioTokenFlush(&tb);
|
_pdfioTokenFlush(&tb);
|
||||||
|
|
||||||
if (type && !strcmp(line, "stream"))
|
if (!strcmp(line, "stream"))
|
||||||
{
|
{
|
||||||
// Possible object or XRef stream...
|
// Possible object or XRef stream...
|
||||||
obj->stream_offset = _pdfioFileTell(pdf);
|
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");
|
PDFIO_DEBUG("repair_xref: Object stream...\n");
|
||||||
sobjs[num_sobjs] = obj;
|
sobjs[num_sobjs] = obj;
|
||||||
num_sobjs ++;
|
num_sobjs ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(type, "XRef") && !pdf->trailer_dict)
|
if (type && !strcmp(type, "XRef") && !pdf->trailer_dict)
|
||||||
{
|
{
|
||||||
// Save the trailer dictionary...
|
// Save the trailer dictionary...
|
||||||
pdfio_obj_t *encrypt_obj;
|
pdfio_obj_t *encrypt_obj;
|
||||||
|
|||||||
@@ -547,6 +547,8 @@ pdfioObjOpenStream(pdfio_obj_t *obj, // I - Object
|
|||||||
pdfio_stream_t *st; // Stream
|
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...
|
// Range check input...
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return (NULL);
|
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...
|
// No stream if there is no dict or offset to a stream...
|
||||||
if (obj->value.type != PDFIO_VALTYPE_DICT || !obj->stream_offset)
|
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);
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
// Open the stream...
|
// Open the stream...
|
||||||
if ((st = _pdfioStreamOpen(obj, decode)) != NULL)
|
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
|
static _pdfio_value_t * // O - Value or NULL on error
|
||||||
get_contents(pdfio_obj_t *page) // I - Page object
|
get_contents(pdfio_obj_t *page) // I - Page object
|
||||||
{
|
{
|
||||||
|
_pdfio_value_t *contents; // Contents value
|
||||||
|
pdfio_obj_t *obj; // Contents object
|
||||||
|
|
||||||
|
|
||||||
// Range check input...
|
// Range check input...
|
||||||
if (!page)
|
if (!page)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@@ -119,5 +123,24 @@ get_contents(pdfio_obj_t *page) // I - Page object
|
|||||||
if (page->value.type != PDFIO_VALTYPE_DICT)
|
if (page->value.type != PDFIO_VALTYPE_DICT)
|
||||||
return (NULL);
|
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 (!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);
|
dict = pdfioObjGetDict(parent);
|
||||||
pdfioDictGetRect(dict, "MediaBox", &media_box);
|
if (pdfioDictGetRect(dict, "MediaBox", &media_box))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user