From d24a61c648fc79ce0b87137266562c8dc04e841c Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Thu, 18 Jul 2024 12:33:29 +0200 Subject: [PATCH] Allow /XYZ destinations without zoom parameter (issue 18408) According to the PDF specification these destinations should have a zoom parameter, which may however be `null`, but it shouldn't be omitted; please see https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/PDF32000_2008.pdf#G11.2095870 Hence we try to work-around bad PDF generators by making the zoom parameter optional when validating explicit destinations in both the worker and the viewer. --- src/core/catalog.js | 9 ++++--- test/pdfs/.gitignore | 1 + test/pdfs/issue18408_reduced.pdf | Bin 0 -> 9787 bytes test/unit/api_spec.js | 43 +++++++++++++++++++++++++++++++ web/pdf_link_service.js | 9 ++++--- 5 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 test/pdfs/issue18408_reduced.pdf diff --git a/src/core/catalog.js b/src/core/catalog.js index 68db4b847..2c4551d3a 100644 --- a/src/core/catalog.js +++ b/src/core/catalog.js @@ -64,26 +64,27 @@ function isValidExplicitDest(dest) { if (!(zoom instanceof Name)) { return false; } + const argsLen = args.length; let allowNull = true; switch (zoom.name) { case "XYZ": - if (args.length !== 3) { + if (argsLen < 2 || argsLen > 3) { return false; } break; case "Fit": case "FitB": - return args.length === 0; + return argsLen === 0; case "FitH": case "FitBH": case "FitV": case "FitBV": - if (args.length > 1) { + if (argsLen > 1) { return false; } break; case "FitR": - if (args.length !== 4) { + if (argsLen !== 4) { return false; } allowNull = false; diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 808cf43a4..dde1c0166 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -13,6 +13,7 @@ !issue1155r.pdf !issue2017r.pdf !bug1727053.pdf +!issue18408_reduced.pdf !bug1907000_reduced.pdf !issue11913.pdf !issue2391-1.pdf diff --git a/test/pdfs/issue18408_reduced.pdf b/test/pdfs/issue18408_reduced.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a97f2d79d57aac68906a82ed2db93d4153702bea GIT binary patch literal 9787 zcmeHNXIN89w?=xAs!~)SARyARQwW5P6ai^s5EKzY5_%F0i4*~iQ~?zM3kuRvz(%#u zL}{TTAX21AIbuZtK@`0^w!=AizVDvz-uv7?C(jd@otar{);lwMulL;}Z){BdVm)&__r%e zkRJg8H3HlFl06`Ldb|V@o@t3${lnt7Ha2eFyQxG7)RI8*pn8G^5D=)TmoJq-0ss4A zsRUyJj*JJ5SwmpV8j3#^90F+3pGqNMiM)ZSh&{k)anY{M05uCM6-H}^zqyLJeWza$ z91g%?fCdtY1OP-?4+^l;0Brjr3R<9coqm=K8w-0sOSNVj3zc2mip>r&T>zrXs#)cD z7Y2ZLAs!;&H*X?2yx+Fj)VdW!9_P7_$#|dqZ~|i&Usf{C%Cgf9whN5u`yjqY$Asob zbh~M8)UO~oT3JG%-(vlV;g4t$Z~#~li;jMv9~S3BphDaT9$q9}**6t6vJfx4uB?N) z6=3COMDX-73#Jfu2U}xs!9F-NURGa^S0_*_kmyGQ=LZr<^dP03&n0B#lWExdhR+j1L=jVH1M8BVoNd9VH zgH*$jiO@i-9~7nrK!4Q#YWX`rUu_tH+X37yzp#PQQb(_}v7+UlZ2VZDzp}DwB;RicU)%o4&Q}j)3WiMf z)%&*M3~>~)8J7j+v1j#PuI!2wOQ`nTX#c3WW)kJEA|Q;1lq9@fv# z*9(Vbt`#T>{x+4Y(VMpo)Z{)m4%1IJl}N3Win1 zA~ZD72*3@{z@oo~2ijfHcZFRr5-kuHJPk*n{CDB{L!a-qbfC=rvtmDe+pJ%I1$QfW zr-1&vReY`bxxN0c3cm;Wf8_zR`;U{q1@1p^{R7wELf~&T{%3Xl1J~a|;BPhlXLbFr z!NvPK*#Oy#u518EB~}p{^%aEX*K`eq{!6;1{)4W;HCJ$)z*OQXE52g}>rEDxV=J!q zwqB%Sgk)j|jLq*n3l~+35~|~o%>EpjbaroP#Z3F1H@Z9mg4ZJiWx3WgZ4ruwz_^WW z=3nPyTZ8IoZgxz@v6WjA-w&n^L3w?hFX|{`A{D(W86`O>H+rt&#!E5f*43@86TA;J zb(K4x;W)pH-p2GTELAIN9gN!IIV4iCyyjt;`zcL2u~t;8%O#_m%{g#rd5yF|h!NK+ zFkma`@GsFoePyWsn!Bq10Sg4u?mKyHhqfv20_-{$+AX*3iP-}ncLBECb^wxdcM3RK-SOH2TVbSUkgTn3jl#>eD$iQ z2Z4f_Ep9hRX`R3#NEx9RLLe3N$E>m=Q$e}{w*1bInHmBU9xyZ}jfSn{)4vC#`Tr3R z{G06YKMZK)e)=wWppn1cKr0mv{ze$@QD7}cr|#t@o|iWU3LpZaP)NT?>2_n`*uXID z%CQsMT?ugi%0~`0;+I~S2RCX=H<&ZnRa~8lH&0Y#9ekJMDtiFCm}gY2K#HP|5F^ zx9t>Evr@`eF|+R!T$9LYprnt4uDb%**EVg=g0iddm-n`xco=|+(Xa)OcHHLUaE)$+ zJx~HTaGQ@6!vFvUN>MOYH$Dgo0RSxT_)omtUVMAM(QTGJa-xB&hlpM=#9z(?90p1= zeqB0zv3|Mz#>@`e$VYFYBN8&!8`@{c67yphZzd2OxAmV$G*S9e z{oDRi8pDisg$&+&MXk5(@zQ;L3kQ9ju9X&>MrK{LZ_o5o>K96$SHxA$j?ynw-PJs> zU&UeT^VhTE_1+~zA=Q`NZ-{MeX=$tXpe=O0U0P-(pVUiBPgiTVWlPfwQM8hF4jc7n zn6!n3e4g+u+JzdQ_0ehXNLM|(Ra!%dGuz!pwCs7PSlI<#-L&-m1u@budZ*rw&+9+G zc9$G?J>9DHz*2~VvQApMs*MaIZqobCfqWO}qlGBJmhQ;ik)cjzY0oPub{tWzP|rcX?4hM!u-aEx+ASN=cJ{sSzC)e3p!M~ zH+4A^9=81cL&&Z|e=V_=*|v?LpV6(|6+LtB0>kdOmKkN)x}-z97G`@#d)tdS|vpPb&l!WwHEp+&Pw7f`Hrr1bfI{-h1wONU4n6E*IwGvsL?!zR=9ku zMJYS%9e_!^$?pQB7eIxs-PR;?TMVzISr$fYgiMIvY&4 z<~|b%CNIIRcF&!$3l)o_aJ&m_VsRFxFC9!?H_!W`o3?FJLqiE|Ghb)InpqW|kcTrx1ovC@yW3>44~UsIRoEW9s+0?-2mE?*Gb)cCLwxmtXIOS&H|Q_ zOnIe`tL-<*xc5w?E9X&mSI)j@gXMUJN0ojoK6tArr1l|O7Kg4)a!kl5;)H7RVNXf-@-&II?em8Mt5pOD@kq>EbbMWPeql`U{8pNySbN=ql*Np=KEe)0 z+it%K5)A-ZpWkNO&*XDl`;+agr)ef3Wy_`Uc zo0?gzh<%R=GdU#{^c5dlmY({Y4>U&>?Ux-kMO(@2wFoAY5 z{++t2wTWf+m~j8gJ+6;6BRa#POT(X)C9lbZxKBALHwm4OnGtXsx*lmX)%#MpiQ_y; z94)6I`vw+WHnd~77TNG=@4-oX_E}e<@Vv|2PSb4@8-2y(TojVzV>qIMT_zK`x8Ha* zzXsj3BiQ#2gZuvO2G2@D{K>|-+fR|YOH_L~UUh)RW0O$)?vm<4|9#?-B)<8_d3R)b zh3}Yze(2k(V?Gf>*4?;!AoARK^@g)1^RD})#Ct^<`-=*tw9Tp9{QP+5p7P`~bal~k zK|DdXoDpDl&v^6FeEpsfj)RGxdgvduZ>vbrIah==HBY zD;;n&!T$`jafZv)hY_^aHEcs?6!je0sXZ-Xf=Ynh-U?B-tl_?iKW>GK+U;jBjk zdgfu;xmU|jgK1`+=2_v!9Dz~BdJc8r(^bMO@|fmo0lI5r`$dN<|2Kkf%Sv()RQ^W?3sxcaCrOXS8B-CXKDV!Hl(iDBaJ||xW^CfYM zqR58!uD&M$6EJ>*f~L`Q0~Wi2M&q2a?RYa9;~GseE;qid%F$np41hh{0V z2KRR{__s+U?U|^KV{Ek-8IK-UKSkcls`B2b;hl7_620OM(pS~+ajNffLLAG3po{GC z63(3a=u(I)1`2ENXJS%4Wv2)c&W?W6o0~4B3m;(J#ZUR9(5U&+O_0rkDDr?|IG8Ej ze843sWl80OiMZs8m%2|6hAqW-ynE)+8n__MX2p>o>@I#iyQmsAn@iG;Qre;Aa*Pyy zTkzxKahahyvrP|lT15nl8rh!p4-?rs9f}v65TD3_tm?F-9_ve4hx#7*c=yRHa#oyl z4jHL9`Q;jvpAjvGIn+U^NvdnGy0XBR9A3j;y-qIQ%|+O}xktV1kR~Sn)dA1jBd(M) zM)g;Q$KH%R&?X0sG<_@xxK%AsC>GH;+Z&}04cfg;?126?y{o5!w9!7dk`~fweXg%Q z`z(L-J|4^0np6IQR0rv-8M~10vMN)7uS{%zovHjqn!EC~-k+!unD>pwg6W?fGyRL1 zWMvUQ&iZ1tYbMk9QyvFb|C;-(CSog-YUhLw?>dN3!yCQ&%>jaOu<1PA2!npRrpzOr z16+WXd8BFmd86U#b1HWsp}k@$JB_ZW@}7M-T` z%DE104-wW=VNSB`X_AsY8%L$()L_1Tfjy*qTgJ(TIN;E+2YtEvtZy9N9Pu;VlzFtA z(^=Mlt9HPOq(aE5pl?Qz_OhozIU1 zr#U~kQcW=HJysBxr81CaeCCSMI{Ura9)tr->qFY&^`M7xW z=HixPH6ng+6CqF7?RJ;QOSzvsTgo1be%OUK@jL-hwcV#AAB%~nXT(Ioo+1aI7Mo+r z8OY}-gcz&~-*Wi1_mJ~KN22`UFN;&lIvpQF(ieih1Y$kMSh=Id2p@vbAD#~->r@$% zk?Vm5!Q|5Gd3F!D85mKIbx%Z&ISZ7Kp?Dsi2Inc+T zV?O30a#NC-;%2;6borTgme-0RhBI^dMXTzodp(O0!Okg>7A;M-SJxv|3ktLEq6%JQ zU#L#pcg#kOTPyQ9L+~SL>)H5jqSVeWX!j|l!&H;>4NpWKAzKh$UP~ELqnZ*vx z1(tmae;R6I5sZ@V#>gJ3jhqVtX~(sqoW zPey(sO6tMk(Q|w~vV_RPv1#eYf~+ox6kXftvcY(tix|XrNtt!L+)s+cHxtu;z6q)D z@~D9@-5^<$?nsYF(lO7ie_i6cI9IxX^8%MF3Ol{mxNCZD=yZu;&Xv4-<=yms2@KR* zW2eJAi*%03I5}O|kS?MS0j+F79pMTe6g0WYYU@a{e^B&9^PDu>o}&x(HM%v6lO6B$ zQDG%{eq>tEhRh+rb;BwClP(pJ9oAR+ZnU&DwaDqKVYbvY3@*{ARD_o=`=oS+G1`N>_2O|70Z4(I-xXahqe^Ma3kF3 z#i2CH$5YUY3%WHtz#ZSugU<^GfP>dD{j)OFhIIb4XK$$@X=#}!Wj@um>Ipo>Z)%}5 zTct_z=OD}8D$jVcN*!jm3tL|_*l;t?u&5-zI#>8c*~c3Ru43>f)O;07cAtVu``Zss zXRGhqyOB)K z+6f`8mr7%M-YAQDZDV;O`&9DNL6i&EaW#>;@^E?Q(5;=WhodjMgpoh`2EQeBSBqrf z^-GkU+K<1fn=i{yO;6b_qDryfpyj>5bLw^;Jw z`NgvnZfaB6Er)MBHtX*W-*I(AZ!Yb6-nz13t&uUrSz#`vkISkh&Q92}EE;VGQJpgR z_J;paZmyPlSs%nY5KFUW{c+)wTIU2t$ojn_o4DTxGs+EamI)r2!*4X$auPep5|nMP za(FvO<#PD&(aww7ukVrK3sA&|-h#KyHiRw@R~5bGp+FKN-!3;ixMtddzw$REW$Hc(4XO1h0%9270dnRrrUe9$)}E&Yk`v)3Gq>H}ZQ0@n8RMhj)W z#Bs^R4JAIFjr+}wu1@F29bxm@3Q$0V5+>zHVhuue zya(o@@9G{^IpJ)m%Cq;t;(N)RGLgJ;i-EK5b5SmXmmgi={-mqfi;bvtl=M5a)0SKJ zWCMKHF_hA_V#KDMCGN_q~bY!yU5Aey~Wt1#j@lBat)(m0=c zXz?2rewnsEG#|cnR>q#MKrOb|6D2~($~L364xoK5Uj-j(_9^WtQV89glv}R{sry8R zvh(HHEzY1)p86Wb*MBUonl-ros@NrGF=T!~T1?++UA*v+qHlW(VuK&6xT zP1ZCb`_hOcfAGi=C}e^PDUM2}Fcnay5angAZAiPMC^aCn^Fzi+{mPJciA zgmYtIRWRiY<5b{`f(ZG@uyr3Xb%LB*kWKhFt!#FTE}XX50eu^N{O!1QhTCT=1NnHd zu{yhq@&FwJp3FhWYd6ROQCVO&9z)O53F5}6Aoy|~OBx%q^6b&&7Gt?|OhS#R#{Th` a6L|iCLJg!4+ 3) { return false; } break; case "Fit": case "FitB": - return args.length === 0; + return argsLen === 0; case "FitH": case "FitBH": case "FitV": case "FitBV": - if (args.length > 1) { + if (argsLen > 1) { return false; } break; case "FitR": - if (args.length !== 4) { + if (argsLen !== 4) { return false; } allowNull = false;