From 1aa7eb533b3590e41128acd90a4e8945ab58bf6b Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Fri, 11 Mar 2022 11:39:20 -0700 Subject: [PATCH 1/4] Default to using the viewbox attributes first for SVG dimensions, to maintain backwards compat. Add a new filter that can be used to default to using the height and width attributes first instead --- safe-svg.php | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/safe-svg.php b/safe-svg.php index 7b52e264..a2016f6e 100644 --- a/safe-svg.php +++ b/safe-svg.php @@ -454,7 +454,7 @@ function metadata_error_fix( $data, $post_id ) { /** * Get SVG size from the width/height or viewport. * - * @param $svg + * @param string|false $svg The file path to where the SVG file should be, false otherwise. * * @return array|bool */ @@ -464,16 +464,43 @@ protected function svg_dimensions( $svg ) { $height = 0; if ( $svg ) { $attributes = $svg->attributes(); - if ( isset( $attributes->width, $attributes->height ) && is_numeric( (float)$attributes->width ) && is_numeric( (float)$attributes->height ) ) { - $width = floatval( $attributes->width ); - $height = floatval( $attributes->height ); - } elseif ( isset( $attributes->viewBox ) ) { + + if ( isset( $attributes->viewBox ) ) { $sizes = explode( ' ', $attributes->viewBox ); if ( isset( $sizes[2], $sizes[3] ) ) { - $width = floatval( $sizes[2] ); - $height = floatval( $sizes[3] ); + $viewbox_width = floatval( $sizes[2] ); + $viewbox_height = floatval( $sizes[3] ); } + } + + if ( isset( $attributes->width, $attributes->height ) && is_numeric( (float) $attributes->width ) && is_numeric( (float) $attributes->height ) ) { + $attr_width = floatval( $attributes->width ); + $attr_height = floatval( $attributes->height ); + } + + /** + * Use the width and height attributes of the SVG for the image tag dimensions. + * + * We default to using the parameters in the viewbox attribute but + * that can be overridden using this filter if you'd prefer to use + * the width and height attributes. + * + * @hook safe_svg_use_width_height_attributes + * + * @param bool $false If the width & height attributes should be used first. Default false. + * @param string $svg The file path to the SVG. + * + * @return bool If we should use the width & height attributes first or not. + */ + if ( (bool) apply_filters( 'safe_svg_use_width_height_attributes', false, $svg ) ) { + $width = $attr_width; + $height = $attr_height; } else { + $width = $viewbox_width; + $height = $viewbox_height; + } + + if ( ! $width && ! $height ) { return false; } } From be5d788cd4de4a1dca3f89509e3aa36bc416ad42 Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Fri, 11 Mar 2022 12:36:00 -0700 Subject: [PATCH 2/4] Update docblock --- safe-svg.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/safe-svg.php b/safe-svg.php index a2016f6e..4c153753 100644 --- a/safe-svg.php +++ b/safe-svg.php @@ -479,7 +479,7 @@ protected function svg_dimensions( $svg ) { } /** - * Use the width and height attributes of the SVG for the image tag dimensions. + * Decide which attributes of the SVG we use first for image tag dimensions. * * We default to using the parameters in the viewbox attribute but * that can be overridden using this filter if you'd prefer to use From 50371a62315c1d669baaac001eba20d078c49fdc Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Fri, 11 Mar 2022 13:23:27 -0700 Subject: [PATCH 3/4] Ensure we don't use the height and width attributes if they are a percenta --- safe-svg.php | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/safe-svg.php b/safe-svg.php index 4c153753..a0c60fdb 100644 --- a/safe-svg.php +++ b/safe-svg.php @@ -473,7 +473,7 @@ protected function svg_dimensions( $svg ) { } } - if ( isset( $attributes->width, $attributes->height ) && is_numeric( (float) $attributes->width ) && is_numeric( (float) $attributes->height ) ) { + if ( isset( $attributes->width, $attributes->height ) && is_numeric( (float) $attributes->width ) && is_numeric( (float) $attributes->height ) && ! $this->str_ends_with( (string) $attributes->width, '%' ) && ! $this->str_ends_with( (string) $attributes->height, '%' ) ) { $attr_width = floatval( $attributes->width ); $attr_height = floatval( $attributes->height ); } @@ -546,6 +546,30 @@ public function fix_direct_image_output( $attr, $attachment, $size = 'thumbnail' return $attr; } + + /** + * Polyfill for `str_ends_with()` function added in PHP 8.0. + * + * Performs a case-sensitive check indicating if + * the haystack ends with needle. + * + * @param string $haystack The string to search in. + * @param string $needle The substring to search for in the `$haystack`. + * @return bool True if `$haystack` ends with `$needle`, otherwise false. + */ + protected function str_ends_with( $haystack, $needle ) { + if ( function_exists( 'str_ends_with' ) ) { + return str_ends_with( $haystack, $needle ); + } + + if ( '' === $haystack && '' !== $needle ) { + return false; + } + + $len = strlen( $needle ); + return 0 === substr_compare( $haystack, $needle, -$len, $len ); + } + } } From b44ce7be6c14f377008400c7aacec2da573b9591 Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Wed, 16 Mar 2022 09:23:26 -0600 Subject: [PATCH 4/4] Update safe-svg.php Co-authored-by: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> --- safe-svg.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/safe-svg.php b/safe-svg.php index a0c60fdb..d6445411 100644 --- a/safe-svg.php +++ b/safe-svg.php @@ -487,10 +487,10 @@ protected function svg_dimensions( $svg ) { * * @hook safe_svg_use_width_height_attributes * - * @param bool $false If the width & height attributes should be used first. Default false. - * @param string $svg The file path to the SVG. + * @param {bool} $false If the width & height attributes should be used first. Default false. + * @param {string} $svg The file path to the SVG. * - * @return bool If we should use the width & height attributes first or not. + * @return {bool} If we should use the width & height attributes first or not. */ if ( (bool) apply_filters( 'safe_svg_use_width_height_attributes', false, $svg ) ) { $width = $attr_width;