From a4631b92e7d57141954a2373ba33edae1512cb08 Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Wed, 13 Sep 2017 11:56:46 -0700 Subject: [PATCH] Improve encoding of embedded SVGs Unencode spaces, slashes, colons and equals signs. Bug: T175318 Change-Id: Idebdfca8f93d5e090deba5bf5a256d7054e2d6c8 --- includes/libs/CSSMin.php | 10 +++++++++- maintenance/benchmarks/cssmin/circle.svg | 2 +- tests/phpunit/data/cssmin/circle.svg | 2 +- tests/phpunit/includes/libs/CSSMinTest.php | 8 ++++---- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/includes/libs/CSSMin.php b/includes/libs/CSSMin.php index cd80066558..ee88d0d2b5 100644 --- a/includes/libs/CSSMin.php +++ b/includes/libs/CSSMin.php @@ -142,7 +142,15 @@ class CSSMin { if ( preg_match( '/^[\r\n\t\x20-\x7e]+$/', $contents ) ) { // Do not base64-encode non-binary files (sane SVGs). // (This often produces longer URLs, but they compress better, yielding a net smaller size.) - $uri = 'data:' . $type . ',' . rawurlencode( $contents ); + $encoded = rawurlencode( $contents ); + // Unencode some things that don't need to be encoded, to make the encoding smaller + $encoded = strtr( $encoded, [ + '%20' => ' ', // Unencode spaces + '%2F' => '/', // Unencode slashes + '%3A' => ':', // Unencode colons + '%3D' => '=', // Unencode equals signs + ] ); + $uri = 'data:' . $type . ',' . $encoded; if ( !$ie8Compat || strlen( $uri ) < self::DATA_URI_SIZE_LIMIT ) { return $uri; } diff --git a/maintenance/benchmarks/cssmin/circle.svg b/maintenance/benchmarks/cssmin/circle.svg index 6b7d1afd87..4f7af21799 100644 --- a/maintenance/benchmarks/cssmin/circle.svg +++ b/maintenance/benchmarks/cssmin/circle.svg @@ -1,4 +1,4 @@ - + diff --git a/tests/phpunit/data/cssmin/circle.svg b/tests/phpunit/data/cssmin/circle.svg index 6b7d1afd87..4f7af21799 100644 --- a/tests/phpunit/data/cssmin/circle.svg +++ b/tests/phpunit/data/cssmin/circle.svg @@ -1,4 +1,4 @@ - + diff --git a/tests/phpunit/includes/libs/CSSMinTest.php b/tests/phpunit/includes/libs/CSSMinTest.php index 7d9a420c73..b06df97666 100644 --- a/tests/phpunit/includes/libs/CSSMinTest.php +++ b/tests/phpunit/includes/libs/CSSMinTest.php @@ -271,9 +271,9 @@ class CSSMinTest extends MediaWikiTestCase { // data: URIs for red.gif, green.gif, circle.svg $red = 'data:image/gif;base64,R0lGODlhAQABAIAAAP8AADAAACwAAAAAAQABAAACAkQBADs='; $green = 'data:image/gif;base64,R0lGODlhAQABAIAAAACAADAAACwAAAAAAQABAAACAkQBADs='; - $svg = 'data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A' - . '%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228%22%20height%3D' - . '%228%22%3E%0A%3Ccircle%20cx%3D%224%22%20cy%3D%224%22%20r%3D%222%22%2F%3E%0A%3C%2Fsvg%3E%0A'; + $svg = 'data:image/svg+xml,%3C%3Fxml version=%221.0%22 encoding=%22UTF-8%22%3F%3E%0A' + . '%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%228%22 height=' + . '%228%22%3E%0A%09%3Ccircle cx=%224%22 cy=%224%22 r=%222%22/%3E%0A%3C/svg%3E%0A'; // @codingStandardsIgnoreStart Generic.Files.LineLength return [ @@ -361,7 +361,7 @@ class CSSMinTest extends MediaWikiTestCase { [ 'SVG files are embedded without base64 encoding and unnecessary IE 6 and 7 fallback', 'foo { /* @embed */ background: url(circle.svg); }', - "foo { background: url($svg); }", + "foo { background: url(\"$svg\"); }", ], [ 'Two regular files in one rule', -- 2.20.1