summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Harrison <rharrison@chromium.org>2018-02-23 22:10:06 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-02-23 22:10:06 +0000
commit26820b47434313b187d664ef702f48b1059bacb5 (patch)
treefb46186c97fd4fbd5a418a4cdc3541fdc6562ee8
parent3760afa05acd4955120a47b82ecf3d543541b791 (diff)
downloadpdfium-26820b47434313b187d664ef702f48b1059bacb5.tar.xz
Setup testing XFA using .in fileschromium/3355chromium/3354
This adds a number of {{}} style tags to the .in format that allow the fix-up script to inject XFA related boilerplate into the PDF, instead of having the .in file replicate this. A simple example XFA .in file, called xfa_example.in has been added as a template for future files to follow. Finally a run_xfa_tests.py has been added for executing all of the tests in testing/resources/xfa, which from what I can tell are not executed any other way. All of the existing PDFs in that directory are currently suppressed. BUG=pdfium:1008 Change-Id: Ie055b6640969ce8291b4c96b401ebf6887dfa0c0 Reviewed-on: https://pdfium-review.googlesource.com/27631 Commit-Queue: Ryan Harrison <rharrison@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org>
-rw-r--r--testing/SUPPRESSIONS15
-rw-r--r--testing/resources/xfa/xfa_example.in71
-rw-r--r--testing/resources/xfa/xfa_example_expected.pdf.0.pngbin0 -> 4806 bytes
-rwxr-xr-xtesting/tools/fixup_pdf_template.py191
-rwxr-xr-xtesting/tools/run_xfa_tests.py16
5 files changed, 288 insertions, 5 deletions
diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS
index 1edc158161..317f370b31 100644
--- a/testing/SUPPRESSIONS
+++ b/testing/SUPPRESSIONS
@@ -321,3 +321,18 @@ bug_735912.in * * noxfa
#
bug_492.in * nov8 *
+#
+# XFA Tests
+#
+# TODO(rharrison): Create expectations for existing files.
+barcode_test.pdf * * *
+dynamic_list_box_allow_multiple_selection.pdf * * *
+dynamic_password_field_background_fill.pdf * * *
+dynamic_table_color_and_width.pdf * * *
+email_recommended.pdf * * *
+resolve_nodes.pdf * * *
+standard_symbols.pdf * * *
+static_list_box_caption.pdf * * *
+static_password_field_rotate.pdf * * *
+xfa_node_caption.pdf * * *
+
diff --git a/testing/resources/xfa/xfa_example.in b/testing/resources/xfa/xfa_example.in
new file mode 100644
index 0000000000..d8be96f305
--- /dev/null
+++ b/testing/resources/xfa/xfa_example.in
@@ -0,0 +1,71 @@
+{{header}}
+
+%% Original object ID: 24 0
+{{object 1 0}}
+<<
+ /AcroForm 2 0 R
+ /Extensions <<
+ /ADBE <<
+ /BaseVersion /1.7
+ /ExtensionLevel 8
+ >>
+ >>
+ /NeedsRendering true
+ /Type /Catalog
+>>
+endobj
+
+%% Original object ID: 32 0
+{{object 2 0}}
+<<
+ /XFA [
+ (preamble)
+ 3 0 R
+ (config)
+ 4 0 R
+ (template)
+ 5 0 R
+ (localeSet)
+ 6 0 R
+ (postamble)
+ 7 0 R
+ ]
+>>
+endobj
+
+{{xfapreamble 3 0}}
+{{xfaconfig 4 0}}
+
+{{object 5 0}}
+<<
+ {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
+ <subform name="form1" layout="tb" locale="zh_CN" restoreState="auto">
+ <pageSet>
+ <pageArea name="Page1" id="Page1">
+ <contentArea x="0.25in" y="0.25in" w="7.75in" h="11.25in"/>
+ <medium stock="default" short="612pt" long="792pt"/>
+ </pageArea>
+ </pageSet>
+ <subform w="576pt" h="756pt" name="Page1">
+ <draw name="HelloWorld" y="0.5in" x="0.5in" w="5in" h="2in">
+ <value>
+ <text>Hello, world.</text>
+ </value>
+ </draw>
+ </subform>
+ </subform>
+</template>
+endstream
+endobj
+
+{{xfalocale 6 0}}
+
+{{xfapostamble 7 0}}
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF \ No newline at end of file
diff --git a/testing/resources/xfa/xfa_example_expected.pdf.0.png b/testing/resources/xfa/xfa_example_expected.pdf.0.png
new file mode 100644
index 0000000000..9a682f7186
--- /dev/null
+++ b/testing/resources/xfa/xfa_example_expected.pdf.0.png
Binary files differ
diff --git a/testing/tools/fixup_pdf_template.py b/testing/tools/fixup_pdf_template.py
index 19f75e0263..fed0ed8e0a 100755
--- a/testing/tools/fixup_pdf_template.py
+++ b/testing/tools/fixup_pdf_template.py
@@ -8,12 +8,20 @@
There are several places in a PDF file where byte-offsets are required. This
script replaces {{name}}-style variables in the input with calculated results
- {{header}} - expands to the header comment required for PDF files.
- {{xref}} - expands to a generated xref table, noting the offset.
- {{trailer}} - expands to a standard trailer with "1 0 R" as the /Root.
- {{startxref} - expands to a startxref directive followed by correct offset.
+ {{header}} - expands to the header comment required for PDF files.
+ {{xref}} - expands to a generated xref table, noting the offset.
+ {{trailer}} - expands to a standard trailer with "1 0 R" as the /Root.
+ {{startxref} - expands to a startxref directive followed by correct offset.
{{object x y}} - expands to |x y obj| declaration, noting the offset.
- {{streamlen}} - expands to |/Length n|.
+ {{streamlen}} - expands to |/Length n|.
+ {{xfapreamble x y}} - expands to an object |x y obj| containing a XML preamble
+ to be used in XFA docs.
+ {{xfaconfig x y}} - expands to an object |x y obj| containing a config XML
+ block to be used in XFA docs.
+ {{xfalocale x y}} - expands to an object |x y obj| containing a locale XML
+ block to be used in XFA docs.
+ {{xfapostamble x y}} - expands to an object |x y obj| containing a XML
+ posteamble to be used in XFA docs.
"""
import cStringIO
@@ -51,6 +59,154 @@ class TemplateProcessor:
STREAMLEN_TOKEN = '{{streamlen}}'
STREAMLEN_REPLACEMENT = '/Length %d'
+ XFAPREAMBLE_PATTERN = r'\{\{xfapreamble\s+(\d+)\s+(\d+)\}\}'
+ XFAPREAMBLE_REPLACEMENT = '%d %d obj\n<<\n /Length %d\n>>\nstream\n%s\nendstream\nendobj\n'
+ XFAPREAMBLE_STREAM = '<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2018-02-23T21:37:11Z" uuid="21482798-7bf0-40a4-bc5d-3cefdccf32b5">'
+
+ XFAPOSTAMBLE_PATTERN = r'\{\{xfapostamble\s+(\d+)\s+(\d+)\}\}'
+ XFAPOSTAMBLE_REPLACEMENT = '%d %d obj\n<<\n /Length %d\n>>\nstream\n%s\nendstream\nendobj\n'
+ XFAPOSTAMBLE_STREAM = '</xdp:xdp>'
+
+ XFACONFIG_PATTERN = r'\{\{xfaconfig\s+(\d+)\s+(\d+)\}\}'
+ XFACONFIG_REPLACEMENT = '%d %d obj\n<<\n /Length %d\n>>\nstream\n%s\nendstream\nendobj\n'
+ XFACONFIG_STREAM = '''<config xmlns="http://www.xfa.org/schema/xci/3.0/">
+ <agent name="designer">
+ <destination>pdf</destination>
+ <pdf>
+ <fontInfo/>
+ </pdf>
+ </agent>
+ <present>
+ <pdf>
+ <version>1.7</version>
+ <adobeExtensionLevel>8</adobeExtensionLevel>
+ <renderPolicy>client</renderPolicy>
+ <scriptModel>XFA</scriptModel>
+ <interactive>1</interactive>
+ </pdf>
+ <xdp>
+ <packets>*</packets>
+ </xdp>
+ <destination>pdf</destination>
+ <script>
+ <runScripts>server</runScripts>
+ </script>
+ </present>
+ <acrobat>
+ <acrobat7>
+ <dynamicRender>required</dynamicRender>
+ </acrobat7>
+ <validate>preSubmit</validate>
+ </acrobat>
+</config>'''
+
+ XFALOCALE_PATTERN = r'\{\{xfalocale\s+(\d+)\s+(\d+)\}\}'
+ XFALOCALE_REPLACEMENT = '%d %d obj\n<<\n /Length %d\n>>\nstream\n%s\nendstream\nendobj\n'
+ XFALOCALE_STREAM = '''<localeSet xmlns="http://www.xfa.org/schema/xfa-locale-set/2.7/">
+ <locale name="en_US" desc="English (United States)">
+ <calendarSymbols name="gregorian">
+ <monthNames>
+ <month>January</month>
+ <month>February</month>
+ <month>March</month>
+ <month>April</month>
+ <month>May</month>
+ <month>June</month>
+ <month>July</month>
+ <month>August</month>
+ <month>September</month>
+ <month>October</month>
+ <month>November</month>
+ <month>December</month>
+ </monthNames>
+ <monthNames abbr="1">
+ <month>Jan</month>
+ <month>Feb</month>
+ <month>Mar</month>
+ <month>Apr</month>
+ <month>May</month>
+ <month>Jun</month>
+ <month>Jul</month>
+ <month>Aug</month>
+ <month>Sep</month>
+ <month>Oct</month>
+ <month>Nov</month>
+ <month>Dec</month>
+ </monthNames>
+ <dayNames>
+ <day>Sunday</day>
+ <day>Monday</day>
+ <day>Tuesday</day>
+ <day>Wednesday</day>
+ <day>Thursday</day>
+ <day>Friday</day>
+ <day>Saturday</day>
+ </dayNames>
+ <dayNames abbr="1">
+ <day>Sun</day>
+ <day>Mon</day>
+ <day>Tue</day>
+ <day>Wed</day>
+ <day>Thu</day>
+ <day>Fri</day>
+ <day>Sat</day>
+ </dayNames>
+ <meridiemNames>
+ <meridiem>AM</meridiem>
+ <meridiem>PM</meridiem>
+ </meridiemNames>
+ <eraNames>
+ <era>BC</era>
+ <era>AD</era>
+ </eraNames>
+ </calendarSymbols>
+ <datePatterns>
+ <datePattern name="full">EEEE, MMMM D, YYYY</datePattern>
+ <datePattern name="long">MMMM D, YYYY</datePattern>
+ <datePattern name="med">MMM D, YYYY</datePattern>
+ <datePattern name="short">M/D/YY</datePattern>
+ </datePatterns>
+ <timePatterns>
+ <timePattern name="full">h:MM:SS A Z</timePattern>
+ <timePattern name="long">h:MM:SS A Z</timePattern>
+ <timePattern name="med">h:MM:SS A</timePattern>
+ <timePattern name="short">h:MM A</timePattern>
+ </timePatterns>
+ <dateTimeSymbols>GyMdkHmsSEDFwWahKzZ</dateTimeSymbols>
+ <numberPatterns>
+ <numberPattern name="numeric">z,zz9.zzz</numberPattern>
+ <numberPattern name="currency">$z,zz9.99|($z,zz9.99)</numberPattern>
+ <numberPattern name="percent">z,zz9%</numberPattern>
+ </numberPatterns>
+ <numberSymbols>
+ <numberSymbol name="decimal">.</numberSymbol>
+ <numberSymbol name="grouping">,</numberSymbol>
+ <numberSymbol name="percent">%</numberSymbol>
+ <numberSymbol name="minus">-</numberSymbol>
+ <numberSymbol name="zero">0</numberSymbol>
+ </numberSymbols>
+ <currencySymbols>
+ <currencySymbol name="symbol">$</currencySymbol>
+ <currencySymbol name="isoname">USD</currencySymbol>
+ <currencySymbol name="decimal">.</currencySymbol>
+ </currencySymbols>
+ <typefaces>
+ <typeface name="Myriad Pro"/>
+ <typeface name="Minion Pro"/>
+ <typeface name="Courier Std"/>
+ <typeface name="Adobe Pi Std"/>
+ <typeface name="Adobe Hebrew"/>
+ <typeface name="Adobe Arabic"/>
+ <typeface name="Adobe Thai"/>
+ <typeface name="Kozuka Gothic Pro-VI M"/>
+ <typeface name="Kozuka Mincho Pro-VI R"/>
+ <typeface name="Adobe Ming Std L"/>
+ <typeface name="Adobe Song Std L"/>
+ <typeface name="Adobe Myungjo Std M"/>
+ </typefaces>
+ </locale>
+</localeSet>'''
+
def __init__(self):
self.streamlen_state = StreamLenState.START
self.streamlens = []
@@ -109,10 +265,35 @@ class TemplateProcessor:
if match:
self.insert_xref_entry(int(match.group(1)), int(match.group(2)))
line = re.sub(self.OBJECT_PATTERN, self.OBJECT_REPLACEMENT, line)
+ line = self.replace_xfa_tag(line,
+ self.XFAPREAMBLE_PATTERN,
+ self.XFAPREAMBLE_REPLACEMENT,
+ self.XFAPREAMBLE_STREAM)
+ line = self.replace_xfa_tag(line,
+ self.XFACONFIG_PATTERN,
+ self.XFACONFIG_REPLACEMENT,
+ self.XFACONFIG_STREAM)
+ line = self.replace_xfa_tag(line,
+ self.XFALOCALE_PATTERN,
+ self.XFALOCALE_REPLACEMENT,
+ self.XFALOCALE_STREAM)
+ line = self.replace_xfa_tag(line,
+ self.XFAPOSTAMBLE_PATTERN,
+ self.XFAPOSTAMBLE_REPLACEMENT,
+ self.XFAPOSTAMBLE_STREAM)
self.offset += len(line)
return line
+ def replace_xfa_tag(self, line, pattern, replacement, stream):
+ match = re.match(pattern, line)
+ if match:
+ x = int(match.group(1))
+ y = int(match.group(2))
+ self.insert_xref_entry(x, y)
+ line = replacement % (x, y, len(stream), stream)
+ return line
+
def expand_file(input_path, output_path):
processor = TemplateProcessor()
diff --git a/testing/tools/run_xfa_tests.py b/testing/tools/run_xfa_tests.py
new file mode 100755
index 0000000000..6647cfd939
--- /dev/null
+++ b/testing/tools/run_xfa_tests.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+# Copyright 2018 The PDFium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import sys
+
+import test_runner
+
+def main():
+ runner = test_runner.TestRunner('xfa')
+ runner.SetEnforceExpectedImages(True)
+ return runner.Run()
+
+if __name__ == '__main__':
+ sys.exit(main())