Add an xref table offset array to better detect xref table loops (Issue #148)

This commit is contained in:
Michael R Sweet
2026-01-13 18:40:44 -05:00
parent 4143808398
commit 5618c432cc
2 changed files with 28 additions and 6 deletions

View File

@@ -15,6 +15,7 @@ v1.6.2 - YYYY-MM-DD
- Increased the maximum length of a single string to 128k (Issue #146) - Increased the maximum length of a single string to 128k (Issue #146)
- 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)
- 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.

View File

@@ -1,7 +1,7 @@
// //
// PDF file functions for PDFio. // PDF file functions for PDFio.
// //
// Copyright © 2021-2025 by Michael R Sweet. // Copyright © 2021-2026 by Michael R Sweet.
// //
// Licensed under Apache License v2.0. See the file "LICENSE" for more // Licensed under Apache License v2.0. See the file "LICENSE" for more
// information. // information.
@@ -2006,6 +2006,9 @@ load_xref(
_pdfio_token_t tb; // Token buffer/stack _pdfio_token_t tb; // Token buffer/stack
off_t line_offset; // Offset to start of line off_t line_offset; // Offset to start of line
pdfio_obj_t *pages_obj; // Pages object pdfio_obj_t *pages_obj; // Pages object
size_t num_xrefs = 1; // Number of xref offsets
off_t xrefs[100] = { xref_offset };
// xref offsets
while (!done) while (!done)
@@ -2471,13 +2474,31 @@ load_xref(
{ {
done = true; done = true;
} }
else if (new_offset == xref_offset) else
{ {
_pdfioFileError(pdf, "Recursive xref table."); // See if we've seen this xref table before...
return (false); size_t i; // Looping var
}
xref_offset = new_offset; for (i = 0; i < num_xrefs; i ++)
{
if (new_offset == xrefs[i])
{
// Yes, error out...
_pdfioFileError(pdf, "Recursive xref table.");
return (false);
}
}
// No, save it...
if (i >= (sizeof(xrefs) / sizeof(xrefs[0])))
{
// Too many xref tables...
_pdfioFileError(pdf, "Too many xref tables.");
return (false);
}
xrefs[num_xrefs ++] = xref_offset = new_offset;
}
} }
// Once we have all of the xref tables loaded, get the important objects and // Once we have all of the xref tables loaded, get the important objects and