From 918193ebf908d35c88bb71d02dfc14bc41ffc31d Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 22 Feb 2023 23:11:29 +0000 Subject: [PATCH] [subset] fix a class of fuzzer timeouts caused by large shared coverage tables. More acurately estimates the op count for CoverageFormat2 tables as the population size instead of the size in bytes. --- src/OT/Layout/GPOS/SinglePosFormat1.hh | 8 +++++++- src/OT/Layout/GSUB/SingleSubstFormat1.hh | 8 +++++++- src/hb-sanitize.hh | 8 ++++++++ ...-minimized-hb-subset-fuzzer-5192684970311680 | Bin 0 -> 67697 bytes 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5192684970311680 diff --git a/src/OT/Layout/GPOS/SinglePosFormat1.hh b/src/OT/Layout/GPOS/SinglePosFormat1.hh index f7a170f34..f379e011a 100644 --- a/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -28,7 +28,13 @@ struct SinglePosFormat1 TRACE_SANITIZE (this); return_trace (c->check_struct (this) && coverage.sanitize (c, this) && - valueFormat.sanitize_value (c, this, values)); + valueFormat.sanitize_value (c, this, values) && + // The coverage table may use a range to represent a set + // of glyphs, which means a small number of bytes can + // generate a large glyph set. Manually modify the + // sanitizer max ops to take this into account. + c->check_ops ((this + coverage).get_population () >> 1)); + } bool intersects (const hb_set_t *glyphs) const diff --git a/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/OT/Layout/GSUB/SingleSubstFormat1.hh index 78725352c..c48ff4427 100644 --- a/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -25,7 +25,13 @@ struct SingleSubstFormat1_3 bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); + return_trace (coverage.sanitize (c, this) && + deltaGlyphID.sanitize (c) && + // The coverage table may use a range to represent a set + // of glyphs, which means a small number of bytes can + // generate a large glyph set. Manually modify the + // sanitizer max ops to take this into account. + c->check_ops ((this + coverage).get_population () >> 1)); } hb_codepoint_t get_mask () const diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index eb907c6b2..6f3db301f 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh @@ -228,6 +228,14 @@ struct hb_sanitize_context_t : unsigned get_edit_count () { return edit_count; } + + bool check_ops(int count) + { + // Manually decrements the ops counter. Used when the automatic op + // counting needs adjustment. + return (this->max_ops -= count) > 0; + } + bool check_range (const void *base, unsigned int len) const { diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5192684970311680 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5192684970311680 new file mode 100644 index 0000000000000000000000000000000000000000..0896b6b26eb4e88c2a0d4d65b04ce58ab54a9d27 GIT binary patch literal 67697 zcmeHw3w%|@wfCC6&nr&?gov1u!&BZS0m4IsBp_%_#TG;>D1;>(GHE&5pFzGA6NKM2wNuO&eDg{jlv#yzd$- z2hUqD@51@v`pK{1({_BXShJ>~Hs=*}1>QG`1V$oO=e5hl63GhS`;Mlyb+zMnN2>8& zD!-P&&9xg^3-Z-Iq<>J!mTx>#X-x_g=XA;5ci-OUNETAgk}8QHdygS}RQ`ZxE^fy` z)QA>|NKj<2vO}>nIGs821BtLj~0cRbDn_+LY;&E2hj)vsJq_ z&H8ui*S2j3>|A?*J;)wmkG97k!v`2XBEnqjsLqo9cptrBUVp@G460BFjJu}qYow>k zW#84`Sa5mu^Fh?jTfu_L6_UGf(eCo40M3J*stMkg48-HM+Y9d6w(Y)ckzcM}d)2mW z+iraTkJ}4^Yj*te_6IvReR;#3x7>`^_GJxM%&oust9Rad^C#Qae)WH^UwzXZ_uahp zzR%sT^-G)Y{>rv3x7>cm7YmR_dGlM#r084sZ>d12KYVjvXFaZyi&k*MtqlUpUX0KQRl$2lzOIRF{nvSp}D z5Y<%M(Smwls`%`D9)IfEhBmr|;-(ba88?NjJ7r?)g ztIx*^dktV3HYUdV0{u?U^d57yWW07k1f6oXd=p+bBPSv=Rkoa^0`$t5Y-GgJ(95th z@gBS4zYwxQ@XI{IFTKygiv}aM7mRVc+5)&oWtH3m|1_*VeloGM=*X4r#_mr%AqfQ9 z$ zGx`%{^9d?HF{~GwGhBS)Y^=o8*+`rxlVgd+lb8zvQ({gCNSrO$u;%GCuNihc!15Z` zG&&oDz0u35m%CWw1O72RGRDLPWpj8JeWYzpbTb23mK=5t;c~L*+l!H1#9x}k#y2HO z)s*qzZh*kck@;u72ud-qN!^Oc5MWY0mNrZU30^FTIXF@anpwfLpu!Ynx-Mfg^Ma`{ zOMmHZNqplZ6yHg0?T4e3S0gqX+{=(x@xH!{Z%5mlUX+>Uj0a(FWcNB`n&wot#uwNY zY=`4)PCW(1cg}!r^!N^HqZ4|-kvQH4wSTXZqE#npAYc#=P!fA-NCz=vM?jC49<+{j zp_QWwzr>2iF9ur8w^YzdKOVGtzPvo_KwQ0!V@Dqtuh#^0c4GBxGTc)=GyA@J)Z{B9bunjp(J6>IKt}-=dz$jLK<_j|wKPLD)yXVKNW3OmlHaWBBOJ{%-Dkwp`LFW3RPSRHHtaS$+m9(rlwF05iqB@wpGrlS`K9CIfP%ay0*O) zMGvEwjKq5`lWJPE5jeX=%4P@%)Ou@G+1^gEYUBo~5IE%S+%Jp7+KTTJ*PPq2A^e#9 zSoSDVw2`JYb+tf*9A}WIt7Sll6sxKZT!nA4(<;#vp7pyNP|(&cIL&HZ+uq@9<9AYc z5*3w;szO}~vm>8GJ|Ce&0uc~^%Q|4*{NfP-iFVDu0U={D;LWo zsdT?^=oSr1EG+#J$l_htSB=Xk*AL;0z$Y>mA%-B%a=AlZRnt|c6}7&hp5hZOd6-SAx`W2^yIR4S|~)@-SiORY7C(FW9*SZ5$?Ia~;h5(Rw&^M9_y zM{Sf0!~Zb-eGY6Sqt4cEv%BB2)jX+}BK4elLB^;EVym=>UDO7*M`T1? zY(wH=WBK+X&m*N=b*e9@q0F&*TKn-vJH})&?tRiFf0zAoP;Nog+48FV21Va3Z-Wu? zM|7A!%X@GSX}}>J1UqhC)!NPsDcPv)#(g6q&PB#&$UMbL5j7Kxk~wg>5SK#rf{CE3 zSjjqE7COldcy{7aauY5KjdKU=cjB_-UR;*khs%=taVhy{To&@e-24ESB|pJsp|ReC z%Whmi*>IT#87KqcI!Jf%vruFU05AkD#kfd!kg^$u%SOYnX-aV^fMNx}a2Bo*h}#PQ zh%7@E8mR$an{b77?pgMYu$wY4_d(?PF8E=-mCm=Vb8PFphLF=v#P&Ka=2d6mSVlG$ z%HY^R-4rogop9n2QjC`)C6Qx74*&l0+yhX5+ zX-wDl0KiX4lTsH=-5cQHU>IjSXAiPYJyw7zoF8{E?Uf352&aV27%UhnITdXAQ5@r| zCx|&7Vn4B_!+NfZ!6c!_-;XntK8d<{s+O9E(F#_lKdAT<_M4^(kUh$qJJ~>8>d&s@4b8J zFh4_enz6Lu^bxvw`DA_uyZ#8aUf8o;H%>&J+c`deCOxKEhP0VdjeH+D6m>W3+E}f5 zD-gB_NNRNgn))gcRV?#lsce;_a#fznSN&9h>W{ek!~b-ItHu@9I9N#IU?EwKE1)s4 z5b&CMl)>O*oxo5+8v6=qEGq=8@Kv}FzY1|xPvcl2q}N|U>MRAEO3hJ2G&wgC*w#SA zM0|^=_7K>KX_2=;{w^`CkjAuZITx3~x7-qT|JfSn3dvGj0bpDWC8T2L) z7VHe#w-#o=71s6ZB5dtEE!h6R`;TFaM zYFD)}bg5)32OKGFa=a}4J$UHg;e#;R;a2@Tbnsx8_uc#7>{)vF-|RS>ks`Weu#{aB zUgt)!riwhcjdiqts1kY5H90IIehU|EB>$79@||nY#@YMNdF}F#mtWFOVil$fHTd?p z_w!)=EmnvGeG}Y!pILfz+2{^opuv$_uzoJrbvviEY^zNDNu@W3WmmTR4jc=Xvhc;2 zEf_9hLy9xDaKpqkE7!Jl%xVKWgLqxHTPtW%k+$~rtqpCBYuiM1+UF8&)sb+Nl>I8WKhl#XH*nX zpgDsf$t_0;6Kya&5b@YUcV0U2V-I}})a-tAw9p2n>00=nu)=k+4+2w4;s=JNb>*M*I`LGw^qENwp zJzC|y^Q<#F)K*uE=HXP1T->iS_w-@seaDG7zJ|efojq~B2i_1H{6>){9`H3$^~Hp|45cR41lY=HM=@(E1%Rq`=R z{WY*<%VJrB$uugfWv$d=LT!hAE!N1R(&2tth_Sx`eJl#ukG1&kfUQOv!4actJ408F zk%jnLg8?dvSlV=q9q=8+_YU}Nmi36c7Ivm}9lo^Ty&kqkJR6V?K0hsMn;MXsz(3<= zN+vIL_~&$A3*>}h8B-(tGqzQ5F@9U6EoXg8V_8*2X<60esXlv!&pyp(pJD7O@NVcw zq5|)Q{v9GK{~3H3&p(GA0?@q?0^dn339rQ0@+{z$sy*~9o=xFZ7!V$L0IbWv?nnjf zpN=1hj6gUyZEAcpTPeu`vL9| z_NU)Z`)|$+3C6jsX7PnJjq5r(I@YgWzhT3M>#n=*GoSg)4L97dX3ZMBZrr%>I*j}Z z!K|FdMtr(%*|LGlV2X-}Ec3%rn7_LN7`kN|lLbkt%@dl|*4BoHYMCsV3iOy9Zgi6b z!%;t_nFiNsOiBTdg_&;bU@(fzaP7p6X1ezCVL#usW6qFSuKfboFL3STyv}y*b6}t2 z+ACqNbnR8JSGo3T*sC4EXVlGHyv%h!%me3do@-~jUg+BAV;Fv%s~zya0PYL4`vkcN z_KRFU7sGzBYyT+huzr;OFFDRU7aoH_GF3=2p?oQdC+UhO^WCh+iie`Hc(_@N?&4uI zpmF57n{+>beN$a++u9aq4y;O%4vI5LC`aC9_+AOGOVcAANncu&^;6d|F7~*WOWn7n zF;|n@NX#L@R+;b~_nH=p<9z9tbCaDQWT1h}`;tTsG{?vR&kz2?K6{*%gN7-NcK)1x zCOK%=O8xXdj*1)rD*6{6IpA1HnDpEz(e)ux`3Qyahy!~l!%a+$VwN;9TEK5jYSeg# z5%I4lv&EG|lAo(=8racief?F-?)(6tk|FVprPb3IHx z?z(fR|AcE_1p6Y_J`eWAuKjY@FL&)rU|&KzM%~;TxC zukUN0SbvlpOTh2s{N>$s{&(1s$v7_wpHsf>Ww#btp%I!ojr^>_tk1a68OGpiIaj4i z)bD-;mvLZ`d=H|kPycj`;utXw-fq->>6`Zh5borfkr^ur_-3KG8wHy1Pf+8{zsy&HNkA0dVFp( zgHo~|HaE=&IOmuQBt0wPGSs*xO*t+HiZ$&wY3CezGEktsch5P%S$z)LT4`K-PtG~( zQ?a0urWG<_(9C1dQnC5uNNgrx5XWLp+~@h~l5U z-_|rUEJrfYbRH^WACek7xo>1S7)Nx^;TTK_7vj_laI>FXje8C5LAay12_?kWt8mxg zz5@43+|9T*;HGGRfI+NBCy>Tc%AQN~K*04gGYETZ3vL1=XOQ{0ufk2YEx5zoaWEA7 z`54>`U4i=}xLId&adSd!#C<*PJ8^#AG0jt7lvmUd$>}va7xgk&!SQ*$9crfrx;4i_U!7GFJ1YZda4^@O}LQSDNLQjNt zhoj-E!ViVt3LlIVMP^1;MDB__8+j%2e%9cu*;y@FU(5P_)(cthWEW;vXD`YARCZ_f zz1iQ-emT1PmHw`k6Jvs<(F9 z`F4xF)qc=^+I}-o0LI~_!1n_OgY!_zmf#)1$AYhhvP0FO>qF0kL*b#}>EUJJE#Yq` zlyq0*ovZ;_6GL%*6}IQA(d3%G8#Lfp77G7Dig#TObXjHC{Rt*@`Vv`xmH<9DCyGsgcQ# zi7$KNdGu|Tw38Rl6{KtYsiay8H^S?bn)hF(lyr@ym`Y&UtY;<*O`GuKRmaNciE;SL z>d90Xq4iXP(_T!8IY}otef+{D22SFoJqN4^M{;$YUYkA6QfFg<5j&3#K&+qq z`_uwPrf*~fki7jhsi2oImkb~nH2mgthnLtOnUNEsj8Wo%Dd_2^#sEV zAdtT6jTjLEb7&9h$v1u~B|aMKEyh<*Qe!3?oO(Ikn92S`$YoOO!t4Gqguoj*J$Ufo zAm)Q81qat;A0E2km7u3m#{8Q2dh+Y9Ka)R(j!orW9+OcGFYa`{IaQF$LUe@0_j!nS zIOvkQf$ZksLzDWp+NpM1gRLj64c2z+H5*GipiX9jzPUnHXhzM(#9b%x4Q?Q-rwqqq zI>tY_TJgAs*Hqpv$UfZ`W`N(TC9gioL5e{x{Tyv8ofd^gd03{Cz87x9i8H#n%w{@o z@aXexcA9pGAL4qwFH1MYsk1E$BSEq;Mec)LRy%emc};#!dLL$tD#bRFN~LPlVi3{w z7;`$*_4ZbE8_3KD)i)mAp}wo0!oH9HQZK1j)m!S1hu%AI(Be2qA`s@~vz02rW`4f^ zzBc?-)r7&C zoF;0B$YaT@yRh#_Z-$cUfzNmS%_%Gz@~PiG`{+0GEAK1_-g)yEZz~v+Jtlj*)JLFa4ZvV5y?@o)BLkzHTwU+> z-l7phe^DHvx$5l^AJLBQ@i`MWSeTB}$%ku1p6Rqkpf$jL%!;uf5971<=GOI>krbPO zyr6qs`&VH9ifg|Q!UXr*W%BvJScp%GeQrg?v}vQy9X)l*Y-@6P(V)Umc*N)t!$X4# zizb&>Ogk&z3Wq`~!jX|VDwvgZ_UQ2gatCJzgZYI8BZn6kPRz@S3_fq-&?$CVc*w}G zjnWhj7(aS&Zb5cGD}PYofU`c57aUx2PGMdN(>?s8eBSvE`E72x2?xh^LWhg=pz>`soJdHiz>D6pvc!y zmp8~~ezJTbKD;fJ0?jO&u{!Vo#4mQpqw=^s1Ch}eYV( zu7!%B;4Sxy&4R1n_YdWV2uYz>B|nn$euNjw#wz&_T(%xqC?%`p7r1Qj4PQoK$RSja zDJ~FO^9GeFQk0_R7QNwM0#i1F!;9g8aOyRZ*<_K@ows?iU%@qeqjuqt136`kl9$3y zIvH*+788dTb9(<|F`E=)IT_d;KP=|rM>2$B*ruoU!o!k?b#`xzK5Wf+v`_axzN|7bA*rG3X82#I(yK zFYlQ`9?imFY5}G*ZI$2f=lXUT-_P|+yVeQ5rGG`5gaAneKaWr|srDIlxLjfJ;*IeX z6WVcxF&Gn1=sGVlVi=l? z53;JWvB*KWK%*e~%wCu5Q#Pd;YfhM|$6g}5RPaG_0UA7ol8=){h-CzyKZJtMqxEpk z!8)zrbD&rFuWvc&^u~W5#%hcwkwod~Q&sZ$Ou>IWLBM2m!_&Th>>_PAR^$v6X^Wvc zJg>m(WoL*OUUAU*!f0+;o%*B*k#SD|!|W@M3%92`C+#a6seB@>dHwMl(|$Xi4{4Txj?cMQsv63BrK+JRqpG0?RSo)V zTWCIk;vmH?k~uku*vgr9a?mh$03ba9^pxxvE5+36zkJD*~dTcS=Q)-h@++h@Vc>Vt*{l^-@zt)qiCnO;|iG<0icWO`x zG;y(yc+`FZWvIthkW|izAPh~Mrj9&9&m&2aRSKMbgdugD(U`Iw%P#v5@YG#x4O)qh*qP*B!^CaQ)Oj*2rWpH&U7t;6 zI%2#yS-QQZr_%lp)ImnR{sWh2Dn1aN$7dmT!G%9RuiQ<~c~1@^A$(qY|L=vm ziNU)Z$>=+wH5a;xtA~T`y`p~*EU!KEoYTcv9M!sfpVNyoIF|Jk z_IM9}%4~i}ME7z5Jj9s#YV$+IX{r$OgI&2wM#nR1FN?97RE)K+7aAZRnOB<3KU?p}jU^={Wg zJRxdp#o(UqX6C1Fc0K$z^^GSs>#3uTEwk-GA9jYbO?$PBOk_SEXt*sa7R-P0@#h~V z_{g8c$uA@Vzw7@Rt#JKt9E*p*yNJ60^Di}+Khz=|I9vlE|Y3z0|0gzZw z*KSi)DSN)o9Bfe_ud24Kb|peHZ8_lR0PNfCb?e*mn`_&y)hF}?PE(cQP=r}y5l^7R`mQF-qAj(} z4PiCwN2sigs1)YI=5dB%*@fl$v;hQ-@W_!Y$o33I>{Apcn(^WEL zRbxx7jBIRa?2vKI4G%Srt-yC1m#$COKf{Q8Dcs^bY~SxpSOhSl(UIBDA^I_B3{tH& zN)P~6RtOsp{IyV)v*B-X7HuNO=lJ`0^OvZ^(mzCZ|ods;%(NI?6&g9<>;RX!}5n zZN-#^rAbaPJj<722M$L@2E*^;Sc5-7TUvaIFCccb1*mnDZZ`hsm`IbJb=r%WGt5WW zQ4TtHf1-qzHl9mZe`Xq2YWJYEv8{3S8YBsQXdThtrZnX^J<9D6>)0V4gJ*V#d@U5> zsux5Iop2xIzVeT?>UNn@w~o=q5%if(Xr2pJT2iSKj&&Jd;1g|~V#cD*Q9K$d)~RAh z31vX22n^d#4sf64XpUq!m4_o4fWGRDBP_e;bU9KT@TO8?|6CdK;`ibvU)LDIE;RT# zIMgf1nqyy#Z8p>u)sKCC=HsJIs)^n@{so_L~gK+%lSr$$>- zr`W^KzxC38+kIQ-^z;9uaNgnvWO8agddJe`|8)4rZXW%AJwV10o6AR*S^oAaLwm^~ z=d9J;nm$*aNb_UaL+z;BH$|XE6wTOpmp+PRKoL)ze5ShcD&5%m(h{|58z%lG2a+41 zU2vP#wwR3$V-6-Bwzh*^he(q#zr!KKZf_Y1iAi;BZ3j*v#<(Zyw*UurVC5Y`Y;h9q z?qL|0yb-~T%l)&uBj>2WL5UE^(_~tk>+0xf#p*ZOTj2|_TY04t$z6?uZ66=Kd<=ja zvrd+b#k5;*6_mC%Y^rN$=_syHXY0sqaqIlOqcv&!`w?3{(@{@IS3Yqal{2R??)chM zhfNDVKE1tOhl`u8KYJXe#utV?3Z}&8q^%ka0J8O+a4KZ0u^ZXyL|`CW=4dB$PK|6? z9fe!w`eSZGpTK$!PB~=Bv%!17#D>o7;$2AxNx?husTfv7 zoS!QQdUd?|@i+XFzipbUF3_JC9ZNY4J#8oU$TdTuL5NUV-;{5I2z-u2A$01$BVB5+imKE)^+9L0AHMeRQRvivxo7qDNWUvd zr#_Ay2VjE}8Ug07d(3on2JM2?RL{kLKl!DuugDB^1-jC0yccu^Ua0D%+Z#?Cp{Haw z29Eb7%XNTodn;dsKMVI$?pybI?`Kcx;K3xATqhK=N5guZoPUHbU-UqqtU z%dzojd8^c_=dcdEe08m^I6De6iM$J(sO~_)Wx)`X-wZ+{^xh=(@jF^OwnuoDV+8Fl z68-k1tM36)OhTAE;sA1lKzTY8zMt_NS9aO$%7J&2F{?^C}2F`T$! zGVx(KcjbK?HTz`d+!ag=r~kPt=VB@|=e?YSb5}qVM;zP99D5Ug?9HP*ZYQDoW9RK) zY?*deMJbUe;L%kr^{@mEe`Wa^2j>XQdr+LUZ5_?E?R9yVaTNM5+@Y4*rTazpN6@xk zgXhVuYj3~XxrumKU=}c+s0jQ*+8PT)Ksa#@%jHatqaj_MfS zH8{|7(U~CzZ{dJabyb zW|cL0TG`8!mX^++R55pR>&CXr8-9Q5Z^qP(k52tL%}e^JALq?8>2}BfC0la_f0l

!_S=FLkdZ|?lU=0E(_AaCWXP~hjOf}1_{Rv6 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 J4Bepf{{i=~rX>IX literal 0 HcmV?d00001