From 718b14008ba9c1ad43ff2bfadfa70a60acdfdb82 Mon Sep 17 00:00:00 2001 From: m-holger Date: Wed, 18 Sep 2024 16:51:37 +0100 Subject: [PATCH] Change QPDFWriter stream_decode_level default to qpdf_dl_generalized Also, fix disabling of preserve_encryption to be ignore stream_decode_level, but disable preserve_encryption if compress_streams is false. Fixes #1286 --- ChangeLog | 5 +++++ libqpdf/QPDFWriter.cc | 2 +- libqpdf/qpdf/QPDFWriter_private.hh | 2 +- qpdf/qtest/encryption.test | 2 +- qpdf/qtest/inline-images.test | 2 +- qpdf/qtest/qpdf/bad-encryption-length.out | 4 ++-- qpdf/qtest/qpdf/damaged-inline-image.out | 3 +++ qpdf/qtest/qpdf/fuzz-16214.out | 5 +++++ qpdf/qtest/qpdf/invalid-id-xref.out | 2 ++ .../qpdf/job-json-input-file-password.pdf | Bin 7343 -> 6530 bytes 10 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 qpdf/qtest/qpdf/damaged-inline-image.out diff --git a/ChangeLog b/ChangeLog index ba03fe89..283cd8cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,11 @@ * Add C API function qpdf_oh_free_buffer to release memory allocated by stream data functions. +2024-09-19 M Holger + + * Bug fix: QPDFWriter stream DecodeLevel incorrectly defaulted to + none instead of generalied. Fixes #1286. + 2024-08-25 M Holger * Add new command-line arguments --remove-metadata and --remove-info diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index 4dda1dc0..7b8daf5b 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -2126,7 +2126,7 @@ QPDFWriter::doWriteSetup() if (m->encrypted) { // Encryption has been explicitly set m->preserve_encryption = false; - } else if (m->normalize_content || m->stream_decode_level || m->pclm || m->qdf_mode) { + } else if (m->normalize_content || !m->compress_streams || m->pclm || m->qdf_mode) { // Encryption makes looking at contents pretty useless. If the user explicitly encrypted // though, we still obey that. m->preserve_encryption = false; diff --git a/libqpdf/qpdf/QPDFWriter_private.hh b/libqpdf/qpdf/QPDFWriter_private.hh index 5a46d907..cbb667fd 100644 --- a/libqpdf/qpdf/QPDFWriter_private.hh +++ b/libqpdf/qpdf/QPDFWriter_private.hh @@ -65,7 +65,7 @@ class QPDFWriter::Members bool normalize_content{false}; bool compress_streams{true}; bool compress_streams_set{false}; - qpdf_stream_decode_level_e stream_decode_level{qpdf_dl_none}; + qpdf_stream_decode_level_e stream_decode_level{qpdf_dl_generalized}; bool stream_decode_level_set{false}; bool recompress_flate{false}; bool qdf_mode{false}; diff --git a/qpdf/qtest/encryption.test b/qpdf/qtest/encryption.test index 9263602e..3173dbbb 100644 --- a/qpdf/qtest/encryption.test +++ b/qpdf/qtest/encryption.test @@ -723,7 +723,7 @@ $td->runtest("check file's validity", $td->runtest("handle missing/invalid Length", {$td->COMMAND => "qpdf --check bad-encryption-length.pdf"}, {$td->FILE => "bad-encryption-length.out", - $td->EXIT_STATUS => 0}, + $td->EXIT_STATUS => 3}, $td->NORMALIZE_NEWLINES); cleanup(); diff --git a/qpdf/qtest/inline-images.test b/qpdf/qtest/inline-images.test index 20388da5..05af5d68 100644 --- a/qpdf/qtest/inline-images.test +++ b/qpdf/qtest/inline-images.test @@ -56,7 +56,7 @@ $td->runtest("externalize damaged image", "qpdf --externalize-inline-images" . " --compress-streams=n --static-id" . " damaged-inline-image.pdf a.pdf"}, - {$td->STRING => "", $td->EXIT_STATUS => 0}, + {$td->FILE => "damaged-inline-image.out", $td->EXIT_STATUS => 3}, $td->NORMALIZE_NEWLINES); $td->runtest("check output", {$td->FILE => "a.pdf"}, diff --git a/qpdf/qtest/qpdf/bad-encryption-length.out b/qpdf/qtest/qpdf/bad-encryption-length.out index a29eb13e..5648fda6 100644 --- a/qpdf/qtest/qpdf/bad-encryption-length.out +++ b/qpdf/qtest/qpdf/bad-encryption-length.out @@ -14,5 +14,5 @@ modify annotations: allowed modify other: allowed modify anything: allowed File is not linearized -No syntax or stream encoding errors found; the file may still contain -errors that qpdf cannot detect +WARNING: bad-encryption-length.pdf, object 7 0 at offset 531 -> dictionary key /Length: operation for integer attempted on object of type null: returning 0 +qpdf: operation succeeded with warnings diff --git a/qpdf/qtest/qpdf/damaged-inline-image.out b/qpdf/qtest/qpdf/damaged-inline-image.out new file mode 100644 index 00000000..f870017d --- /dev/null +++ b/qpdf/qtest/qpdf/damaged-inline-image.out @@ -0,0 +1,3 @@ +WARNING: damaged-inline-image.pdf, stream object 8 0: error while getting stream data: stream inflate: inflate: data: invalid distance too far back +WARNING: damaged-inline-image.pdf, stream object 8 0: qpdf will attempt to write the damaged stream unchanged +qpdf: operation succeeded with warnings; resulting file may have some problems diff --git a/qpdf/qtest/qpdf/fuzz-16214.out b/qpdf/qtest/qpdf/fuzz-16214.out index a03574be..040592ff 100644 --- a/qpdf/qtest/qpdf/fuzz-16214.out +++ b/qpdf/qtest/qpdf/fuzz-16214.out @@ -6,6 +6,11 @@ WARNING: fuzz-16214.pdf (xref stream, offset 116): Cross-reference stream data h WARNING: fuzz-16214.pdf: reported number of objects (6) is not one plus the highest object number (35) WARNING: fuzz-16214.pdf (object 14 0, offset 652): expected dictionary key but found non-name object; inserting key /QPDFFake1 WARNING: fuzz-16214.pdf (object 14 0, offset 734): expected endobj +WARNING: fuzz-16214.pdf (object 15 0, offset 869): unknown token while reading object; treating as string +WARNING: fuzz-16214.pdf (object 15 0, offset 745): expected dictionary key but found non-name object; inserting key /QPDFFake1 +WARNING: fuzz-16214.pdf (object 15 0, offset 894): expected endobj +WARNING: fuzz-16214.pdf, object 15 0 at offset 745: kid 0 (from 0) MediaBox is undefined; setting to letter / ANSI A +WARNING: fuzz-16214.pdf, object 15 0 at offset 745: /Type key should be /Page but is not; overriding WARNING: fuzz-16214.pdf: file is damaged WARNING: fuzz-16214.pdf (object 1 0, offset 7189): expected n n obj WARNING: fuzz-16214.pdf: Attempting to reconstruct cross-reference table diff --git a/qpdf/qtest/qpdf/invalid-id-xref.out b/qpdf/qtest/qpdf/invalid-id-xref.out index c8e7eefc..cbfa67e7 100644 --- a/qpdf/qtest/qpdf/invalid-id-xref.out +++ b/qpdf/qtest/qpdf/invalid-id-xref.out @@ -15,4 +15,6 @@ modify annotations: allowed modify other: not allowed modify anything: not allowed File is not linearized +WARNING: invalid-id-xref.pdf, trailer at offset 910 -> dictionary key /ID: operation for array attempted on object of type null: returning null +WARNING: invalid-id-xref.pdf, trailer at offset 910 -> dictionary key /ID -> null returned from invalid array access: operation for string attempted on object of type null: returning empty string qpdf: operation succeeded with warnings diff --git a/qpdf/qtest/qpdf/job-json-input-file-password.pdf b/qpdf/qtest/qpdf/job-json-input-file-password.pdf index dc56bf36ec58960c94e4aee56a87d71d6d0fa5d5..a54e6e4e1d8652470732f406e5caa034fa6d5102 100644 GIT binary patch literal 6530 zcmd5>%Wm5^6y579xCxLfT8S?`27!U*1q`M|0>?lX#Viz=@u*0oKvsZEKc_#^&+2Y4 z_mXui>xzr21tcwGgTB1yki1X&=;q?;4S%bGqi^58{ugi-vHI?FaC*wZn|x!oOv1>L zg{yy`3=7ZmHh-u$Y_SMTwMIeFnQ-2iye;eMB5w^lzW75#Tttb0S0s3H0velo{al!a z9lv`rFAShRHf3v?la4~f+c7w=pR1OMh=qTZ>n;1llqI9>JGSq{zEk_o?3+jK1DCR7 z90|gQTLyOuxYNL$3hs1pr-VB#0E+X3(;}P};k5j{+YYxw`^`Y@d+t?hs&>nS!wf%| zb(x>lFR%>M9Rsr@6AYByH^>b6e*5e^u)$oh`!kKWi7YnuPn3^`C{&Pt|bh8!p}XSmZcLk@(QbiOn# zGaD8tHRs8U>6H_~g@2}K;B!x*snhojnK<5x`ZJMFfT=<^&KnF8{ zoI@tC>6q@?98!TT5h%4eRX`J6#lvbtvpv;|z%lf4H#4 zUVo29AozV*4*Bv31iv%OA!imKCnCHEIg}He zu1!d^#h#qXsJ>WJxiq43Sxn?4$42lFLkg(a`eRB^IgNE-Z*Dv=1{dZ;F2yddH#ej9 zqTs^4FQ<4!&Qgg8%DF>*O49RH3aqg&H?XHlQyWroM(jl;8Cjc3Q_3%+=c}WX*s10z z!O$Wl7+NMBjJC-?rR2nhJSG^>$+ty7r)<@Ukvyw2wbpFrv_{=PtzjF zf!O*kE^?XQ8KdEe;-V-PrxMIwXCeldPO~JFLZ&Jfv63dst2B8kdF{xtt+Na#@Z`kEp%w7bitmw~|d^3a!2N+Ud4;?RJEOVZt!(w-Lrc z52uLo#3HNnR$@|Gx*(U-S~h=+k>1zJbyC>9lP9jB*o4rK(MAbElj40^^BAec@1BtbL- zVN9S20VPO|7Ab=$5R9I{8Ii#Z3=nLBlh`!!^D!kEEeMVxnsHJ3L?jF$WvZ0?q~#|g zKUw+7$xjSbz9d7n2qw`7Uy6~Kq5xAgV2TP%(Sa#SFhvUhmFD4!7F^MSD_W*EE|#)> zP245zP27zZ(P&9Ta0OEnDC(nlZ&NZbL()wHW(^5V8EGl>Jlj8OJc%QBP00!&TW-z`i{9g}^)hL__8p~RdPruI(s ze@pGpl+mIgO%Ca>Lt8_%mD3DNO$pyE?9lgS0-`l!0y!PStJWG)fm|ZM)LKI>kjoaB zT5CuKaw!E-BU?i@kjp!mT5HG#a>)r(YYo{zE`woetsxu8r8!KkHDm+10cfP=9~El> z?U2Sl7PL^lqF~a4rfa-tjI_)`C_<{(6D^?0inF_%(_>v)m*BYcQ?W7bPF>S(>Xt-I z)H-e&Z4)t|bJW=)-bI^i-uusf6(?fZxFSvd>hwOd`+%11&*_cLn>yTk^NFI|PiQ7b z#fgb-T2mZvL^OUzz#_^RiD;%o8AlltqnZXLCFv}3TPQUZSYvM?>uBnFaCHf9wS6OS z&CZ#3UY^Ug&(Ciz_kSBz?mR;}(j~8NQyH1&yRF|1Daa`r)kse6+a<3iby*Dm* zJiepW?~4_MUtg-}24kzsaI3L*hR)BcuJL&}d|%ObmybI5cJVu$n)Nrwa*sti4WMRQ-p?5UZ9a(09hd5B6PPxBTMw55 zJui)^cr`JGz?H!Prua{opmvUX$zMpItU$&4e30bbg;a&YCu)E;jah>Bi)c z^wPp!BQ!U5%=@MwXwH8NmsXJ-8Sz-rCaxC7Rv&9vZ8v!UT@ie?!Z5=|C(gPYR`MY7 z`IqDC7jW)JL)JdtmvA_sAuw=J`zwp-z00q4cO5g+cW^~QE{v^?Uw?^Bs$wU0|9t(t z%rg~{SG|iT7Y8l5l6z=b^;p|30jU?-jyp4`Z-UpJ?K|}i?sd0{T}!;TZp;i`QnaW) z3~qH`Q-g2We>(7d-L){^xkhzdo@)xzau-nFxl#tqyH!@Z-q+4dGAS|LEQZ>z1~y^7-xLsTb=^ zJzQ?D_MX%^xT3#beAtaSzi$iRyoYv-9y_N?`5n)YStDU^t7DrQ{QMf%tX+2f`nmUy zN%!xtzHEPz*WUVDQ+wCiA@N^kITQyu4+#H^h;A2F@J-T^oUf)AL==bqItl`ptJ4qO zXk8r#&z?E(+>!IUNppVjp@UtwWu9@^zVf4jKDWr9`d%q0=v3uC>#oBPo9iDRt4gi$ zaqqjdVIGWab#PM~zIDv0(p{Is?*DL)jqzDmImByNWxsX9ewoEAO&EK$mvimf?9ybu z&7LRv54<;z`(++^wGZw)^mt8={jh z{X6*XZ*N>ezunN?_Gw07&721vkItALxaqrv!Fm|n>hPupKilrM%anxeUMHQB96PuD zYDm6m<-%hQX;Zp&u-R}L>uHR?-9^w&(b@VQyFGov38$)Z^R(Qya2_YEj&EvkH>d44 z3p{o`i=96$=wR=m-h~B6cGSOq);;Dy?%8c2q28&v&)?jys&Ttxf0^)({c!DJ;1IrpXlwetrAw`O$SQ5i2LBvR0C!%^0 zC&95iswWtRq(zjWbS#H46iqXjbaITik%&eMPMb9$hzBLGdIM+RfF>TNP*E?UtU=J@ z1Q^yEL`;WH?a;R$gr+Eh zLJY{;G3fwa`XI)pF&em`*%)9AjS)0>SDMLDQh(lT3|I?|vC;{8GdYd{;pW{j3?m>6 z-~k8&BT2Ann$4v+SdO7!IdE0dd@hdCkQ|P~w&4T=%TYM2k7i*xmVo6ra1YVU4gw<~ zIf6i8Ig*0qC>C0Kf_~2!i$eY&I2`f^iGt3k89x$ZAY76_Aza`h2!o_Z7=vbD3CA~yw4QF!E&5*e(>&G8ddAFnE9w!=|&FR zE{!o7Okn%U_kUWG$%25n(p})BsCgpT!$80n3G)z90_Ry)V0eyY^g0?`@$ouQq`(KI z1wrui0B;LMaX1aOISV!v0pbTq<1|TtXoWKzAioLzcK-*+nx~fl