From 0a081e1f097e29e022cd04c12ffcfa7691107ba4 Mon Sep 17 00:00:00 2001 From: m-holger Date: Sat, 29 Jun 2024 12:38:07 +0100 Subject: [PATCH] In QPDFOutlineObjectHelper detect loops in direct children Also, add diagnostic messages in qpdf_fuzzer and additional fuzz test case. --- fuzz/CMakeLists.txt | 1 + fuzz/qpdf_extra/69969.fuzz | Bin 0 -> 11828 bytes fuzz/qpdf_fuzzer.cc | 3 +++ fuzz/qtest/fuzz.test | 2 +- libqpdf/QPDFOutlineObjectHelper.cc | 3 ++- 5 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 fuzz/qpdf_extra/69969.fuzz diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt index 8f3008d5..d492bfea 100644 --- a/fuzz/CMakeLists.txt +++ b/fuzz/CMakeLists.txt @@ -120,6 +120,7 @@ set(CORPUS_OTHER 68915.fuzz 69857.fuzz 69913.fuzz + 69969.fuzz ) set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus) diff --git a/fuzz/qpdf_extra/69969.fuzz b/fuzz/qpdf_extra/69969.fuzz new file mode 100644 index 0000000000000000000000000000000000000000..3fdb635155d761b3bbdbe5091c722fad8ca2c4ef GIT binary patch literal 11828 zcmdTK%W@mX(dYS!xv+|=vb6KqXG*0iiL$IDmcx*+Vkf1;5*UDRLA%UiDakqHWAY>U zlzc*tzS-`c$IfDA37RaGWuQo4(3qWmPIpiD9GyOY@sK}~ z?Zx-x@nb@1@|Wv=vu@Ou3ILxWKf52cRJwVyAFg1|N!{0*c7?xx zUB88O^s?~nx!U$y%2{FOKY2pnPc;j~O%R(W;-tN9dYa=RFV@|*r>R5oRSn-V_syUj zXd11DRE6tFh710Az1Y%!z=+b^u0yFKiqdj`Rl|rgKSXJvSSaOALNIhffT1H5hK^1c zdQ{xw;vO0I*o4O>JT~F636D*9Y{Fv`9-Hte#zT)ydTi2TlOCJ&*rdlM9kw?pQ=&<3zpphAikdDVhn}l>yO}=s{_TP1%i7nNGvwZLHezR_v4Nc&4H;}KGoKQ^ zX+}cYPCNC^Te_w6yx!CcpdSe3j?z5G#i-m*Ed32I=98Mo06NHZxxr!vLNuu~65Ga1o7 ze~Oy}+%!4SUUq_;%x%j9GPHu|$UDW&0s4TF=;UFFn*($L718<66gR((7x>@D3^tq* zox@GBGj;=*p>j4DpH4_P8{(sl^Mg8docH;Q3G|PbYPn=AlZ+J{{ximM{De4N3@aaw z1LY;rY3hXNia`(u#7;$Ysy)TdZ)4aWH;ZCK9~Y+B85{N|ND4o*uRA4$oaiIZ1Uuyc z1~?&zxFO3eeK|ypWW{REPi7U91qb`XqCrz<)h_0X_x+FHm&H=gt zsE_Kh-V{3r~&x$q%vWwo`X>1w*V)t$SD7GQ~wmyrGt%tKT-6cUEr7i@w?z z=JvK~_eymQ<&SiIk#i_80*d|BI=y5_HJ03Vi1u|`T=AtYq!qq0=cpfC!$&=ez|kZx z854}LWx?behBdswSi>YpO(@1BOu#u}0b}@%WBg6R^Rl+T!BHp8VZ92DI4O+nx)Ros z0FwfXgtitqQGbPU;86KnwjI4Pg-%`3^g{efHLL!TN+UHWFK&BCTi%jqGh7_1l91ES zmN14BRsm)A*#gGLrsB#T(AoFoiy3w(>|?H1q1Qt!X*TpPbbZrfepYXlE`la6)#jb* z*Yg@te$mX^#kyJ1p=hqj#PO7f>O#OfmQ)0(8$2pd+og!Ln zXe7|#(Nm!UPTmZpP0C6TT`=_&TUn*%)Ot5r@tb9(*9&AdNsuHdMu3?A-XuXONzsSL1R2M1H-h9If?TS98$lUK(F?}}dGk)r`|f()8>fWk{r_M4x^W+* zdnk8l@NJamMAsQ3$}{6t?IF54w~z$E zxSCXV<<-5%nJ z*v>Ei31aK;lO8`c%xlH4d+B92yxoEKVXvL^p3-KJFQO**gx9N^`v7fiG|gb_9+=k8m48f^E!s zSaNiS<;FdIWG{q_wl^;JW}FKf)uDGm!40=vtQlG(9Dn!}`9r6cgh3ps2pm@Ii{@Dd z=iwzCU})UU^!NF16Y|x>w&RBG~S)Z1xhG@rC5UuU^x~e0$7QM zm0g%%F>7{L&1Y1Hrrk>rer#!b99HEaPd!2N*@fN0#LgA6bz{d}LJ-@sV?^>hI#sWf|!$ z&oD;~=9SoH+=Uek?=A!|fjNqXp*2(1z`0wN5q(90-Do{;u<@eACTIx5N>Ko-V!4zo zUa#cwdVnILr4)I@M=4`|%QUu)GR3pfE`4Q&r;rd5B=ER+?v#K<-v$;Ebi@T`pN0FvA^+((>YhY_4Y^n4oaFU~Sd zsscPY7BvD`fyIIlh8>3hRz~&)K?k$Z-Fa|iV#zlrXE8kTp`7zFeqLY~Bv?~M@qu$$ zM0(+A89$pvv5)gSvSEPXWrYB55&1kIIr7t-S9r%Yc(#J`MF0a=7U@I)C(%5Cw{CaW z69SKx0W6L6De_n@qKxGy8TR~k*OMaFyG$cr%VnGsa9NJydf(OSjq1!PDLHFfxMl(e zD1A;jU;hhIU`SXXXZj7xh$t7e%8OLiOEm{ix_ol`44qDG`?~9O HLd4}S44vrw literal 0 HcmV?d00001 diff --git a/fuzz/qpdf_fuzzer.cc b/fuzz/qpdf_fuzzer.cc index 6f941276..678bec8e 100644 --- a/fuzz/qpdf_fuzzer.cc +++ b/fuzz/qpdf_fuzzer.cc @@ -173,8 +173,11 @@ FuzzHelper::doChecks() { // Get as much coverage as possible in parts of the library that // might benefit from fuzzing. + std::cout << "starting testWrite\n"; testWrite(); + std::cout << "\nstarting testPages\n\n"; testPages(); + std::cout << "\nstarting testOutlines\n\n"; testOutlines(); } diff --git a/fuzz/qtest/fuzz.test b/fuzz/qtest/fuzz.test index 6bcbbde4..fffecc19 100644 --- a/fuzz/qtest/fuzz.test +++ b/fuzz/qtest/fuzz.test @@ -21,7 +21,7 @@ my @fuzzers = ( ['pngpredictor' => 1], ['runlength' => 6], ['tiffpredictor' => 2], - ['qpdf' => 62], # increment when adding new files + ['qpdf' => 63], # increment when adding new files ); my $n_tests = 0; diff --git a/libqpdf/QPDFOutlineObjectHelper.cc b/libqpdf/QPDFOutlineObjectHelper.cc index 3b5db47a..2939c47c 100644 --- a/libqpdf/QPDFOutlineObjectHelper.cc +++ b/libqpdf/QPDFOutlineObjectHelper.cc @@ -23,8 +23,9 @@ QPDFOutlineObjectHelper::QPDFOutlineObjectHelper( return; } + QPDFObjGen::set children; QPDFObjectHandle cur = oh.getKey("/First"); - while (!cur.isNull()) { + while (!cur.isNull() && children.add(cur)) { QPDFOutlineObjectHelper new_ooh(cur, dh, 1 + depth); new_ooh.m->parent = std::make_shared(*this); m->kids.push_back(new_ooh);