From 93accbd51d43f3af7a0cacb7d5ee1a2075ae78c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20B=C3=BCrk?= <stefan@buerk.tech>
Date: Fri, 14 Apr 2023 23:54:18 +0200
Subject: [PATCH] [BUGFIX] Mitigate incorrect libxml usage of
 "enshrined/svg-sanitize"

External "enshrined/svg-sanitize" package uses
`libxml_use_internal_errors()`, but fails to
clear errors using libxml_clear_errors().

This can lead to side effects with subsequest
libxml usages.

An upstream patch to fix this is pending,
but it needs to be merged and released.

In the meantime, we mitigate the issue in
our wrapper class.

See: https://github.com/darylldoyle/svg-sanitizer/pull/90

Resolves: #100607
Releases: main, 11.5
Change-Id: I911119b498a4dda8312c5ca940b5fdf6410a1a87
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/78648
Tested-by: core-ci <typo3@b13.com>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
---
 .../Classes/Resource/Security/SvgSanitizer.php     |  7 ++++++-
 .../Resource/Security/SvgSanitizerTest.php         | 14 +++++++-------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/typo3/sysext/core/Classes/Resource/Security/SvgSanitizer.php b/typo3/sysext/core/Classes/Resource/Security/SvgSanitizer.php
index 373ade783bf1..3cabcdbff524 100644
--- a/typo3/sysext/core/Classes/Resource/Security/SvgSanitizer.php
+++ b/typo3/sysext/core/Classes/Resource/Security/SvgSanitizer.php
@@ -49,8 +49,13 @@ class SvgSanitizer
      */
     public function sanitizeContent(string $svg): string
     {
+        // @todo: Simplify again when https://github.com/darylldoyle/svg-sanitizer/pull/90 is merged and released.
+        $previousXmlErrorHandling = libxml_use_internal_errors(true);
         $sanitizer = new Sanitizer();
         $sanitizer->removeRemoteReferences(true);
-        return $sanitizer->sanitize($svg) ?: '';
+        $sanitizedString = $sanitizer->sanitize($svg) ?: '';
+        libxml_clear_errors();
+        libxml_use_internal_errors($previousXmlErrorHandling);
+        return $sanitizedString;
     }
 }
diff --git a/typo3/sysext/core/Tests/Functional/Resource/Security/SvgSanitizerTest.php b/typo3/sysext/core/Tests/Functional/Resource/Security/SvgSanitizerTest.php
index 281e99f8d876..dfb13e26fa41 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/Security/SvgSanitizerTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/Security/SvgSanitizerTest.php
@@ -42,24 +42,24 @@ class SvgSanitizerTest extends FunctionalTestCase
         $data = [];
         foreach ($finder as $file) {
             $fileName = $file->getFilename();
-            $data[$fileName] = ['DirtySVG/' . $fileName, 'CleanSVG/' . $fileName];
+            $data[$fileName] = [
+                $basePath . 'DirtySVG/' . $fileName,
+                $basePath . 'CleanSVG/' . $fileName,
+            ];
         }
         return $data;
     }
 
     /**
-     * @param string $filePath
-     * @param string $sanitizedFilePath
      * @test
      * @dataProvider svgContentIsSanitizedDataProvider
      */
-    public function svgContentIsSanitized($filePath, $sanitizedFilePath): void
+    public function svgContentIsSanitized(string $filePath, string $sanitizedFilePath): void
     {
-        $basePath = dirname(__FILE__, 2) . '/Fixtures/';
         $sanitizer = new SvgSanitizer();
         self::assertStringEqualsFile(
-            $basePath . $sanitizedFilePath,
-            $sanitizer->sanitizeContent(file_get_contents($basePath . $filePath))
+            $sanitizedFilePath,
+            $sanitizer->sanitizeContent(file_get_contents($filePath))
         );
     }
 }
-- 
GitLab