From 311b741b0f5b5c059eb3c8c232c7f5847b71d8b9 Mon Sep 17 00:00:00 2001
From: Cerdic <cedric@yterium.com>
Date: Wed, 7 Sep 2022 15:15:55 +0200
Subject: [PATCH] =?UTF-8?q?feat:=20s=C3=A9parer=20la=20fonction=20qui=20sa?=
 =?UTF-8?q?nitize=20le=20source=20du=20SVG=20pour=20pouvoir=20l'utiliser?=
 =?UTF-8?q?=20dans=20un=20autre=20contexte?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Refs: https://git.spip.net/spip/safehtml/issues/4786
---
 sanitizer/svg.php | 103 ++++++++++++++++++++++++++++------------------
 1 file changed, 62 insertions(+), 41 deletions(-)

diff --git a/sanitizer/svg.php b/sanitizer/svg.php
index 13d842a2..d57431b2 100644
--- a/sanitizer/svg.php
+++ b/sanitizer/svg.php
@@ -29,13 +29,21 @@ include_spip('inc/autoriser');
  * cf http://www.slideshare.net/x00mario/the-image-that-called-me
  * http://heideri.ch/svgpurifier/SVGPurifier/index.php
  *
- * @param string $file
- * @return array Tableau (largeur, hauteur)
+ * @param string $file_or_svg
+ * @return bool
  */
-function sanitizer_svg_dist($file) {
+function sanitizer_svg_dist($file_or_svg) {
 
 	include_spip('inc/svg');
-	if ($svg = svg_charger($file)) {
+	if ($svg = svg_charger($file_or_svg)) {
+		if ($svg === $file_or_svg) {
+			$file = false;
+		}
+		else {
+			$file = $file_or_svg;
+		}
+		unset($file_or_svg);
+
 		// forcer une viewBox et width+height en px
 		$svg = svg_force_viewBox_px($svg, true);
 
@@ -46,43 +54,7 @@ function sanitizer_svg_dist($file) {
 			// qu'on soit admin ou non, on sanitize les SVGs car rien ne dit qu'un admin sait que ca contient du JS
 			// and !autoriser('televerser', 'script')
 		) {
-			spip_log("sanitization SVG $file", 'svg');
-
-			if (!class_exists('enshrined\svgSanitize\Sanitizer')) {
-				spl_autoload_register(function ($class) {
-					$prefix = 'enshrined\\svgSanitize\\';
-					$base_dir = _DIR_PLUGIN_MEDIAS . 'lib/svg-sanitizer/src/';
-					$len = strlen($prefix);
-					if (strncmp($prefix, $class, $len) !== 0) {
-						return;
-					}
-					$relative_class = substr($class, $len);
-					$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
-									if (file_exists($file)) {
-						require $file;
-									}
-				});
-			}
-
-			// sanitization can need multiples call
-			$maxiter = 10;
-			do {
-				$size = strlen($svg);
-				$sanitizer = new Sanitizer();
-				$sanitizer->setXMLOptions(0); // garder les balises vide en ecriture raccourcie
-
-				// Pass it to the sanitizer and get it back clean
-				$svg = $sanitizer->sanitize($svg);
-
-				// loger les sanitization
-				$trace = '';
-				foreach ($sanitizer->getXmlIssues() as $issue) {
-					$trace .= $issue['message'] . ' L' . $issue['line'] . "\n";
-				}
-				if ($trace) {
-					spip_log($trace, 'svg' . _LOG_DEBUG);
-				}
-			} while (strlen($svg) !== $size and $maxiter-- > 0);
+			$svg = sanitizer_svg_string($svg, $file);
 		}
 
 		ecrire_fichier($file, $svg);
@@ -93,3 +65,52 @@ function sanitizer_svg_dist($file) {
 	// pas de svg valide
 	return false;
 }
+
+/**
+ * @param string $svg
+ * @param string $fileName
+ * @return false|string
+ */
+function sanitizer_svg_string($svg, $fileName = '') {
+
+	$tracesvg = ($fileName ?: substr($svg, 0,32)."...(".strlen($svg). "c ". md5($svg) . ")");
+	spip_log("sanitization SVG $tracesvg", 'svg' . _LOG_DEBUG);
+
+	if (!class_exists('enshrined\svgSanitize\Sanitizer')) {
+		spl_autoload_register(function ($class) {
+			$prefix = 'enshrined\\svgSanitize\\';
+			$base_dir = _DIR_PLUGIN_MEDIAS . 'lib/svg-sanitizer/src/';
+			$len = strlen($prefix);
+			if (strncmp($prefix, $class, $len) !== 0) {
+				return;
+			}
+			$relative_class = substr($class, $len);
+			$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
+			if (file_exists($file)) {
+				require $file;
+			}
+		});
+	}
+
+	// sanitization can need multiples call
+	$maxiter = 10;
+	do {
+		$size = strlen($svg);
+		$sanitizer = new Sanitizer();
+		$sanitizer->setXMLOptions(0); // garder les balises vide en ecriture raccourcie
+
+		// Pass it to the sanitizer and get it back clean
+		$svg = $sanitizer->sanitize($svg);
+
+		// loger les sanitization
+		$trace = '';
+		foreach ($sanitizer->getXmlIssues() as $issue) {
+			$trace .= $issue['message'] . ' L' . $issue['line'] . "\n";
+		}
+		if ($trace) {
+			spip_log($trace, 'svg' . _LOG_DEBUG);
+		}
+	} while (strlen($svg) !== $size and $maxiter-- > 0);
+
+	return $svg;
+}
-- 
GitLab