From a5408ab8edb12eb001539d9331a9bc11a354fd9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Mon, 14 Sep 2026 11:27:02 +0200 Subject: [PATCH 1/9] fix: pin the Imagick coder per provider instead of letting it sniff (OC10-164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit isDangerousToDecode() (af3c147ef5) is a deny-list over the libmagic-sniffed type, but the decode that follows re-derives the format independently: readImageBlob()/readImage() with no format set consults Imagick's own ~130-entry magic table, so the coder actually invoked can differ from what the mime check reasoned about. application/postscript and application/pdf are deliberately not denied - Postscript and PDF legitimately decode them - which means PostScript-looking bytes still pass the gate through every other Bitmap provider (SGI, Font, Illustrator, Photoshop, TIFF, Heic), and Imagick's own sniffing then hands them to the Ghostscript delegate anyway. Confirmed directly: libmagic classifies "%!PS-Adobe-3.0..." as application/postscript (not denied), and a bare readImageBlob() on that content picks the PS coder regardless of which provider read it. Pin the coder each provider actually expects instead of leaving Imagick to guess: getImagickFormat() maps each provider's own detected mime type(s) to an explicit Imagick format name, and Bitmap::getResizedPreview() reads through a temporary file with a "FORMAT:path" prefix rather than a bare blob read. SVG.php and Office.php - the only other two Imagick read paths in core - get the same treatment. The pin has to be path-based, not setFormat()+readImageBlob(): the latter does reliably make a mismatched format fail, but for every coder pinned here it also silently skips the actual rasterization step, so setImageFormat('png') ends up with no effect and getImageBlob() returns the original, undecoded bytes - confirmed for all eight Bitmap subclasses, not just the lazily-rendered ones (fonts, HEIC) where it was first suspected. Font's failure mode for foreign content is a safe, empty placeholder image rather than a hard rejection: FreeType fails to parse non-font bytes and Imagick returns a blank canvas without ever reaching a script coder or delegate, so it gets its own, separately-worded test rather than sharing the "must return false" assertion used for SGI/Photoshop/TIFF/Heic. PDF/Postscript/Illustrator are intentionally not covered by the foreign-content regression test: they are the Ghostscript-backed providers PostScript-ish content is not foreign to, and Ghostscript does not respect the pin the same way the other coders do - pinning does not close that specific gap, which is a known, accepted residual bounded to those three providers' own domain and mitigated separately by the ImageMagick policy shipped in owncloud-docker/php#309 (denies the MSL/MVG/MSVG coders regardless of entry point). Adds tests/data/testimage.{ai,heic,psd,sgi,tiff,ttf} - genuine samples of each format, since none existed. No genuine OTF ('OTTO'-tagged) fixture: this environment's Imagick/FreeType delegate cannot decode CFF-outline OpenType fonts at all, confirmed against four real system .otf files, independent of pinning; TTF-tagged content is what's actually exercised in practice for the font-sfnt mime type it shares with OTF. Stacked on af3c147ef5..51ca68bd2c (this branch) rather than opened against master directly, since it touches the same files. Per the discussion on OC10-164, this is an independent follow-up, not a blocker for that PR - and the 10.16 backport (#41828) stays unmerged until this approach is agreed here first. Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- lib/private/Preview/Bitmap.php | 33 +++++- lib/private/Preview/Font.php | 9 ++ lib/private/Preview/Heic.php | 7 ++ lib/private/Preview/Illustrator.php | 4 + lib/private/Preview/Office.php | 5 +- lib/private/Preview/PDF.php | 4 + lib/private/Preview/Photoshop.php | 4 + lib/private/Preview/Postscript.php | 4 + lib/private/Preview/SGI.php | 4 + lib/private/Preview/SVG.php | 13 ++- lib/private/Preview/TIFF.php | 4 + tests/data/testimage.ai | Bin 0 -> 9508 bytes tests/data/testimage.heic | Bin 0 -> 3675 bytes tests/data/testimage.psd | Bin 0 -> 14988 bytes tests/data/testimage.sgi | Bin 0 -> 12885 bytes tests/data/testimage.tiff | Bin 0 -> 5568 bytes tests/data/testimage.ttf | Bin 0 -> 153260 bytes tests/lib/Preview/CoderPinningTest.php | 133 +++++++++++++++++++++++++ tests/lib/Preview/SanitizeTest.php | 19 ++-- 19 files changed, 229 insertions(+), 14 deletions(-) create mode 100644 tests/data/testimage.ai create mode 100644 tests/data/testimage.heic create mode 100644 tests/data/testimage.psd create mode 100644 tests/data/testimage.sgi create mode 100644 tests/data/testimage.tiff create mode 100644 tests/data/testimage.ttf create mode 100644 tests/lib/Preview/CoderPinningTest.php diff --git a/lib/private/Preview/Bitmap.php b/lib/private/Preview/Bitmap.php index 30f09c161f5a..ad6f11f97d5c 100644 --- a/lib/private/Preview/Bitmap.php +++ b/lib/private/Preview/Bitmap.php @@ -49,7 +49,7 @@ public function getThumbnail(File $file, $maxX, $maxY, $scalingUp) { // Creates \Imagick object from bitmap or vector file try { - $bp = $this->getResizedPreview($stream, $maxX, $maxY); + $bp = $this->getResizedPreview($stream, $maxX, $maxY, $file->getMimeType()); } catch (\Exception $e) { Util::writeLog('core', 'ImageMagick says: ' . $e->getmessage(), Util::ERROR); return false; @@ -82,10 +82,12 @@ public function isAvailable(FileInfo $file) { * @param resource $stream the handle of the file to convert * @param int $maxX * @param int $maxY + * @param string $mimeType the file's own detected mime type, used to pin the + * Imagick coder so it can't be redirected by the file's actual content * * @return Imagick */ - private function getResizedPreview($stream, int $maxX, int $maxY): Imagick { + private function getResizedPreview($stream, int $maxX, int $maxY, string $mimeType): Imagick { $content = \stream_get_contents($stream); if ($this->isDangerousToDecode($content)) { @@ -94,8 +96,27 @@ private function getResizedPreview($stream, int $maxX, int $maxY): Imagick { $bp = ImagickFactory::create(); + # Pin the coder instead of letting Imagick's own content-sniffing pick one: + # reading with no format set re-derives the format from a ~130-entry magic + # table independently of isDangerousToDecode()'s check above, so content that + # looks like PostScript/PDF (which that check must allow through for the + # Postscript/PDF providers) would otherwise reach the Ghostscript delegate via + # any Bitmap provider, not just those two. + # + # The pin has to be a "FORMAT:path" read, not setFormat()+readImageBlob(): the + # latter does reliably reject a mismatched format, but for several coders here + # (PDF, EPS, AI, PSD, SGI, TIFF, HEIC, HEIF - i.e. all of them) it also silently + # skips the actual rasterization step, so setImageFormat('png') below ends up + # with no effect and getImageBlob() returns the original, undecoded bytes. + $tmpPath = \OC::$server->getTempManager()->getTemporaryFile(); + \file_put_contents($tmpPath, $content); + try { + $bp->readImage($this->getImagickFormat($mimeType) . ':' . $tmpPath); + } finally { + \unlink($tmpPath); + } + # setIteratorIndex(0) will make previews to be generated from the first page - $bp->readImageBlob($content); $bp->setIteratorIndex(0); $bp = $this->resize($bp, $maxX, $maxY); @@ -122,6 +143,12 @@ private function isDangerousToDecode(string $content): bool { return \in_array($mimeType, ['application/xml', 'image/x-mvg'], true); } + /** + * Maps this provider's own detected mime type(s) to the Imagick coder name that + * must decode them - the format pinned in getResizedPreview() above. + */ + abstract protected function getImagickFormat(string $mimeType): string; + /** * Returns a resized \Imagick object * diff --git a/lib/private/Preview/Font.php b/lib/private/Preview/Font.php index 775147d83eaa..3cd330aa2164 100644 --- a/lib/private/Preview/Font.php +++ b/lib/private/Preview/Font.php @@ -29,4 +29,13 @@ class Font extends Bitmap { public function getMimeType() { return '/application\/(?:font-sfnt|x-font$)/'; } + + protected function getImagickFormat(string $mimeType): string { + if ($mimeType === 'application/x-font') { + return 'PFB'; + } + # .otf and .ttf are indistinguishable by mime type alone (both application/font-sfnt); + # TTF is what actually decodes real font files here, both tagged variants included. + return 'TTF'; + } } diff --git a/lib/private/Preview/Heic.php b/lib/private/Preview/Heic.php index 6e7bba4125ff..e06cd65acc1c 100644 --- a/lib/private/Preview/Heic.php +++ b/lib/private/Preview/Heic.php @@ -29,4 +29,11 @@ class Heic extends Bitmap { public function getMimeType() { return '/image\/hei(f|c)/'; } + + protected function getImagickFormat(string $mimeType): string { + if ($mimeType === 'image/heif') { + return 'HEIF'; + } + return 'HEIC'; + } } diff --git a/lib/private/Preview/Illustrator.php b/lib/private/Preview/Illustrator.php index 06a98d9e4c5b..0267b4712d15 100644 --- a/lib/private/Preview/Illustrator.php +++ b/lib/private/Preview/Illustrator.php @@ -30,4 +30,8 @@ class Illustrator extends Bitmap { public function getMimeType() { return '/application\/illustrator/'; } + + protected function getImagickFormat(string $mimeType): string { + return 'AI'; + } } diff --git a/lib/private/Preview/Office.php b/lib/private/Preview/Office.php index d8f038279b23..1def5ee281da 100644 --- a/lib/private/Preview/Office.php +++ b/lib/private/Preview/Office.php @@ -68,7 +68,10 @@ public function getThumbnail(File $file, $maxX, $maxY, $scalingUp) { $pdfPreview = $tmpDir . '/' . $pathInfo['filename'] . '.pdf'; # Note: no SVG sanitization of the file content required .... - $imagick = ImagickFactory::create($pdfPreview . '[0]'); + # Pin the coder: this is LibreOffice's own PDF output, but readImageBlob()-style + # content-sniffing is avoided everywhere else Imagick decodes a file in this + # codebase, so pin it here too rather than rely on the ".pdf" path extension. + $imagick = ImagickFactory::create('PDF:' . $pdfPreview . '[0]'); $imagick->setImageFormat('jpg'); } catch (\Exception $e) { @\unlink($pdfPreview); diff --git a/lib/private/Preview/PDF.php b/lib/private/Preview/PDF.php index 0ab92bfb9cbe..40ae6397091b 100644 --- a/lib/private/Preview/PDF.php +++ b/lib/private/Preview/PDF.php @@ -30,4 +30,8 @@ class PDF extends Bitmap { public function getMimeType() { return '/application\/pdf/'; } + + protected function getImagickFormat(string $mimeType): string { + return 'PDF'; + } } diff --git a/lib/private/Preview/Photoshop.php b/lib/private/Preview/Photoshop.php index ca15dc1a12bd..7f7add29fa96 100644 --- a/lib/private/Preview/Photoshop.php +++ b/lib/private/Preview/Photoshop.php @@ -30,4 +30,8 @@ class Photoshop extends Bitmap { public function getMimeType() { return '/application\/x-photoshop/'; } + + protected function getImagickFormat(string $mimeType): string { + return 'PSD'; + } } diff --git a/lib/private/Preview/Postscript.php b/lib/private/Preview/Postscript.php index bab73b808494..e96c2539afa8 100644 --- a/lib/private/Preview/Postscript.php +++ b/lib/private/Preview/Postscript.php @@ -30,4 +30,8 @@ class Postscript extends Bitmap { public function getMimeType() { return '/application\/postscript/'; } + + protected function getImagickFormat(string $mimeType): string { + return 'EPS'; + } } diff --git a/lib/private/Preview/SGI.php b/lib/private/Preview/SGI.php index 81f43410fe3a..c9c24d4ab523 100644 --- a/lib/private/Preview/SGI.php +++ b/lib/private/Preview/SGI.php @@ -27,4 +27,8 @@ class SGI extends Bitmap { public function getMimeType() { return '/image\/sgi/'; } + + protected function getImagickFormat(string $mimeType): string { + return 'SGI'; + } } diff --git a/lib/private/Preview/SVG.php b/lib/private/Preview/SVG.php index 50347f4de65e..f750de84e34d 100644 --- a/lib/private/Preview/SVG.php +++ b/lib/private/Preview/SVG.php @@ -58,7 +58,18 @@ public function getThumbnail(File $file, $maxX, $maxY, $scalingUp) { return false; } - $imagick->readImageBlob($output); + # Pin the coder: reading with no format set would let Imagick's own content- + # sniffing pick the coder independently of the svg:sanitize/embed/decode + # options above and of the isDangerousToDecode()-style reasoning in Bitmap.php. + # This has to be a "SVG:path" read, not setFormat()+readImageBlob(): the latter + # silently skips the actual rasterization step, same as in Bitmap.php. + $tmpPath = \OC::$server->getTempManager()->getTemporaryFile(); + \file_put_contents($tmpPath, $output); + try { + $imagick->readImage('SVG:' . $tmpPath); + } finally { + \unlink($tmpPath); + } $imagick->setImageFormat('png32'); } catch (\Exception $e) { \OCP\Util::writeLog('core', $e->getmessage(), \OCP\Util::ERROR); diff --git a/lib/private/Preview/TIFF.php b/lib/private/Preview/TIFF.php index 25404d6e6a0f..9f7ff4bfedc7 100644 --- a/lib/private/Preview/TIFF.php +++ b/lib/private/Preview/TIFF.php @@ -30,4 +30,8 @@ class TIFF extends Bitmap { public function getMimeType() { return '/image\/tiff/'; } + + protected function getImagickFormat(string $mimeType): string { + return 'TIFF'; + } } diff --git a/tests/data/testimage.ai b/tests/data/testimage.ai new file mode 100644 index 0000000000000000000000000000000000000000..bdbe2f59ae0ecd1fbc31c3e49f040629a6269ad0 GIT binary patch literal 9508 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 Q@c(a1o+@d-!sq5JhM9aF6PUp<<~yo z{{mX}e`ZekPw~HE1zee>YfT7)kuV>=g7ffH)7&aSW9S72d4Lj zX_x?v(T92XB)|(ztKJ*7Y1(V~p&u}h8VzB!ruh=bcb%ryWLz~5YFaJETZ{O$=%cnD zybsL1_5)3mwShUxFMu`k^Mcke7FZ*{lbU8DhOG&-gFY}0ro#$g3^roeEw# z$`Am-&;v#R^YY&Ur{R&N1>gyw&wy?)8R#qEJGiN7frX(KIi_@_AJ>k+8n`ZjZ{aHW z%?FItjXb#xfT^$^SO>RX;W;^V17G+T&_|iUFa%Bm)v{9X>vaVm_tR@sA4*~9|){%<+tGwxo-xnr(kUbd2qMEE^;3PjNj7-bhtv^ z8^Hp|AnzSu6L~KV#PB{&-UHzy$Rh9Efim`ZF$n_HO{=4rl@B0S;i_1~8_8L~>sen71pXD|_0N zdAoi9pTIu2Lw;SL1~6AQa^%K%+_u6=NG6}JKn3sv1zlk{5Ub20_#F1a8Mq72$a5*E z2E;7O*vs~Y(STl#*yVeX_d>9kyt7X#t|0FfVHSBW026@quF?lCl6&$g*e~vk-<^4R z425gty#*|Xr{uj8d_msbfbms5O5SV2bfB+l^igdmd1o#@QNW(5-W2A;ZSwvGB#?K; zUIV?xLvlZkyq5sxS&M#a(Qhs0S{qO8p1`4mS3SEgsn0HukfPHMcPq+Y@s8D&Y5T0_|Y{;P+n%d*CKHW(@;;p%n}S<{Gd8 zPQU|l&$t2^hbyJ)zkv00jRoSl{s<}Lm^f}WVEk^(*KHx}g!4cjWeNkwNtrr8oHD&& z3`~V(um$$R1)#sO`G9z3eW4jJ_Okt80=cK3ayQ8T5^~SDDjXvBAwXG)@m1PJ-pN_z z<>cKJh(QxgOoZp;p1(cFpGQ17&ku~n^BeMB9!9|_@*V&);U0OXZ|~2@dvRd@Rbz}k z^?)_>c|zX1!A5vN?t26CsKGpId`#|%EyZ!1i=Vc2JA&YV%X|KYv>6hAqEx$W3Um!b`}x=uYVa}E&Q7Ud)t2q#K9Uk z07>MyB=|!(42OBZF%UpM0h#2UaRky{BZq&B3m%KS-h%x7{}R?-YYrTD8tbh20c+`` zI;9Wfmbt&Jzgb_6wa_G3ZEAowI5$V0(w*NHx%Jj>j~u)xJ;Bnd0&C;cDp6L<`Rz$* z^=o0pwc-VW72EpT^5w$*&|LH2#&7na#@^T1Z%#^3T97A=<4h|J|C9C1o12&AE3f{4 z`}<}6{ZGdFvbO)^|DXIf=NS0s`2X+igS^M|%Z}H)dfwmGImtTzSmd6Qa?4`WSy+GP zmPPq(k++Y$zh8E2|5Nwh%jwJ3E$>?A{hgbayt&GozucT!Wp2L9mNff{lBPx>vkPSv zT8z)AggqD1yO=TQ7xpBK^5Gg)%p4?&nN}gQ3uP6Wy;AJizNYT0V<>7CB11BD5&^iqxXiD@xOS zqRf0gf2tit?WjN1CQzI3r`kQ#?)g*g1!^z+sWzS3^#58LWwK8HWnBL&>q?2ZI^9Rl zm=hW5TU5kV4WInk51$&1ON(j$iWm{MVtGttm!@uFhI_jOJ5MG){q^KGQ(IIKS}7UV zVnEdVMH9L-Dk|dwyT@!k_}TQ3(sEjxe(%p+oiKZ1-_~w&hF`bkyU!#&y?18s-0&(= zE2ZK(ji0e{RqUX!qAD(A*oQlhZClj6w3^m??6hT@H!X=9)6-4O2pYO}|AmySqzea^ z^{JvXXHH58NBy|tFAAIXdkKvS38VFeLZ&@yP5olR;njKh&7!8`>PH1Fu@`zltcP9KoYE-lhHR z^&^5xD0{?)MB3k666&JjLPst;czQ!jw<0-{C?@PR;~y6{&O1tfYM4H^5;70WgEpvk4T3Q4V~GR8fyn!Kat)8zg;1(m(!tQ4BujSXVWhuo#fPaTvBUPqIw{R-ub zu81(EJS%NFj*6xkB}{#P0b#s;zJh7|)R132Gs>Edn?a%*JzlR-P-sP@5%(PTPqOtR z+=mNDBlHsP(=GWm@Dc9YZ^;3;Z#F0>wIa%hx7#D4>j9S8<>3%CCu!ao_Ey z#^JuxwqVY1T!cQ$&9wIs-@j@`_Z6b+gGy#ha(f~AWtBG_>2Hdq#Z7$`BXN=X0*u4t z0gRDS_J4>mrKgm`pJDthT&}{njzPF6{S%B)>L|u3N{vg$m=>wj6w8>=S8c$!EjNB) zp$~R59a&!0vPzoKX${1bXI0GTr=vyFv2(BmcmbgmmiidW=wJ64#`{4s?zv@* zlCAG!yxG+MIL00Yq*hqz(Uvi|wPk!5q2euL)(qA2A;vrHgHL0OERZvQ_CxSvhWm>M zV?(_wbWhVUN_5G>y5GG?RxwkbMR2yj+nKno%dWVF%4xVJ%f8QW9rkNwxfT$atoOHE zx6}|^lhs08)72Qubt0&T<@)50u=;+s%C}--Nz<`Zbbp5RX}E~0Xxbyi$2fO6qw0q- zeJ|~pR>=X+EmIE}hiQUbi)pVjsD1*|VKo=i1~uL?WksrZOtESUrh~aL3ktn^S<}8l z7$r={$*TW)P}OuKH4s}F-c9eoM@3Ej9zhFAeE_a+<#b$U0^2;ql^i6u79-%HA3ydb+=WgOk62>!XCkTQFJQKhHBzk{n~Lk#kPaERy0vL&#GHP!~(p%s;1+;>;5L*jp9QW zQ(wzjqkzf^8$`i~>sk8QYGQA$ta>wbwHn*@+%pCf<^(=7e`1f#rt3rP?uZOnUjWacPJkBBNHqI03L!9@* z@(kgLE9a70J_qxg(c8R5|Kx(E{Uh-SE#`~Gw74Yt7cz}sT5)Y*2`uy7#&v(hyrYgB zk%D=pT!(py{222UIRf+bPFz)3h^Lqn!$VJE-rGujkcN4^+KPF#T95g<`T+B-fw|Wc zmLtiPT_HXyXwEoZN5~-`9k_X{h5N6xxG3JHMY4FSfN6iRygCPJZu0X3qyXRb$ljCX^61u8w8uh))n{k&#%d@8v#w%`d7|2tr{}mpZpe zA*r{=r|RJQMRvIG^XEo;ZegbFAFcE^uG8aTH(8)`d_*D<($5`w=4wz znoDw)zxSmgW?aUmnZvqw61{4h_HdC_j%#fxXWTuO<@GvOusr%Qe*A!UPqe z?vhgw_sA&35%MzPSJ@GkAnsE$5f7*th##nHh`aOj-5kd|;s}oQVj7M~Vjqs^?7rI~ z4w1(Zx5#;j(ee=D%LUk<~ne>B*&mvQ+&(B3LJCAMjWrx zH>dw!5R?2{BYrAZBYq^mKn$gC&iXeHQ-XUUZd98QKUKRBd*$hS9FEmuHjd>veQzpj zl0;|UI^qVo5HTUA?=KNAmv;6&8}Tc(3UO0T-`^r$E1k36++uoNDZyDwe2ZnXm`eEf z#UU(Hot+#0*HGum?@_;!b5R}gDC%5i??&)V)Me^0>Tb0Rb)Gtfx-7SQHfmoS!^C+U z-{++BdKr%U*XW+@8HqYxUP3*Plh2!|iS_B8O*sWMR$WCsnv>8ws3~o7yXQt{VR6&m zL8N0jBYHA`aPg#!sgHAY-rTG}>?MCgJSPVtc9)i@yE<=Z)*+5i8HkshJ8_tLia6Uf zXJrZt!((SL(`Z<`G_MT2T5x>SwGsW8r?YRvwi~f!6U0aU;fO7oA)d53`!<61BX$i( zd>q^dv2zE+vn_M`b`eIk&D_B@uFaXCow&`Re_nKPGmT#Z-K@JpqwZIzAx*4vkhD%Z zmtdS$xGB0NfHb zH4b@jP%3iD(6TuZc#w7RaRZE2VA`FxOc>LvK}Alcv9=P<2MWo<$es$ zS_C}AaM$l03}@afXFagl$L`I*uu2`Z44p%qSIMA}7%p@vmlNkzo_D*)EdRor`f&B3++`NZ3oOw_-2NTLtiB4p-0Qr==W#TDKE8Gd5RssWYZ6eR6P1B zwH$q(+Km2iQLFMfLCOieAy=T}s@3mSH)F1PiN>>UapQ9@zE(w{m6LifVoG4WM8xX> zGGyUx#KfhID@v`L(z_w1g@kfX6LUL6b$33UrmP9CnA3N8E)GPVAjVcV=M4~VdI|R~ zA8kLAZl+)UVP0GJ%0es8WdVm>PQfu!h6hN$zAJZ~OE-V}<>2B7zsgc8&jkU;95oY% zq56iXpfT(BUCuBwZX8P(5>)w*Py-pvgFw%ptC_J!M97n*_$HkBs(Cqsj7EF-hV4As zaoO=n^3qnE`09E&ySJmIcWQYB?X-IDY3iCDocCIL{ob+R&LkY$M3Yo*dhgcty_(;Q zd2wb#OfS!>R^NsnGjQyXt+As8f2?#b#DYQe8*nZ!@B)W?i_a8k}vOC zGO=aVoCpD`lbJ01Ad-=>ZVv7q$g9n{gka|Cqwz7})ypS0ox1(fQ{Z>%=Sd@3v zXiIrASnalypxiDi3O&9wmzVrPf8WzO$BpM+?v%ICDoTAR!VmeS?m!qX4TPV)rB+et zYY-0SSNc4JSTzUXqIb>^D+Y^ zlM9$JkB1A-FZ@8W z<_$|s;`|Wx-fdjTVYy+2i1qXm0TcE-H!(l^xS_Q5Sbi1rB@TEgLoD+MA8X>VEkjhtIY+WE{}$54 zGOrI)L6K{3V7{6#I7q4PPciF0IZGhKtoIVZN-YXQ9a+3 z()RA!7R_k!d39@4vy7C4u1bXsiJG(AP~&KEf739=(sj6F;b-gOjmR#%#TvDxa|c>{ zS^f8+#qBrEXWtA^uW?e+d5FHXppCDKnCjR0<0R8;FCKAG{?^kuq`1ST`F!ul_VqbM zO~ZM6SwtfjIkj1zwaKR0Q$EJ|oy|FvxDz-J8hzVv!di&)?%Kg&E^6vqqqn4*W~9o* zd8p+dL(m@==3URRFC)b2(q>%x#qZXBw(rU#ZnFo9OYGclUVF`25j_)E%E@o~$ql%E zyS#tn=0n#W;~Fim;M!aNHER`|uC%k?k5ymc%D8rP`_AJxGjZ9~bzBGAyp}WbDnbwB zk`XC>^spXK_p+;=Pj{~&v?@}617U(Zju0pJTf&EaHKbNW>75W_)ft3%^&`TI6+tzA z@6Ygk!SN6!_92fIhj>!^A*`m=pV7z?V&x$#l01rVuxm}LKO@W%<|`}GOmzz3*bx3r zqVsk^2%Tx!7l@6By~SlVTk_{`*LJSNHH2mI3xpx^Dnjbk-nE^R=asH~t=fe!N!>uW z|MiI4fAq)g6OY6nd6;pbV*bjhBinfRIlJS=iD%%I)OV3f*36w0VdEdUv6S30@zA@T z`ax>-mSxih2l@TcSwF;MVz4`xgzEL2-3+JZq#Q#{X1#jO4yI6ZRz+Jiq4jc_x(j`4 z5nfjY)XWm5{&jup*w=YI;CSA=kyW#&zIB}Id#HKQv7J?Op#JYo4ZlPl$|s8NsUGcY zYBWot#x4&~6Xk4byp=-DTy>P18M#e8gwfE-B&GA0Xn1enZu?1OW6NpO*=GGQp|NE(TJ7SG zr?HK5y#B(7=H0H5)UJup{G~C|`Xjkp6RG(tWAO|ANFCZF#~UDw@FP4-WvvQqDzpG; zbU)5t&(^)sRB8dr7GZufHy|I?_J$u=V=q!KTpHrB+AT zC!etXOyAM#^_&*<#B{$=3A;{SIr7Egu3pWBR!>fEHu>|tXRaOJ`Emb%=2EMtroT1) z%Yzqgp8jtAxRB;K?fyUbfTh3m^PK+jPkAr@?Dz6dgfIV`nEmPTr5`*EE%$rnU&#N* zubuztbLn4wn9cLe^{*`d>D%q!eE|Nu56FL^=lKNv_n)!<{!{qhe@_2*KFa?)ANT+L He=6`F9S(1Y literal 0 HcmV?d00001 diff --git a/tests/data/testimage.tiff b/tests/data/testimage.tiff new file mode 100644 index 0000000000000000000000000000000000000000..9db137a2f5a6c78c1a7133c9551c38d51389bd7d GIT binary patch literal 5568 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 RocY_INXi#<^&)Tp{s%UN0|fv8 literal 0 HcmV?d00001 diff --git a/tests/data/testimage.ttf b/tests/data/testimage.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3f603b740aafe509213b9c41109a2dea9f615f50 GIT binary patch literal 153260 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�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%0Db$C7AfH&ezcr)IDx8iMh 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 + * + * @copyright Copyright (c) 2026, ownCloud GmbH + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace Test\Preview; + +use Generator; +use OC\Preview\Bitmap; +use OC\Preview\Font; +use OC\Preview\Heic; +use OC\Preview\Illustrator; +use OC\Preview\PDF; +use OC\Preview\Photoshop; +use OC\Preview\Postscript; +use OC\Preview\SGI; +use OC\Preview\TIFF; +use OCP\Files\File; +use Test\TestCase; + +class CoderPinningTest extends TestCase { + private function makeFile(string $content, string $mimeType): File { + $stream = \fopen('php://memory', 'rb+'); + \fwrite($stream, $content); + \rewind($stream); + $file = $this->createMock(File::class); + $file->method('fopen')->willReturn($stream); + $file->method('getMimeType')->willReturn($mimeType); + return $file; + } + + /** + * @dataProvider providesLegitimateContent + */ + public function testDecodesItsOwnFormat(string $fixture, string $mimeType, Bitmap $provider): void { + if (\count(\Imagick::queryFormats('SVG')) === 0) { + $this->markTestSkipped('No SVG/extra ImageMagick coders present'); + } + # HEIF is registered as a coder distinct from HEIC on a real libheif1 install (verified + # against the actual owncloud/server images), but not in every CI ImageMagick build. + if ($mimeType === 'image/heif' && \count(\Imagick::queryFormats('HEIF')) === 0) { + $this->markTestSkipped('No distinct HEIF coder present in this environment'); + } + $content = \file_get_contents(__DIR__ . '/../../data/' . $fixture); + $file = $this->makeFile($content, $mimeType); + + $result = $provider->getThumbnail($file, 32, 32, false); + + $this->assertNotFalse($result, "$fixture via " . \get_class($provider) . ' should have decoded'); + } + + public function providesLegitimateContent(): Generator { + yield 'PDF' => ['testimage.pdf', 'application/pdf', new PDF()]; + yield 'Postscript (EPS)' => ['testimage.eps', 'application/postscript', new Postscript()]; + yield 'Illustrator (AI)' => ['testimage.ai', 'application/illustrator', new Illustrator()]; + yield 'Photoshop (PSD)' => ['testimage.psd', 'application/x-photoshop', new Photoshop()]; + yield 'SGI' => ['testimage.sgi', 'image/sgi', new SGI()]; + yield 'TIFF' => ['testimage.tiff', 'image/tiff', new TIFF()]; + # no genuine OTF ('OTTO'-tagged) fixture here: this environment's ImageMagick/FreeType + # delegate cannot decode CFF-outline OpenType fonts at all, pinned or not - confirmed + # against four real system .otf files. TTF-tagged content, which the TTF coder decodes + # fine, is what's actually exercised in practice for the font-sfnt mime type. + yield 'Font (font-sfnt, ttf bytes)' => ['testimage.ttf', 'application/font-sfnt', new Font()]; + yield 'Heic (image/heic)' => ['testimage.heic', 'image/heic', new Heic()]; + yield 'Heic (image/heif)' => ['testimage.heic', 'image/heif', new Heic()]; + } + + /** + * PostScript content is sniffed by libmagic as application/postscript, which + * isDangerousToDecode() must not reject since Postscript/PDF legitimately decode + * it - so the mime-type gate alone lets it through here too. Pinning the expected + * coder is what stops ImageMagick's own content-sniffing from handing it to the + * Ghostscript delegate through a provider that has nothing to do with PostScript. + * + * PDF/Postscript/Illustrator are deliberately not in this set: they are the + * Ghostscript-backed providers PostScript-ish content is NOT foreign to, so + * feeding it to them tests Ghostscript's own leniency, not cross-coder confusion. + * Font is also excluded: see testFontNeverInvokesADangerousCoderForForeignContent(). + * + * @dataProvider providesForeignProviders + */ + public function testRejectsPostScriptContentFromAForeignProvider(Bitmap $provider, string $mimeType): void { + if (\count(\Imagick::queryFormats('SVG')) === 0) { + $this->markTestSkipped('No SVG/extra ImageMagick coders present'); + } + $postscript = "%!PS-Adobe-3.0\n%%BoundingBox: 0 0 10 10\nshowpage\n"; + $file = $this->makeFile($postscript, $mimeType); + + $result = $provider->getThumbnail($file, 32, 32, false); + + $this->assertFalse($result); + } + + public function providesForeignProviders(): Generator { + yield 'SGI' => [new SGI(), 'image/sgi']; + yield 'Photoshop' => [new Photoshop(), 'application/x-photoshop']; + yield 'TIFF' => [new TIFF(), 'image/tiff']; + yield 'Heic' => [new Heic(), 'image/heic']; + } + + public function testFontNeverInvokesADangerousCoderForForeignContent(): void { + if (\count(\Imagick::queryFormats('SVG')) === 0) { + $this->markTestSkipped('No SVG/extra ImageMagick coders present'); + } + $postscript = "%!PS-Adobe-3.0\n%%BoundingBox: 0 0 10 10\nshowpage\n"; + $file = $this->makeFile($postscript, 'application/font-sfnt'); + + $result = (new Font())->getThumbnail($file, 32, 32, false); + + # FreeType fails on non-font bytes by producing a blank placeholder, not by + # invoking Ghostscript or a script coder - so this may be a small valid image + # rather than false, but it must never carry rendered PostScript content. + if ($result !== false) { + $this->assertLessThan(2048, \strlen($result->data())); + } + } +} diff --git a/tests/lib/Preview/SanitizeTest.php b/tests/lib/Preview/SanitizeTest.php index 882a1230866c..fef24e0da798 100644 --- a/tests/lib/Preview/SanitizeTest.php +++ b/tests/lib/Preview/SanitizeTest.php @@ -32,7 +32,7 @@ class SanitizeTest extends TestCase { /** * @dataProvider providesSVG */ - public function test(string $svgContent, Bitmap $provider): void { + public function test(string $svgContent, Bitmap $provider, string $mimeType): void { if (\count(\Imagick::queryFormats('SVG')) === 0) { $this->markTestSkipped('No SVG provider present'); } @@ -43,6 +43,7 @@ public function test(string $svgContent, Bitmap $provider): void { $file = $this->createMock(File::class); $file->method('getContent')->willReturn($svgContent); $file->method('fopen')->willReturn($stream); + $file->method('getMimeType')->willReturn($mimeType); # create the preview - SVG/text/script-shaped content must never reach Imagick via a Bitmap provider $return = $provider->getThumbnail($file, 32, 32, false); @@ -78,13 +79,13 @@ public function providesSVG(): Generator { SVG; # all Bitmap based providers use the same thumbnailing logic - two is enough .... - yield 'PDF provider - image tag' => [$svgContent0, new PDF()]; - yield 'Font Provider - image tag' => [$svgContent0, new Font()]; - yield 'PDF provider - malformed SVG with MSL href' => [$malformedSvgWithMslHref, new PDF()]; - yield 'Font Provider - malformed SVG with MSL href' => [$malformedSvgWithMslHref, new Font()]; - yield 'PDF provider - raw MVG' => [$rawMvg, new PDF()]; - yield 'Font Provider - raw MVG' => [$rawMvg, new Font()]; - yield 'PDF provider - well-formed SVG' => [$wellFormedSvg, new PDF()]; - yield 'Font Provider - well-formed SVG' => [$wellFormedSvg, new Font()]; + yield 'PDF provider - image tag' => [$svgContent0, new PDF(), 'application/pdf']; + yield 'Font Provider - image tag' => [$svgContent0, new Font(), 'application/font-sfnt']; + yield 'PDF provider - malformed SVG with MSL href' => [$malformedSvgWithMslHref, new PDF(), 'application/pdf']; + yield 'Font Provider - malformed SVG with MSL href' => [$malformedSvgWithMslHref, new Font(), 'application/font-sfnt']; + yield 'PDF provider - raw MVG' => [$rawMvg, new PDF(), 'application/pdf']; + yield 'Font Provider - raw MVG' => [$rawMvg, new Font(), 'application/font-sfnt']; + yield 'PDF provider - well-formed SVG' => [$wellFormedSvg, new PDF(), 'application/pdf']; + yield 'Font Provider - well-formed SVG' => [$wellFormedSvg, new Font(), 'application/font-sfnt']; } } From 4bb8f0529b69aa201803660ea7121c128d6851bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Mon, 14 Sep 2026 11:29:39 +0200 Subject: [PATCH 2/9] docs: add changelog entry for OC10-164 coder-pinning fix (#41832) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- changelog/unreleased/41832 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 changelog/unreleased/41832 diff --git a/changelog/unreleased/41832 b/changelog/unreleased/41832 new file mode 100644 index 000000000000..9ddb3d5b0a16 --- /dev/null +++ b/changelog/unreleased/41832 @@ -0,0 +1,14 @@ +Security: Pin the Imagick coder for each bitmap preview provider + +Bitmap previews decoded content with no format hint, so ImageMagick's own +content-sniffing - independent of the mime-type check that decides whether a +preview is even attempted - could still pick a different coder than the one +a provider actually serves. PostScript-looking content, which the mime check +must allow through for the PDF and Postscript providers, could therefore +still reach the Ghostscript delegate through any other bitmap provider (SGI, +Font, Illustrator, Photoshop, TIFF, Heic). + +Each provider now pins the exact Imagick coder it expects instead of letting +ImageMagick guess from the file's content. + +https://github.com/owncloud/core/pull/41832 From 2bf5ab9c34eda4bd1ced8909310ea4057b0250df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Tue, 15 Sep 2026 11:26:57 +0200 Subject: [PATCH 3/9] fix: replace the HEVC-encoded HEIC test fixture with an AVIF-encoded one (OC10-164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tests/data/testimage.heic was a real HEVC-encoded photo. The GitHub Actions CI runner's stock libheif1 build only ships AV1 decoder plugins (aomdec/aomenc), not HEVC, so CoderPinningTest's Heic (image/heic) and Heic (image/heif) cases fail there even though the pinning mechanism itself is correct - confirmed by reproducing the exact CI steps (ubuntu:24.04 + the same PPA setup-php uses + plain apt-get install imagemagick) locally. Swap in an AVIF-encoded file under the same filename instead: the HEIC coder module decodes both HEVC- and AV1-encoded content, and an AV1-only libheif matches what CI actually has installed. Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- tests/data/testimage.heic | Bin 3675 -> 1326 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/data/testimage.heic b/tests/data/testimage.heic index d6059ba8b301cde85c95b8bc8fd9fd6306001140..6b0bbd258cd3e51d65f9ab7bdb8d9a1d28ad3fdf 100644 GIT binary patch delta 1300 zcmcaDvyMxFfq_9Lt)#Lbu`DwU$Yuc1xtVE(xtWO|{;P=^I`w=7nI*X(Nd`tBR?5uD zPX=*Z9Dsa~2m>P@gl1r1Q2=t4Gc)tRhJi&zft*w(uriSG28JMJR%Ss_0g(32EJ)4= z(!$C4IYoKNITZ{{K*-hr6yixNGjwib;9;l-azrwV3sQkJ2sA*kKtX0jCP;vpgM$M| ziDwq%CW81t0CX5jV-s@=&_x=#DTyUQ3|wpylKcN>I2ldm5d6b>UFV~^i^E;L=OG?z zr4*isysPbWx69z*Y4)=7eV*{dZSSvnH8%@)&a~ze^RBO8_rEWtoYzDGZ3-^wCCmzq5Z!vROrNJz*2ki)+v3I&<_zJNmu^4X zcI!*%$EPRF*7g25>v2<9`2+)(`i<7o%q0(2msfDG)M@{<|2;qKLHdh7{}z_WtepKm zI^=~zf%Pl?68|s8^`6S_L?ox43OmZQ;`;5hl{LPn1mv2Z_H*~Ie7SJ>(qgWTx%;|J z9(4xHQ#IGLj1PTxaH0RL84t_$FNsmLL1yNUPR-=T z$AJ$YN=MGvD}6bQ$>Pekf2%+3oRjkJ^_{YKm8o?<4);%3eCTB6?ApxS`merkLnp4z znp_xfsczP-lGU@8W$&#^pL|^_`tR$rK9UaI%kYJRxx)Y41CO(68T#Gx7}j545!K&6 zRpFKIlb?H*yRrY4|KoGpWexM9^V^*M`6M28lGAIsaDRQkp-bHDY}0;y*Uow|K~eNr z%YWPcE7HFZ)hMo#~#B zep8bEu6xj6dZABY-&L7UsXe}Lb@n$mJ6*oxx$VW_`F{58>vigyn3bMgdKSp0#H=6O z|B=P$NkaVUZ>w8x^+&v@4tSWcbJey9=j4yRIWqqhe~xcO;um$bRoN@1Mb7AqnUW&+ z>PG!R&bIwC4u9J-lW%|cmxY~*S5-w;ENfqz^wXqCNB7FgG^NE+inC+e_dd*z_?eMB zuVLA`h0mrYb_@RBdZsz^UP`-Chg?N{Esxs|Tj64}B_1Jn__^{&m*R$`p8t%{pN#DppC zyG!6zaorYg%{`)0JN_S^*?sm;zR$b7drLkoT;F3Go#5)9oXTgEBWZFrsQ z{q{c+ZJNY+%If`ZIvw?EJNIn&hy3o;#MO;6cqhKKu+FR&F#b`{+MU-jX-EF)(2dc3 zo|?1G_HbO^W)#`7W{yf_<`4fVf;Nw5akxq}wd+(BEqw4KhO2n$z1yb`o%ZHfVir;3 zxPyI_Uq%E&V!h&&SwcTg7S0UY;;|()i&@0=qOD%$yR6vqg%eL_pUPpmI`5(QU3Z_1 z180>Mg_;T+xbUtnZx%)`EZoj`_7rd6yU8sr?hgRu CaWo77 literal 3675 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 Date: Tue, 15 Sep 2026 12:03:13 +0200 Subject: [PATCH 4/9] perf: back the Imagick coder-pinning temp file with tmpfs instead of disk (OC10-164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getResizedPreview()'s coder pin needs a real file path for Imagick to read from, but that file is written, read, and deleted again within the same function call - it never needs to survive on disk at all, so writing it there on every single bitmap/vector preview is unnecessary I/O. Add TempManager::getRamTemporaryFile(), which prefers a tmpfs mount (/dev/shm by default, configurable via the new 'ramtempdirectory' system config key) and falls back transparently to the regular disk-backed temporary directory if none is available or a specific write to it fails. Bitmap::getResizedPreview() now sources its pin file from this method instead of the disk-backed getTemporaryFile(). Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- config/config.sample.php | 18 +++++++++ lib/private/Preview/Bitmap.php | 6 ++- lib/private/TempManager.php | 68 ++++++++++++++++++++++++++++++++++ tests/lib/TempManagerTest.php | 50 +++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 1 deletion(-) diff --git a/config/config.sample.php b/config/config.sample.php index 7427d763d8ab..fb924b6ff37d 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1443,6 +1443,24 @@ */ 'tempdirectory' => '/tmp/owncloudtemp', +/** + * Define the location for RAM-backed (tmpfs) temporary files + * Used for a small number of short-lived, write-then-immediately-read + * scratch files (currently just bitmap/vector preview generation), to avoid + * unnecessary disk I/O for content that is read back within milliseconds of + * being written. + * + * Auto-detects /dev/shm by default and silently falls back to the regular + * 'tempdirectory' location above if no writable tmpfs mount is found, or if + * a specific write to it fails (e.g. the mount's own size limit is hit under + * concurrent load) - this is always a best-effort optimization, never a hard + * requirement. + * + * Set to a path to use a different tmpfs mount than /dev/shm. Set to false + * to disable RAM-backed temporary files entirely. + */ +'ramtempdirectory' => '/dev/shm', + /** * Define the hashing cost * The hashing cost used by hashes generated by ownCloud. diff --git a/lib/private/Preview/Bitmap.php b/lib/private/Preview/Bitmap.php index ad6f11f97d5c..f75e534f196f 100644 --- a/lib/private/Preview/Bitmap.php +++ b/lib/private/Preview/Bitmap.php @@ -108,7 +108,11 @@ private function getResizedPreview($stream, int $maxX, int $maxY, string $mimeTy # (PDF, EPS, AI, PSD, SGI, TIFF, HEIC, HEIF - i.e. all of them) it also silently # skips the actual rasterization step, so setImageFormat('png') below ends up # with no effect and getImageBlob() returns the original, undecoded bytes. - $tmpPath = \OC::$server->getTempManager()->getTemporaryFile(); + # + # Uses a RAM-backed (tmpfs) temp file rather than the regular disk-backed one: + # this write-then-immediately-read-then-delete file exists purely to give + # Imagick a path to pin against and never needs to survive on disk. + $tmpPath = \OC::$server->getTempManager()->getRamTemporaryFile(); \file_put_contents($tmpPath, $content); try { $bp->readImage($this->getImagickFormat($mimeType) . ':' . $tmpPath); diff --git a/lib/private/TempManager.php b/lib/private/TempManager.php index cfa5ae9b6006..8fa9c00b1b01 100644 --- a/lib/private/TempManager.php +++ b/lib/private/TempManager.php @@ -40,6 +40,9 @@ class TempManager implements ITempManager { protected array $current = []; /** @var ?string i.e. /tmp on linux systems */ protected ?string $tmpBaseDir = null; + /** @var ?string tmpfs-backed directory to use for getRamTemporaryFile(), resolved lazily */ + protected ?string $ramBaseDir = null; + protected bool $ramBaseDirChecked = false; protected ILogger $logger; protected IConfig $config; @@ -144,6 +147,71 @@ public function getTemporaryFolder($postFix = '') { return false; } + /** + * Create a temporary file backed by a tmpfs/RAM-backed mount when one is + * available and writable, falling back transparently to the regular + * disk-backed temporary directory otherwise. Internal-only optimization + * for callers that write-then-immediately-read short-lived scratch + * content and want to avoid real disk I/O for it - deliberately not part + * of the public ITempManager contract, matching overrideTempBaseDir()'s + * existing precedent for a TempManager-only extra. + * + * @param string $postFix Postfix appended to the temporary file name + * @return string|false Same failure contract as getTemporaryFile(): + * false only if even the disk-backed fallback fails. + */ + public function getRamTemporaryFile($postFix = '') { + $ramBaseDir = $this->resolveRamBaseDir(); + if ($ramBaseDir !== null) { + $file = @\tempnam($ramBaseDir, self::TMP_PREFIX); + if ($file !== false) { + $this->current[] = $file; + + if ($postFix !== '') { + $fileNameWithPostfix = $this->buildFileNameWithSuffix($file, $postFix); + $old_umask = \umask(0077); + \touch($fileNameWithPostfix); + \umask($old_umask); + $this->current[] = $fileNameWithPostfix; + return $fileNameWithPostfix; + } + + return $file; + } + + $this->logger->debug( + 'Could not create a RAM-backed temporary file in {dir}, falling back to disk', + ['dir' => $ramBaseDir] + ); + } + + return $this->getTemporaryFile($postFix); + } + + /** + * Resolve and cache the tmpfs-backed directory to use for + * getRamTemporaryFile(), or null if none is available/enabled. + * + * @return ?string + */ + private function resolveRamBaseDir(): ?string { + if ($this->ramBaseDirChecked) { + return $this->ramBaseDir; + } + $this->ramBaseDirChecked = true; + + $configured = $this->config->getSystemValue('ramtempdirectory', null); + if ($configured === false) { + return $this->ramBaseDir = null; + } + $candidate = \is_string($configured) && $configured !== '' ? $configured : '/dev/shm'; + + if (\is_dir($candidate) && \is_writable($candidate)) { + return $this->ramBaseDir = $candidate; + } + return $this->ramBaseDir = null; + } + /** * Remove the temporary files and folders generated during this request */ diff --git a/tests/lib/TempManagerTest.php b/tests/lib/TempManagerTest.php index 3280a552402a..8c973a1ae6ef 100644 --- a/tests/lib/TempManagerTest.php +++ b/tests/lib/TempManagerTest.php @@ -194,6 +194,56 @@ public function testBuildFileNameWithSuffixPathTraversal(): void { $this->assertStringEndsWith('.Traversal..FileName', $tmpManager); } + public function testGetRamTemporaryFileUsesConfiguredRamDirWhenWritable(): void { + $ramDir = $this->baseDir . '/ram'; + \mkdir($ramDir); + $config = $this->createMock(IConfig::class); + $config->method('getSystemValue') + ->willReturnMap([ + ['tempdirectory', null, '/tmp'], + ['ramtempdirectory', null, $ramDir], + ]); + $manager = $this->getManager(null, $config); + + $file = $manager->getRamTemporaryFile('txt'); + + $this->assertStringEndsWith('.txt', $file); + $this->assertStringStartsWith($ramDir, $file); + $this->assertTrue(\is_file($file)); + } + + public function testGetRamTemporaryFileFallsBackToDiskWhenRamDirMissing(): void { + $config = $this->createMock(IConfig::class); + $config->method('getSystemValue') + ->willReturnMap([ + ['tempdirectory', null, '/tmp'], + ['ramtempdirectory', null, '/nonexistent-ram-dir-for-testing'], + ]); + $manager = $this->getManager(null, $config); + + $file = $manager->getRamTemporaryFile('txt'); + + $this->assertStringEndsWith('.txt', $file); + $this->assertStringStartsWith($this->baseDir, $file); + $this->assertTrue(\is_file($file)); + } + + public function testGetRamTemporaryFileDisabledByExplicitFalse(): void { + $config = $this->createMock(IConfig::class); + $config->method('getSystemValue') + ->willReturnMap([ + ['tempdirectory', null, '/tmp'], + ['ramtempdirectory', null, false], + ]); + $manager = $this->getManager(null, $config); + + $file = $manager->getRamTemporaryFile('txt'); + + $this->assertStringEndsWith('.txt', $file); + $this->assertStringStartsWith($this->baseDir, $file); + $this->assertTrue(\is_file($file)); + } + public function testGetTempBaseDirFromConfig(): void { $dir = $this->getManager()->getTemporaryFolder(); From c71562c15dd03ed00089282aba8cde67b785ea57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Tue, 15 Sep 2026 12:03:32 +0200 Subject: [PATCH 5/9] docs: mention the tmpfs-backed coder-pinning temp file in the OC10-164 changelog entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- changelog/unreleased/41832 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog/unreleased/41832 b/changelog/unreleased/41832 index 9ddb3d5b0a16..d3678efb27b0 100644 --- a/changelog/unreleased/41832 +++ b/changelog/unreleased/41832 @@ -9,6 +9,8 @@ still reach the Ghostscript delegate through any other bitmap provider (SGI, Font, Illustrator, Photoshop, TIFF, Heic). Each provider now pins the exact Imagick coder it expects instead of letting -ImageMagick guess from the file's content. +ImageMagick guess from the file's content, using a tmpfs-backed temporary +file (falling back to disk if none is available) so the pin adds no disk +I/O to preview generation. https://github.com/owncloud/core/pull/41832 From 34769f52851ec457ff87e913119e1c8678742d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Tue, 15 Sep 2026 12:58:39 +0200 Subject: [PATCH 6/9] fix: declare getRamTemporaryFile() on the public ITempManager interface (OC10-164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bitmap::getResizedPreview() calls it through \OC::$server->getTempManager(), which is typed to the ITempManager interface, not the concrete TempManager class - so Phan correctly flagged it as an undeclared method. Unlike overrideTempBaseDir(), which is only ever called on a concrete-typed test variable, this method is used from real production code and needs to be part of the actual contract. ITempManager has exactly one implementer (\OC\TempManager), so adding a method to it is safe. Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- lib/private/TempManager.php | 8 +++----- lib/public/ITempManager.php | 13 +++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/private/TempManager.php b/lib/private/TempManager.php index 8fa9c00b1b01..2ad4e05c6b1e 100644 --- a/lib/private/TempManager.php +++ b/lib/private/TempManager.php @@ -150,11 +150,9 @@ public function getTemporaryFolder($postFix = '') { /** * Create a temporary file backed by a tmpfs/RAM-backed mount when one is * available and writable, falling back transparently to the regular - * disk-backed temporary directory otherwise. Internal-only optimization - * for callers that write-then-immediately-read short-lived scratch - * content and want to avoid real disk I/O for it - deliberately not part - * of the public ITempManager contract, matching overrideTempBaseDir()'s - * existing precedent for a TempManager-only extra. + * disk-backed temporary directory otherwise. Intended for callers that + * write-then-immediately-read short-lived scratch content and want to + * avoid real disk I/O for it. * * @param string $postFix Postfix appended to the temporary file name * @return string|false Same failure contract as getTemporaryFile(): diff --git a/lib/public/ITempManager.php b/lib/public/ITempManager.php index 29633806018c..08f38ad1d64f 100644 --- a/lib/public/ITempManager.php +++ b/lib/public/ITempManager.php @@ -67,4 +67,17 @@ public function cleanOld(); * @since 8.2.0 */ public function getTempBaseDir(); + + /** + * Create a temporary file backed by a tmpfs/RAM-backed mount when one is + * available and writable, falling back transparently to the regular + * disk-backed temporary directory otherwise. Intended for callers that + * write-then-immediately-read short-lived scratch content and want to + * avoid real disk I/O for it. + * + * @param string $postFix + * @return string|false + * @since 11.0.0 + */ + public function getRamTemporaryFile($postFix = ''); } From 029cf084eac65ed50b5015e299aa70adef51cb70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Tue, 15 Sep 2026 15:55:53 +0200 Subject: [PATCH 7/9] refactor: add native type declarations to TempManager::getRamTemporaryFile() (OC10-164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minimum PHP for this codebase is 8.3, so this newly-added method can state its string $postFix / string|false return contract with real declarations instead of relying purely on the docblock. Also correct the @since tag to 11.0.1 - 11.0.0 has already shipped. Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- lib/private/TempManager.php | 7 +++---- lib/public/ITempManager.php | 6 ++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/private/TempManager.php b/lib/private/TempManager.php index 2ad4e05c6b1e..13e13c902c24 100644 --- a/lib/private/TempManager.php +++ b/lib/private/TempManager.php @@ -154,11 +154,10 @@ public function getTemporaryFolder($postFix = '') { * write-then-immediately-read short-lived scratch content and want to * avoid real disk I/O for it. * - * @param string $postFix Postfix appended to the temporary file name - * @return string|false Same failure contract as getTemporaryFile(): - * false only if even the disk-backed fallback fails. + * Same failure contract as getTemporaryFile(): returns false only if + * even the disk-backed fallback fails. */ - public function getRamTemporaryFile($postFix = '') { + public function getRamTemporaryFile(string $postFix = ''): string|false { $ramBaseDir = $this->resolveRamBaseDir(); if ($ramBaseDir !== null) { $file = @\tempnam($ramBaseDir, self::TMP_PREFIX); diff --git a/lib/public/ITempManager.php b/lib/public/ITempManager.php index 08f38ad1d64f..61d71164de37 100644 --- a/lib/public/ITempManager.php +++ b/lib/public/ITempManager.php @@ -75,9 +75,7 @@ public function getTempBaseDir(); * write-then-immediately-read short-lived scratch content and want to * avoid real disk I/O for it. * - * @param string $postFix - * @return string|false - * @since 11.0.0 + * @since 11.0.1 */ - public function getRamTemporaryFile($postFix = ''); + public function getRamTemporaryFile(string $postFix = ''): string|false; } From 3f5fe59ce88b47e5295c9b9ef8ee84774b917bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Tue, 15 Sep 2026 16:03:41 +0200 Subject: [PATCH 8/9] fix: back the SVG coder-pin temp file with tmpfs too (OC10-164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SVG provider's coder pin used the disk-backed getTemporaryFile(), while Bitmap.php uses getRamTemporaryFile() for the identical write-read-unlink file. Before the pin was introduced the SVG path was a pure in-memory readImageBlob(), so as it stood this added a real disk write, read and unlink to every SVG preview - contradicting the changelog entry's claim that the pin adds no disk I/O to preview generation. Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- lib/private/Preview/SVG.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/private/Preview/SVG.php b/lib/private/Preview/SVG.php index f750de84e34d..343842897e99 100644 --- a/lib/private/Preview/SVG.php +++ b/lib/private/Preview/SVG.php @@ -63,7 +63,11 @@ public function getThumbnail(File $file, $maxX, $maxY, $scalingUp) { # options above and of the isDangerousToDecode()-style reasoning in Bitmap.php. # This has to be a "SVG:path" read, not setFormat()+readImageBlob(): the latter # silently skips the actual rasterization step, same as in Bitmap.php. - $tmpPath = \OC::$server->getTempManager()->getTemporaryFile(); + # + # RAM-backed like Bitmap.php's pin file: it is written, read and deleted again + # within this one call and exists purely to give Imagick a path to pin against, + # so it never needs to survive on disk. + $tmpPath = \OC::$server->getTempManager()->getRamTemporaryFile(); \file_put_contents($tmpPath, $output); try { $imagick->readImage('SVG:' . $tmpPath); From 374b0ced836957ba8c3029f4d923036d8a454916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Tue, 15 Sep 2026 16:03:48 +0200 Subject: [PATCH 9/9] docs: only promise the ramtempdirectory fallback that is implemented (OC10-164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getRamTemporaryFile() falls back to the disk-backed directory when no writable tmpfs mount is found or when the temp file cannot be created there. It does not fall back when a later write to an already-created file fails, so drop that claim from the config documentation. Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- config/config.sample.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index fb924b6ff37d..18975d01f6fe 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1452,9 +1452,8 @@ * * Auto-detects /dev/shm by default and silently falls back to the regular * 'tempdirectory' location above if no writable tmpfs mount is found, or if - * a specific write to it fails (e.g. the mount's own size limit is hit under - * concurrent load) - this is always a best-effort optimization, never a hard - * requirement. + * the temporary file cannot be created there - this is always a best-effort + * optimization, never a hard requirement. * * Set to a path to use a different tmpfs mount than /dev/shm. Set to false * to disable RAM-backed temporary files entirely.