The CSS scanner reads any name ending in url before a ( as a url() link. Its guard refuses only an ASCII letter, a digit or _ in front of those three letters. The CSS ident set is wider than that, so a hyphenated function name is fetched and its argument rewritten.
Repro, a stylesheet with two controls and the cases. .c2 holds a raw U+1680 OGHAM SPACE MARK between x and url, and .c3 holds a raw U+FEFF ZERO WIDTH NO-BREAK SPACE. Both print as nothing below:
.c0{background:url(/img/a.png)}
.c1{background:image-url(/img/b.png)}
.c2{background:x url(/img/c.png)}
.c3{background:xurl(/img/d.png)}
.c5{background:myurl(/img/f.png)}
httrack fetched a.png, b.png, c.png and d.png, and never asked for f.png. The mirrored stylesheet comes back with four of the five values rewritten:
.c0{background:url(img/a.png)}
.c1{background:image-url(img/b.png)}
.c2{background:x url(img/c.png)}
.c3{background:xurl(img/d.png)}
.c5{background:myurl(/img/f.png)}
.c0 must be rewritten and is. .c5 must not be and is not, so the run can show a loss as well as a gain.
CSS Syntax 3 names - (U+002D) an ident code point, so image-url( is consumed as one function-token and never becomes a url-token. No browser resolves that argument. The mirror therefore fetches a file nobody asked for, and rewrites a declaration that a browser reads differently from us. Compass and the Rails asset pipeline both define image-url(), font-url() and asset-url(), so the spelling is common in stylesheet sources.
Every non-ASCII ident code point glues the same way, an accented letter included. U+1680 and U+FEFF are the invisible members of that set. They read as whitespace, and the spec's non-ASCII ident ranges still hold them.
Refusing - and every byte over 127 would also refuse the code points CSS treats as a delim, U+00A0 among them. There the url-token does form, so the argument really is a URL and only the declaration around it is invalid. Those are a separate question.
Two binaries show the same behaviour, 6b23ca8c from before #1743 and 6758bc36 from after it, so that PR neither caused nor fixed this. Found while reviewing it.
The CSS scanner reads any name ending in
urlbefore a(as aurl()link. Its guard refuses only an ASCII letter, a digit or_in front of those three letters. The CSS ident set is wider than that, so a hyphenated function name is fetched and its argument rewritten.Repro, a stylesheet with two controls and the cases.
.c2holds a raw U+1680 OGHAM SPACE MARK betweenxandurl, and.c3holds a raw U+FEFF ZERO WIDTH NO-BREAK SPACE. Both print as nothing below:httrack fetched
a.png,b.png,c.pngandd.png, and never asked forf.png. The mirrored stylesheet comes back with four of the five values rewritten:.c0must be rewritten and is..c5must not be and is not, so the run can show a loss as well as a gain.CSS Syntax 3 names
-(U+002D) an ident code point, soimage-url(is consumed as one function-token and never becomes a url-token. No browser resolves that argument. The mirror therefore fetches a file nobody asked for, and rewrites a declaration that a browser reads differently from us. Compass and the Rails asset pipeline both defineimage-url(),font-url()andasset-url(), so the spelling is common in stylesheet sources.Every non-ASCII ident code point glues the same way, an accented letter included. U+1680 and U+FEFF are the invisible members of that set. They read as whitespace, and the spec's non-ASCII ident ranges still hold them.
Refusing
-and every byte over 127 would also refuse the code points CSS treats as a delim, U+00A0 among them. There the url-token does form, so the argument really is a URL and only the declaration around it is invalid. Those are a separate question.Two binaries show the same behaviour,
6b23ca8cfrom before #1743 and6758bc36from after it, so that PR neither caused nor fixed this. Found while reviewing it.