When processing:
url( 'foo.svg#anchors' )
getLocalFileReferences() would yield a file 'foo.svg#anchors'. It might
occur with upstream libraries, such as WikiFonts used by the Refreshed
skin.
When a path is found, strip the anchor entirely. Skip the case if that
results in an empty file.
remap() would properly skip the behavior "#default#', also skip url that
are solely an anchor such as '#other'.
Add a few test cases to cover CSSMin::getLocalFileReferences and cover
anchors usage in CSSMin::remap.
Bug: T115436
Change-Id: I1749ddc2b89021807f42d64131931ad7a99a7b43
In cases where we're operating on text data (and not binary data),
use e.g. "\u{00A0}" to refer directly to the Unicode character
'NO-BREAK SPACE' instead of "\xc2\xa0" to specify the bytes C2h A0h
(which correspond to the UTF-8 encoding of that character). This
makes it easier to look up those mysterious sequences, as not all
are as recognizable as the no-break space.
This is not enforced by PHP, but I think we should write those in
uppercase and zero-padded to at least four characters, like the
Unicode standard does.
Note that not all "\xNN" escapes can be automatically replaced:
* We can't use Unicode escapes for binary data that is not UTF-8
(e.g. in code converting from legacy encodings or testing the
handling of invalid UTF-8 byte sequences).
* '\xNN' escapes in regular expressions in single-quoted strings
are actually handled by PCRE and have to be dealt with carefully
(those regexps should probably be changed to use the /u modifier).
* "\xNN" referring to ASCII characters ("\x7F" and lower) should
probably be left as-is.
The replacements in this commit were done semi-manually by piping
the existing "\xNN" escapes through the following terrible Ruby
script I devised:
chars = eval('"' + ARGV[0] + '"').force_encoding('utf-8')
puts chars.split('').map{|char|
'\\u{' + char.ord.to_s(16).upcase.rjust(4, '0') + '}'
}.join('')
Change-Id: Idc3dee3a7fb5ebfaef395754d8859b18f1f8769a
This is called relatively often. Even small improvements might have an
impact.
I'm intentionally replacing method_exists with class_exists because the
old check looked like it was done for backwards compatibility (MediaWiki
before 1.27 did not contained the method), while in reality this code is
meant to run without MediaWiki. This is much better reflected with a
straight "if this class doesn't exist, there is no MediaWiki".
I'm intentionally using the …::class feature. Yes, this works, even if the
class is not there.
Change-Id: I7f250a7cb000105bb751f68f25c6cc1c44c8f221
The current editors draft from 23 April 2018 does not require to escape
the REPLACEMENT CHARACTER (U+FFFD) as code point anymore.
https://drafts.csswg.org/cssom/#serialize-a-string
If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
(U+FFFD).
https://www.w3.org/TR/2016/WD-cssom-1-20160317/#serialize-a-string
If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
(U+FFFD) escaped as code point.
Change-Id: Ia67e89b3c9561ca29e133d61a2eca8f3db306d8c
* Consistently name data providers as "provide.." and make them
static.
* Document why wgServer is being mocked.
* Use TestingAccessWrapper instead of ad-hoc sub class for
accessing protected methods.
Change-Id: Ife2d98091200bbc8fb16b7ac6eafd3f2c22c1463
The empty string being matched causes an undefined array index
notice in production, seen from various random gadgets, but spiked
after a change in MonoBook from last week that introduced a
broken background-image rule with empty string as url.
In browsers, that is actually interpreted as valid and "expands"
to the current url and re-fetches as Accept:image/*, silly, but
still broken. The broken icon was fixed in MonoBook, but we still
need to avoid trying to remap empty string as url.
Two changes:
1. Fix regex used by remap() to not match empty string.
This was already fixed for the 'url()' case without the
optional quotes, but with quotes, it was being matched as
non-empty. This is now fixed by using '+' instead of '*'.
Added tests to confirm they produce output, and PHPUnit
is configured to also assert no Notices are emitted (which
it converts to fatal exceptions).
2. Fix processUrlMatch() as sanity check to throw if the key
is missing.
Bug: T191237
Change-Id: I0ada337b0b4ab73c80236367ff79c31bcd13aa7d
* Trim whitespaces after opening and before closing parentheses and
brackets.
* Ensure by test case that the invalid "url (" will not become the
valid "url(" by minification.
This change also prevents the parsing problem in Firefox 57.0
https://bugzilla.mozilla.org/1418152 which is fixed in Firefox 57.0.1.
Change-Id: I804477ba7c6363f0e964fc8c7c0bc74d2d4c1a0d
Removing unnecessary XML declaration prolog when embedding SVGs
as data URI and adding more complex elements & attributes to test.
Bug: T175318
Change-Id: Ibec8c2ab498554a6ad33b4420ae6258dcc80fcdf
Convert newlines and tabs to spaces (which can be unencoded),
and consolidate runs of multiple spaces into a single space.
Also remove any leading and trailing spaces that might result
(most files end in a newline, for example).
Follow-up to Iddc98332d. This was reverted as dependency for the
original issues causing patch, but works perfectly fine.
Bug: T175318
Change-Id: Ic25d73caeb42ba7a32ef304806d401047b5a1997
Clean up use of @codingStandardsIgnore
- @codingStandardsIgnoreFile -> phpcs:ignoreFile
- @codingStandardsIgnoreLine -> phpcs:ignore
- @codingStandardsIgnoreStart -> phpcs:disable
- @codingStandardsIgnoreEnd -> phpcs:enable
For phpcs:disable always the necessary sniffs are provided.
Some start/end pairs are changed to line ignore
Change-Id: I92ef235849bcc349c69e53504e664a155dd162c8
Convert newlines and tabs to spaces (which can be unencoded),
and consolidate runs of multiple spaces into a single space.
Also remove any leading and trailing spaces that might result
(most files end in a newline, for example).
Bug: T175318
Change-Id: Ic66c6acb37079cae84dd80ab2d5f2c829cf2df96
When a URL (data: or otherwise) contains quotes, don't wrap it in
double quotes (") but in single quotes ('). This then allows
us to unencode double quotes (") in the data URI embedding of SVGs.
Bug: T175318
Change-Id: I3e7eab64e1c3e82066014fb594f82d786983ce90
Previously they were often being cut short due to the url pattern
ending at the first single quote, double quote or closing parenthesis
regardless of which of those started the url match.
Running benchmarkCSSMin.php before and after the change doesn't seem
produce consistent improvement or regression. Repeated runs with count=100
with and without this change both have a median between 2.6ms and 2.9ms
using PHP 5.6, and between 2.6ms and 2.8ms using HHVM 3.12.
Bug: T60473
Change-Id: I6d6a077ad76588f3ed81b1901a26b7e56d2157ee
Direct follow up for I1768646. The tests are copied from my patch
If985f33, with one important difference: Now the file extension always
wins. Mismatches are not fixed any more by this code. This is intended.
See the discussion at I1768646.
Change-Id: I06b873a808d58ae7e53272765b156ac0fa293c2c
It's unreasonable to expect newbies to know that "bug 12345" means "Task T14345"
except where it doesn't, so let's just standardise on the real numbers.
Change-Id: I46261416f7603558dceb76ebe695a5cac274e417
The check for file existence before checking its MIME type was
building the path incorrectly, causing this piece of code to always
think the file does not exist. (The code to actually embed the file
was correct.)
This was not caught by the tests before of a bug in the test code,
which cancelled out this one.
Bug: T100958
Change-Id: I4469079f41d48052d0a02f98bb1ed02407abd54c
The content of these files is more stable than their mtimes, which change
every time we roll out a new branch. Because MD5 avalanches well[0], using
the first five hexadecimal digits is sufficient to ensure that the chance
of two successive versions colliding is improbably small (roughly one in a
million).
[0]: https://en.wikipedia.org/wiki/Avalanche_effect
Change-Id: I1bdf94c58786d2545311b238476b48217a5a60af
Call wfRemoveDotSegments() (if available) on relative local URLs, so that
relative dot segments are collapsed.
Change-Id: Icc1c23a2a7d96c869412965bd8c3730d3c3b3a53
Do not base64-encode non-binary files (containing only whitespace and
printable ASCII characters, which matches sane SVG files).
For SVG files the percent-encoded URIs are actually slightly longer
than the base64-encoded ones (~10%), but compress a lot better
resulting on 15-20% less data to transfer after gzip compression.
(The effect is best seen on the 'oojs-ui' module, which consists
mostly of SVG icons – especially after commenting out everything other
than 'oojs-ui.svg.css'.)
I tried this for binary files too, just in case; but as expected, they
suffer from a noticeable size increase even with compression (~15%).
Bug: 67341
Change-Id: Iddaf863b6be98570a2bb8e606f13946a96345f65
This reverts most of commit 2d842f1425,
leaving only the test added in it, and reimplements the same
functionality better.
Instead of stripping /*@noflip*/ annotations in CSSJanus, which is
incompatible with other implementations that preserve it, extend
CSSMin to allow other CSS comments to be present before the
rule-global @embed annotation. (This required making the regex logic
in it even worse than it was, but it's actually slightly less terrible
than I expected it would be. Good thing we have tests!)
Bug: 69698
Change-Id: I58603ef64f7d7cdc6461b34721a4d6b15f15ad79
Remapping of url()s was thrown off if the CSS contained comments
with curly braces. To fix, replace all block comments (except @embed
directives) with placeholders before url() processing and swap them
back in afterwards. Patch also includes tests.
Bug: 60077
Change-Id: If18a93c17ea9bcd529f6a664aa2dcc51d4a37f38
Introduce new static function, CSSMin::buildUrlValue.
Actually using such values in CSS does not work well because the
URL_REGEX is nowhere near good enough. :(
Change-Id: I04a7078dd0087bcb461fa5e5168c870d37c255f4
We would previously return the path to the local file on the
filesystem, which is useless in all cases and possibly a security
issue in some. Now we return the URL at which the file would be
accessible had it existed.
Also reordered the code around that part to make the control flow
clearer and added a test.
Change-Id: I1d5befb2ea385ae4d316c5d8c5d1fc092b64c4ff
Each can be selectively embedded by placing the /* @embed */ comment
just before the url() value. /* @embed */ at the beginning of the rule
affects all url() values appearing in it.
Three changes in existing behavior for previously supported syntax:
* /* @embed */ comments are no longer preserved in output
* rules not terminated by semicolons are correctly supported
* spaces within url() values are correctly supported
Bug: 46757
Bug: 56514
Change-Id: If9082f553fa920c606f12093f39f4a163ebacc32
Also added commented-out tests which should work, but don't.
Making them work in subsequent patch If9082f55.
Change-Id: I65f62493e6d10e7e90af8844f8a26e3982d75f51