From: Brian Sweeney <bsweeney@aaas.org>
Date: Wed, 31 Jan 2024 09:55:55 -0500
Subject: Update resource validation logic

The previous logic did not validate the font-family when set by attribute. To accommodate style validation across all sources the Style class now accepts the Document during construction so that it has access to the allowExternalReferences property regardless of style source.

Origin: upstream
Fixes: CVE-2024-25117
Bug-Debian: https://bugs.debian.org/1064781
---
 src/Svg/Document.php        |  2 +-
 src/Svg/Style.php           | 27 +++++++++++++++++----------
 src/Svg/Tag/AbstractTag.php |  2 +-
 src/Svg/Tag/Image.php       |  6 +++++-
 4 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/src/Svg/Document.php b/src/Svg/Document.php
index 309875b..990cfde 100644
--- a/src/Svg/Document.php
+++ b/src/Svg/Document.php
@@ -202,7 +202,7 @@ class Document extends AbstractTag
     {
         $surface = $this->getSurface();
 
-        $style = new DefaultStyle();
+        $style = new DefaultStyle($this);
         $style->inherit($this);
         $style->fromAttributes($attributes);
 
diff --git a/src/Svg/Style.php b/src/Svg/Style.php
index 514f546..9fac469 100644
--- a/src/Svg/Style.php
+++ b/src/Svg/Style.php
@@ -18,6 +18,7 @@ class Style
     const TYPE_ANGLE = 4;
     const TYPE_NUMBER = 5;
 
+    private $_document;
     private $_parentStyle;
 
     public $color;
@@ -43,6 +44,12 @@ class Style
     public $fontStyle = 'normal';
     public $textAnchor = 'start';
 
+    public function __construct($document = null) {
+        if ($document !== null) {
+            $this->_document = $document;
+        }
+    }
+
     protected function getStyleMap()
     {
         return array(
@@ -139,16 +146,6 @@ class Style
                         break;
                     }
                 }
-
-                if (
-                    \array_key_exists("font-family", $styles)
-                    && (
-                        \strtolower(\substr($this->href, 0, 7)) === "phar://"
-                        || ($this->document->allowExternalReferences === false && \strtolower(\substr($this->href, 0, 5)) !== "data:")
-                    )
-                ) {
-                    unset($style["font-family"]);
-                }
             }
         }
 
@@ -185,6 +182,16 @@ class Style
                         $value = $styles[$from];
                 }
 
+                if ($from === "font-family") {
+                    $scheme = \strtolower(parse_url($value, PHP_URL_SCHEME) ?: "");
+                    if (
+                        $scheme === "phar" || \strtolower(\substr($value, 0, 7)) === "phar://"
+                        || ($this->_document !== null && $this->_document->allowExternalReferences === false && $scheme !== "data")
+                    ) {
+                        continue;
+                    }
+                }
+
                 if ($value !== null) {
                     $this->$to = $value;
                 }
diff --git a/src/Svg/Tag/AbstractTag.php b/src/Svg/Tag/AbstractTag.php
index 9fa6793..e368aab 100644
--- a/src/Svg/Tag/AbstractTag.php
+++ b/src/Svg/Tag/AbstractTag.php
@@ -119,7 +119,7 @@ abstract class AbstractTag
      * @return Style
      */
     protected function makeStyle($attributes) {
-        $style = new Style();
+        $style = new Style($this->document);
         $style->inherit($this);
         $style->fromStyleSheets($this, $attributes);
         $style->fromAttributes($attributes);
diff --git a/src/Svg/Tag/Image.php b/src/Svg/Tag/Image.php
index 8cbfccd..de397c4 100644
--- a/src/Svg/Tag/Image.php
+++ b/src/Svg/Tag/Image.php
@@ -58,7 +58,11 @@ class Image extends AbstractTag
 
         $this->document->getSurface()->transform(1, 0, 0, -1, 0, $height);
 
-        if (\strtolower(\substr($this->href, 0, 7)) === "phar://" || ($this->document->allowExternalReferences === false && \strtolower(\substr($this->href, 0, 5) !== "data:"))) {
+        $scheme = \strtolower(parse_url($this->href, PHP_URL_SCHEME) ?: "");
+        if (
+            $scheme === "phar" || \strtolower(\substr($this->href, 0, 7)) === "phar://"
+            || ($this->document->allowExternalReferences === false && $scheme !== "data")
+        ) {
             return;
         }
 
