diff --git a/lib/public/Collaboration/Reference/LinkReferenceProvider.php b/lib/public/Collaboration/Reference/LinkReferenceProvider.php index 2dd1e5f5b1e52..5dc71b329142a 100644 --- a/lib/public/Collaboration/Reference/LinkReferenceProvider.php +++ b/lib/public/Collaboration/Reference/LinkReferenceProvider.php @@ -193,7 +193,7 @@ private function fetchReference(Reference $reference): void { $bodyStream = new LimitStream($stream, self::MAX_CONTENT_LENGTH, 0); $content = $bodyStream->getContents(); - if ($contentType === 'image/svg+xml' && stripos(html_entity_decode($content, ENT_XML1), 'XSL/Transform') !== false) { + if ($contentType === 'image/svg+xml' && $this->containsXslt($content)) { return; } @@ -230,4 +230,30 @@ public function getCacheKey(string $referenceId): ?string { public function getCacheKeyPublic(string $referenceId, string $sharingToken): ?string { return null; } + + /** + * Check if XML content contains XSLT transformations + * + * XSLT transformations in SVG files can cause memory exhaustion + * in Chromium based browsers when rendered. + */ + private function containsXslt(string $xmlContent): bool { + set_error_handler(function (int $code, string $message): bool { + $this->logger->debug('Failed to parse XML content for XSLT check', ['error' => $message]); + return true; + }); + + $xml = simplexml_load_string($xmlContent); + + restore_error_handler(); + + $namespaces = $xml ? $xml->getNamespaces(true) : []; + foreach ($namespaces as $namespace) { + if (stripos($namespace, 'XSL/Transform') !== false) { + return true; + } + } + + return false; + } }