From e6a0f8758b5fc62f569635df971e06b8ff9ac365 Mon Sep 17 00:00:00 2001 From: Mirco Miranda Date: Sat, 4 Jan 2025 06:46:41 +0000 Subject: [PATCH] JXL: Fix missing checks for BOXES when parsing animation Fix error when parsing something like: ``` JXL_DEC_BOX JXL_DEC_BOX JXL_DEC_BOX JXL_DEC_BASIC_INFO JXL_DEC_COLOR_ENCODING JXL_DEC_BOX JXL_DEC_BOX JXL_DEC_FRAME JXL_DEC_BOX JXL_DEC_FRAME ``` CCBUG: 496350 --- autotests/read/jxl/bug_496350.jxl | Bin 0 -> 3605 bytes autotests/read/jxl/bug_496350.png | Bin 0 -> 5860 bytes src/imageformats/jxl.cpp | 38 ++++++++++++++++++++++-------- src/imageformats/jxl_p.h | 1 + 4 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 autotests/read/jxl/bug_496350.jxl create mode 100644 autotests/read/jxl/bug_496350.png diff --git a/autotests/read/jxl/bug_496350.jxl b/autotests/read/jxl/bug_496350.jxl new file mode 100644 index 0000000000000000000000000000000000000000..97cb3b936f02c1c427caa192209c9716ec186ba2 GIT binary patch literal 3605 zcmb`KNdZX(M+l=!T0oRg zIv<3A)PM=EKG*XnykE|J-{-?Q*Y*2$0{{Rz9dkVxJtzhQ003AVef&LL(QdFm9`K*C z{!!1r`4VI)Z^?BQbgC`{-ARTt0(B4|pUig3)l*-5_i=OW$de~-v$ zn3&GkvpBLjbGULLng2R~CI3z2OAMw@#> zT`B=805=VQCR}4jS^)`zEl%*lE+JER-n|dAN>#ArV=>_l+4~%Y1&j=5OlOOijN~9g z#xuYl4>)7|Gxsie$a%eVR`@*L;FN?o$$r0>jOF0}5>xd6s1`6+;`1 zWZ@`2t%`MhCHV1#rmP2IhZS zq0FLd@@BJOMx(XIvesX9X`G+ERLa$R5@q?5aW^!yJ)1Ubp@vUi`1cN%eOmgiKR?}GBbn5KO!}Dv_EMd;3eB2j-QKm(5E&xt( z`AleTJGG(px5r_RQ}3g>u3syyeXzv5T?g+Ftu4EJ= z7=lSPb#gitP7TzKcISCLd$L2bG^wu#a<-dzEC$SM$XB((c%BBZRu`STE*R*aw^vC7 zj4DlA9474N$gU^O9DMI1kUZ-PZ)SUi&Y3-0i-zh@H(eBH2W=ZUl?X%8IJp;=k`_l` zuW{LOhM>BwFg|J~{Hvplc7LCzhdvir}H-}G5hfEhg|-WH41 zzJRy*7!Jkodz)3G3q$0GDyWKdWvX6M?%q8!!T$^Z(-E;XJBRPqvGy@unHV+YqS2>U z52Kte!&f*=>jsT!0R0l7Xt&3ufN9?a_=mWCFdB`WlgzX;T~{QwH{EGM8{iScX<2Y( z;VfCtD(0IvTLWqwMM`GV^AMlks@B(?{HWS(mHQ=}Uwj3tU3=ctQHYzIHg|B<#^jv{JM*>#l8Ko-So z@W3NsjMxM%G6R>fZnFYOZs>34lx%yr6dKPawj16czE7dC? z5K1k@pe#|ZpwcwWD6+v+r7?5H2%I00m{S~9Egw4FZvT+`$s}kyiGK34u?FIodi9T3 zcbMqMfauFP(AYkRc~~OwqWiQ)CnIbg=JZUa6=NY`TPY0H7IR~T|7?&7;!hY;{aCuB zG(&-v77r$?xP4r_VkDqDe$n!wl~ij@Xo29|v~si^cK_uu1#V|n7NMVJ5zO*_ei$G1 zm&X<)6T-ns@rQ@fgv;xe@V`6+yxxEv1QAx?7fBrW1z|MT)M_OV|Ft!OLQGZu)!X02 z;=g=;rf~F*C=y*}ga__(KP?b6BfX|#)bi0Fez5W}F!Rq@aBSl_De2*xjlKDslL90o zo9(KSG~!V>j1lOzZF;*(N!~?@xMYpPB6AD+LMNWP2v- zwV&nS(@y*-BKjS*o!715gCw&HK3)U zcPu`gux}smkh*5Jw_Y`3jV!8JAy_6y$YR;hBCQMVnIEtL3E2of$}&=M{s^^tMY;W{ zP)M#k$T4;+O;X+h00{dR|?BH2kce zVia|D^q`M}2gRQ)obDwwNjrMlnb8qoKeHW4UB|myU#INHfM`)A@NxTfet-3N%R#A* zyYMVWelSX%aX4K9CGx0_VWqY6vvUkvp%gxi9%U6xL@BQ{tc4j3*7EETE^N=PdX=h% znO^h8G5{ONl+(vrG#1#x&AV+5M0wazCtD~IutfjB3WZOa zFSrXxG~qNQHkUp+Z=CKo)9Ve_^Lu^ewsqIm)Hmq%MX4}O>IFqIZy_2AW-Uh{pxan5 zLO4)Ozwk{1%cjt-=xR=Czvc6y0E)#lALil!-9~PZ$MQ$N>ganx5y1ZaWfat}Dg{#8 zRNcq>ym_1JM)_uN_{GmiGJS#Mo!pi+;5B2@tyAY{zkTU){9vpkTa%Y5;S03WA1IU8 zd^9jJ!Djo&<`>s$jHCh(5RbI}Jhwe}>6;@O=I?|2QDIAA0pS z6sZ3=ZTjRCQn@#wfpY~6RbSgYr7(+4<)m~nsX1k@9AjZ6nBQWu_T?AJJEbdDk4-8A z`;?T+RLzli_Js`!gj#Pr0u7J4%ry#b2dEa6-EgKZv6>!PHMLYB7FJl~TefNSoBY1_ zKwu8p-LiC`H+E0NEcwaWeArJ}AuotSaYo&fX_u5#(%Mu?%f5$1>=@iNf^?p^sUDx1 z-&{QZu=g=_eZ8oinS2h;SM|=1phY%U0-uJ6mj`a#6&$E+{METrUKoe%(=6+G9ikI@ zmF_mBeP}?$cVQpoC+pa#P{@H!@#h4lUlZ|yX4Fl&3#9bl`nmQ5D^c@*q#bZsv!d8j z+2r6@U^bfWxzv;Q_H~)0R3>kpS!!V4ATqMfH|e|!rtG$$Z+j~&M#Q`z5^&DJyOTYj zMde&Ddx^AVt;8pzi82$`GOYq?p!=7&h{kzMLSWn`Jxf7>)M&|!CySq!e3^%5INrR+ zZ@JCsPG83|*GJ|qjXy*R$Bdg(iR!;ZOdGPey&nPNxJWn@nGZFfU_3@qw<75vNwtidqC6+=i-v=6a4G zr__}N0NCWoD@kXGk&)h-eQz9IkXcv^95=eylk$pBA*EtG+QIt{#OA2T!R^YZ!!J{Y zYJ=L8r!g+Daiel~Z%5>t>GocFR(xfUard?0#<$|;YC!^L5#q^d?*r8$@iIt0UUvoM zyffcoF_(6!Bhe|or>^wcGs>?KBuQUxf&KzBdgKxG)`3#okn|OZw_iA^8gYj8Ua}-G zLf4JL?jQ!inB5rd1>}muawmebypr}P!v}5^XB?AnEX*N!|H-^LtA-@6bmq6sP)fVw z1dz3vK;jGs{KBN6v6c8m0kh1^vnbJYrSh_?&whA|a!HK&^ABB?_K9-bJB87Oz`~F8 z1DHel^qBA~M)Nb7g>0(lXPiuvNxVv87p-avDFHyHJXVF7mfO1Z|18`rhqx;_$_yzF z9YwO%@Ti+nwwX4kYTvmQo+H$l!)c}>(CE=*x4D@oK*#T}O}b9@Da6VhVr~UrwO2~g zBxheao@0;#B4eHz+r&klvuUUUQKHY2;SYn_n}_X=0BAq#_Zf7pph}^|ss`tk9ZSx6 zj-KfyWa@Q7n)t*hjzdqK1;NsAuQ>ZVp9*8FD?QYhyROzyEHbGi@EwW6m6FPkXbHc{ zc}wAlzWVt2ady}Idoiqbu1``d&SI*tNs2YCYs-ec+i=l(pnWvMOH7efPk)ksZ!22j zjYZ9#n4)YY`Jd*K`nULm0RZGQOdV~}j`xIsLev|5rT;oW583~*_|Ug-*-7|{!^i;? gndAWWRz}J%sFjY?7v8R`Ebhl)sd|qqxkJhR2YzAVSO5S3 literal 0 HcmV?d00001 diff --git a/autotests/read/jxl/bug_496350.png b/autotests/read/jxl/bug_496350.png new file mode 100644 index 0000000000000000000000000000000000000000..bab81da165e87667581aa2dce930df313cffed56 GIT binary patch literal 5860 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.data()), m_xmp.size()); - } - } + if (!decodeBox(status)) { + qWarning("ERROR: JXL BOX decoding failed"); } } while (status == JXL_DEC_BOX); @@ -1240,6 +1237,27 @@ bool QJpegXLHandler::decodeBoxes(JxlDecoderStatus &status) return true; } +bool QJpegXLHandler::decodeBox(const JxlDecoderStatus &status) +{ + if (status != JXL_DEC_BOX) { + return true; + } + + JxlBoxType type; + JxlDecoderGetBoxType(m_decoder, type, JXL_FALSE); + if (memcmp(type, "xml ", 4) == 0) { + uint64_t size; + if (JxlDecoderGetBoxSizeRaw(m_decoder, &size) == JXL_DEC_SUCCESS && size < uint64_t(kMaxQVectorSize)) { + m_xmp = QByteArray(size, '\0'); + JxlDecoderSetBoxBuffer(m_decoder, reinterpret_cast(m_xmp.data()), m_xmp.size()); + return true; + } + return false; + } + + return true; +} + QImageIOPlugin::Capabilities QJpegXLPlugin::capabilities(QIODevice *device, const QByteArray &format) const { if (format == "jxl") { diff --git a/src/imageformats/jxl_p.h b/src/imageformats/jxl_p.h index 7648e0c..04aee93 100644 --- a/src/imageformats/jxl_p.h +++ b/src/imageformats/jxl_p.h @@ -52,6 +52,7 @@ private: bool decode_one_frame(); bool rewind(); bool decodeBoxes(JxlDecoderStatus &status); + bool decodeBox(const JxlDecoderStatus &status); enum ParseJpegXLState { ParseJpegXLError = -1,