From f08f3989200a532634ab5fa7d2b0e8ec6edba20b Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 7 May 2022 16:07:52 -0400 Subject: Test json v2 with invalid stream data --- TODO | 2 - qpdf/qtest/qpdf.test | 32 +++++- qpdf/qtest/qpdf/bad-data-4.out | Bin 0 -> 48 bytes qpdf/qtest/qpdf/bad-data-json.out | 3 + qpdf/qtest/qpdf/json-bad-data-json-file-v2.out | 126 +++++++++++++++++++++++ qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out | 126 +++++++++++++++++++++++ 6 files changed, 284 insertions(+), 5 deletions(-) create mode 100644 qpdf/qtest/qpdf/bad-data-4.out create mode 100644 qpdf/qtest/qpdf/bad-data-json.out create mode 100644 qpdf/qtest/qpdf/json-bad-data-json-file-v2.out create mode 100644 qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out diff --git a/TODO b/TODO index b184d81f..68abb326 100644 --- a/TODO +++ b/TODO @@ -60,8 +60,6 @@ General things to remember: when present in the schema. It's reasonable for people to check for presence of a key. Most languages make this easy to do. -* Test stream with invalid data - * When we get to full serialization, add json serialization performance test. diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 23dce379..9f97540a 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -1110,7 +1110,7 @@ my @json_files = ( ['V4-aes', ['--json-key=encrypt']], ['V4-aes', ['--json-key=encrypt', '--show-encryption-key']], ); -$n_tests += 2 * scalar(@json_files); +$n_tests += 5 + (2 * scalar(@json_files)); foreach my $d (@json_files) { my ($file, $xargs) = @$d; @@ -1134,7 +1134,8 @@ foreach my $d (@json_files) my $in = "$file.pdf"; $td->runtest("json v1 $out", {$td->COMMAND => - ['qpdf', '--json=1', '--test-json-schema', @v1_xargs, $in]}, + ['qpdf', '--json=1', '--test-json-schema', + @v1_xargs, $in]}, {$td->FILE => "$out-v1.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); $td->runtest("json v2 $out", @@ -1144,6 +1145,31 @@ foreach my $d (@json_files) $td->NORMALIZE_NEWLINES); } +$td->runtest("bad json stream data (inline)", + {$td->COMMAND => + "qpdf --json=2 --test-json-schema" . + " --json-stream-data=inline bad-data.pdf > a.json"}, + {$td->FILE => "bad-data-json.out", $td->EXIT_STATUS => 3}, + $td->NORMALIZE_NEWLINES); +$td->runtest("check (inline)", + {$td->FILE => "a.json"}, + {$td->FILE => "json-bad-data-json-inline-v2.out"}, + $td->NORMALIZE_NEWLINES); +$td->runtest("bad json stream data (file)", + {$td->COMMAND => + "qpdf --json=2 --test-json-schema" . + " --json-stream-data=file --json-stream-prefix=auto" . + " bad-data.pdf > a.json"}, + {$td->FILE => "bad-data-json.out", $td->EXIT_STATUS => 3}, + $td->NORMALIZE_NEWLINES); +$td->runtest("check (file)", + {$td->FILE => "a.json"}, + {$td->FILE => "json-bad-data-json-file-v2.out"}, + $td->NORMALIZE_NEWLINES); +$td->runtest("check stream (file)", + {$td->FILE => "auto-4"}, + {$td->FILE => "bad-data-4.out"}); + show_ntests(); # ---------- $td->notify("--- Page API Tests ---"); @@ -5778,6 +5804,6 @@ sub get_md5_checksum sub cleanup { - system("rm -rf *.ps *.pnm ?.pdf ?.qdf *.enc* tif1 tif2 tiff-cache"); + system("rm -rf a.json *.ps *.pnm ?.pdf ?.qdf *.enc* tif1 tif2 tiff-cache"); system("rm -rf *split-out* ???-kfo.pdf *.tmpout \@file.pdf auto-*"); } diff --git a/qpdf/qtest/qpdf/bad-data-4.out b/qpdf/qtest/qpdf/bad-data-4.out new file mode 100644 index 00000000..ba572187 Binary files /dev/null and b/qpdf/qtest/qpdf/bad-data-4.out differ diff --git a/qpdf/qtest/qpdf/bad-data-json.out b/qpdf/qtest/qpdf/bad-data-json.out new file mode 100644 index 00000000..00019fec --- /dev/null +++ b/qpdf/qtest/qpdf/bad-data-json.out @@ -0,0 +1,3 @@ +WARNING: bad-data.pdf (offset 319): error decoding stream data for object 4 0: LZWDecoder: bad code received +WARNING: bad-data.pdf (offset 319): stream will be re-processed without filtering to avoid data loss +qpdf: operation succeeded with warnings diff --git a/qpdf/qtest/qpdf/json-bad-data-json-file-v2.out b/qpdf/qtest/qpdf/json-bad-data-json-file-v2.out new file mode 100644 index 00000000..147dc372 --- /dev/null +++ b/qpdf/qtest/qpdf/json-bad-data-json-file-v2.out @@ -0,0 +1,126 @@ +{ + "version": 2, + "parameters": { + "decodelevel": "generalized" + }, + "pages": [ + { + "contents": [ + "4 0 R" + ], + "images": [], + "label": null, + "object": "3 0 R", + "outlines": [], + "pageposfrom1": 1 + } + ], + "pagelabels": [], + "acroform": { + "fields": [], + "hasacroform": false, + "needappearances": false + }, + "attachments": {}, + "encrypt": { + "capabilities": { + "accessibility": true, + "extract": true, + "modify": true, + "modifyannotations": true, + "modifyassembly": true, + "modifyforms": true, + "modifyother": true, + "printhigh": true, + "printlow": true + }, + "encrypted": false, + "ownerpasswordmatched": false, + "parameters": { + "P": 0, + "R": 0, + "V": 0, + "bits": 0, + "filemethod": "none", + "key": null, + "method": "none", + "streammethod": "none", + "stringmethod": "none" + }, + "userpasswordmatched": false + }, + "outlines": [], + "qpdf": { + "jsonversion": 2, + "pdfversion": "1.3", + "objects": { + "obj:1 0 R": { + "value": { + "/Pages": "2 0 R", + "/Type": "/Catalog" + } + }, + "obj:2 0 R": { + "value": { + "/Count": 1, + "/Kids": [ + "3 0 R" + ], + "/Type": "/Pages" + } + }, + "obj:3 0 R": { + "value": { + "/Contents": "4 0 R", + "/MediaBox": [ + 0, + 0, + 612, + 792 + ], + "/Parent": "2 0 R", + "/Resources": { + "/Font": { + "/F1": "5 0 R" + }, + "/ProcSet": "6 0 R" + }, + "/Type": "/Page" + } + }, + "obj:4 0 R": { + "stream": { + "datafile": "auto-4", + "dict": { + "/Filter": "/LZWDecode" + } + } + }, + "obj:5 0 R": { + "value": { + "/BaseFont": "/Helvetica", + "/Encoding": "/WinAnsiEncoding", + "/Name": "/F1", + "/Subtype": "/Type1", + "/Type": "/Font" + } + }, + "obj:6 0 R": { + "value": [ + "/PDF", + "/Text" + ] + }, + "trailer": { + "value": { + "/ID": [ + "b:4a5e383aee3970ed44eb87234d7f93f1", + "b:4a5e383aee3970ed44eb87234d7f93f1" + ], + "/Root": "1 0 R", + "/Size": 7 + } + } + } + } +} diff --git a/qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out b/qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out new file mode 100644 index 00000000..bfd7ad36 --- /dev/null +++ b/qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out @@ -0,0 +1,126 @@ +{ + "version": 2, + "parameters": { + "decodelevel": "generalized" + }, + "pages": [ + { + "contents": [ + "4 0 R" + ], + "images": [], + "label": null, + "object": "3 0 R", + "outlines": [], + "pageposfrom1": 1 + } + ], + "pagelabels": [], + "acroform": { + "fields": [], + "hasacroform": false, + "needappearances": false + }, + "attachments": {}, + "encrypt": { + "capabilities": { + "accessibility": true, + "extract": true, + "modify": true, + "modifyannotations": true, + "modifyassembly": true, + "modifyforms": true, + "modifyother": true, + "printhigh": true, + "printlow": true + }, + "encrypted": false, + "ownerpasswordmatched": false, + "parameters": { + "P": 0, + "R": 0, + "V": 0, + "bits": 0, + "filemethod": "none", + "key": null, + "method": "none", + "streammethod": "none", + "stringmethod": "none" + }, + "userpasswordmatched": false + }, + "outlines": [], + "qpdf": { + "jsonversion": 2, + "pdfversion": "1.3", + "objects": { + "obj:1 0 R": { + "value": { + "/Pages": "2 0 R", + "/Type": "/Catalog" + } + }, + "obj:2 0 R": { + "value": { + "/Count": 1, + "/Kids": [ + "3 0 R" + ], + "/Type": "/Pages" + } + }, + "obj:3 0 R": { + "value": { + "/Contents": "4 0 R", + "/MediaBox": [ + 0, + 0, + 612, + 792 + ], + "/Parent": "2 0 R", + "/Resources": { + "/Font": { + "/F1": "5 0 R" + }, + "/ProcSet": "6 0 R" + }, + "/Type": "/Page" + } + }, + "obj:4 0 R": { + "stream": { + "data": "eJxzCuFSUNB3M1QwMlEISQOyzY2AyEAhJAXI1gjIL0ksyddUCMnicg3hAgDLAQnI", + "dict": { + "/Filter": "/LZWDecode" + } + } + }, + "obj:5 0 R": { + "value": { + "/BaseFont": "/Helvetica", + "/Encoding": "/WinAnsiEncoding", + "/Name": "/F1", + "/Subtype": "/Type1", + "/Type": "/Font" + } + }, + "obj:6 0 R": { + "value": [ + "/PDF", + "/Text" + ] + }, + "trailer": { + "value": { + "/ID": [ + "b:4a5e383aee3970ed44eb87234d7f93f1", + "b:4a5e383aee3970ed44eb87234d7f93f1" + ], + "/Root": "1 0 R", + "/Size": 7 + } + } + } + } +} -- cgit v1.2.3-54-g00ecf