Check for and reject Adobe LiveCycle Designer PDFs

These are the ones that display a "Please wait..." message.

Closes #296
This commit is contained in:
James R. Barlow
2018-09-13 21:50:51 -07:00
parent 517b385fe5
commit 686207ab7f
5 changed files with 56 additions and 11 deletions
+7
View File
@@ -170,6 +170,13 @@ def repair_and_parse_pdf(
log.error(e)
raise InputFileError()
if pdfinfo.needs_rendering:
log.error(
"This PDF contains dynamic XFA forms created by Adobe LiveCycle "
"Designer and can only be read by Adobe Acrobat or Adobe Reader."
)
raise InputFileError()
if pdfinfo.has_userunit and options.output_type.startswith('pdfa'):
log.error(
"This input file uses a PDF feature that is not supported "
+7 -11
View File
@@ -611,7 +611,7 @@ def _pdf_get_pageinfo(pdf, pageno: int, infile):
def _pdf_get_all_pageinfo(infile):
pdf = pikepdf.open(infile)
return [PageInfo(pdf, n, infile) for n in range(len(pdf.pages))]
return [PageInfo(pdf, n, infile) for n in range(len(pdf.pages))], pdf
class PageInfo:
@@ -697,7 +697,8 @@ class PdfInfo:
"""
def __init__(self, infile):
self._infile = infile
self._pages = _pdf_get_all_pageinfo(infile)
self._pages, pdf = _pdf_get_all_pageinfo(infile)
self._needs_rendering = pdf.root.get('/NeedsRendering', False)
@property
def pages(self):
@@ -718,6 +719,10 @@ class PdfInfo:
raise NotImplementedError("can't get filename from stream")
return self._infile
@property
def needs_rendering(self):
return self._needs_rendering
def __getitem__(self, item):
return self._pages[item]
@@ -727,15 +732,6 @@ class PdfInfo:
def __repr__(self):
return "<PdfInfo('...'), page count={}>".format(len(self))
# def __getstate__(self):
# state = {'_infile': self._infile}
# return state
#
# def __setstate__(self, state):
# self._infile = state['_infile']
# self._pages = _pdf_get_all_pageinfo(self._infile)
def main():
import argparse
parser = argparse.ArgumentParser()
+5
View File
@@ -109,6 +109,11 @@ licensed under the specified license.
- @jbarlow83
- @jbarlow83
- CC-BY-SA 4.0
* - livecycle.pdf
- a minimal PDF that claims to use dynamic XFA forms
- @jbarlow83
- @jbarlow83
- CC-BY-SA 4.0
* - masks.pdf
- file containing explicit masks and a stencil mask drawn without a proper transformation matrix; printout of a German Wikipedia article (CC-BY-SA)
- @supergrobi
+28
View File
@@ -0,0 +1,28 @@
%PDF-1.7
%¿÷¢þ
1 0 obj
<< /NeedsRendering true /Pages 2 0 R /Type /Catalog >>
endobj
2 0 obj
<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
endobj
3 0 obj
<< /Contents 4 0 R /MediaBox [ 0 0 300 300 ] /Parent 2 0 R /Resources << >> /Type /Page >>
endobj
4 0 obj
<< /Length 0 >>
stream
endstream
endobj
xref
0 5
0000000000 65535 f
0000000015 00000 n
0000000085 00000 n
0000000144 00000 n
0000000250 00000 n
trailer << /Root 1 0 R /Size 5 /ID [<8088c23e0edc07ef4fbed3daa55f52ed><9d36eee510d20004f32255f5800b6fd7>] >>
startxref
299
%%EOF
+9
View File
@@ -925,3 +925,12 @@ def test_output_is_symlink(spoof_tesseract_noop, resources, outdir):
)
assert p.returncode == ExitCode.ok, err
assert (outdir / 'out.pdf').stat().st_size > 0, 'target file not created'
def test_livecycle(resources, no_outpdf):
p, _, err = run_ocrmypdf(
resources / 'livecycle.pdf',
no_outpdf
)
assert p.returncode == ExitCode.input_file, err