Handle malformed DocumentInfo (#497)

User submitted a PDF in which /Trailer /Info pointed to the XMP metadata
block instead of a DocumentInfo dictionary. Fix and add test.
This commit is contained in:
James R. Barlow
2020-03-03 03:27:01 -08:00
parent e429c3d729
commit b3b61c152c
2 changed files with 39 additions and 10 deletions
+12 -5
View File
@@ -694,11 +694,18 @@ def convert_to_pdfa(input_pdf, input_ps_stub, context):
# stamping them out as soon as possible.
modified = False
with pikepdf.open(input_pdf) as pdf_file:
if pdf_file.docinfo:
for k, v in pdf_file.docinfo.items():
if b'\x00' in bytes(v):
pdf_file.docinfo[k] = bytes(v).replace(b'\x00', b'')
modified = True
try:
len(pdf_file.docinfo)
except TypeError:
context.log.error(
"File contains a malformed DocumentInfo block - continuing anyway"
)
else:
if pdf_file.docinfo:
for k, v in pdf_file.docinfo.items():
if b'\x00' in bytes(v):
pdf_file.docinfo[k] = bytes(v).replace(b'\x00', b'')
modified = True
if modified:
pdf_file.save(fix_docinfo_file)
else:
+27 -5
View File
@@ -31,8 +31,11 @@ import pytest
from pikepdf.models.metadata import decode_pdf_date
from ocrmypdf._jobcontext import PDFContext
from ocrmypdf._pipeline import convert_to_pdfa
from ocrmypdf.cli import parser
from ocrmypdf.exceptions import ExitCode
from ocrmypdf.pdfa import SRGB_ICC_PROFILE, file_claims_pdfa, generate_pdfa_ps
from ocrmypdf.pdfinfo import PdfInfo
try:
import fitz
@@ -313,11 +316,6 @@ def test_metadata_fixup_warning(resources, outdir, caplog):
def test_prevent_gs_invalid_xml(resources, outdir):
from ocrmypdf.cli import parser
from ocrmypdf._pipeline import convert_to_pdfa
from ocrmypdf.pdfa import generate_pdfa_ps
from ocrmypdf.pdfinfo import PdfInfo
generate_pdfa_ps(outdir / 'pdfa.ps')
copyfile(resources / 'trivial.pdf', outdir / 'layers.rendered.pdf')
@@ -349,3 +347,27 @@ def test_prevent_gs_invalid_xml(resources, outdir):
# Ensure we did not carry the nul forward.
assert mm.find(b'�', xmp_start, xmp_end) == -1, "found escaped nul"
assert mm.find(b'\x00', xmp_start, xmp_end) == -1
def test_malformed_docinfo(caplog, resources, outdir):
generate_pdfa_ps(outdir / 'pdfa.ps')
# copyfile(resources / 'trivial.pdf', outdir / 'layers.rendered.pdf')
with pikepdf.open(resources / 'trivial.pdf') as pike:
pike.trailer.Info = pikepdf.Stream(pike, b"<xml></xml>")
pike.save(outdir / 'layers.rendered.pdf', fix_metadata_version=False)
options = parser.parse_args(
args=['-j', '1', '--output-type', 'pdfa-2', 'a.pdf', 'b.pdf']
)
pdfinfo = PdfInfo(outdir / 'layers.rendered.pdf')
context = PDFContext(options, outdir, outdir / 'layers.rendered.pdf', pdfinfo)
convert_to_pdfa(
str(outdir / 'layers.rendered.pdf'), str(outdir / 'pdfa.ps'), context
)
print(caplog.records)
assert any(
'malformed DocumentInfo block' in record.message for record in caplog.records
)