Skip to content

Commit 83f3479

Browse files
dumbmoronchromium-wpt-export-bot
authored andcommitted
Wire up URL request modifiers for @import url()
Parse cross-origin(), integrity(), and referrer-policy() modifiers on @import url() rules, apply them to the stylesheet fetch (CORS mode, integrity metadata, referrer policy), and serialize them back in CSSImportRule::cssText(). Bug: 435625756 Change-Id: I4f52b9dce9871593005595fac9ac3e661e2af65b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7779724 Commit-Queue: jj <jj@chromium.org> Reviewed-by: Fredrik Söderquist <fs@opera.com> Cr-Commit-Position: refs/heads/main@{#1619475}
1 parent f46f7cb commit 83f3479

11 files changed

Lines changed: 292 additions & 0 deletions
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html class="reftest-wait">
3+
<head>
4+
<title>Request URL Modifiers: cross-origin(anonymous) negative test for @import</title>
5+
<link rel="help" href="https://drafts.csswg.org/css-values-5/#typedef-request-url-modifier-cross-origin-modifier">
6+
<link rel="match" href="/css/reference/ref-filled-green-100px-square.xht">
7+
<meta name="assert" content="cross-origin(anonymous) should block a cross-origin @import served without CORS headers.">
8+
<style>
9+
@import url("http://{{hosts[][]}}:{{ports[http][1]}}/css/css-values/urls/support/red-style.css" cross-origin(anonymous));
10+
div {
11+
width: 100px;
12+
height: 100px;
13+
background-color: green;
14+
}
15+
</style>
16+
</head>
17+
<body>
18+
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
19+
<div></div>
20+
<script>
21+
window.addEventListener("load", () => {
22+
document.documentElement.classList.remove("reftest-wait");
23+
});
24+
</script>
25+
</body>
26+
</html>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html class="reftest-wait">
3+
<head>
4+
<title>Request URL Modifiers: cross-origin(anonymous) for @import</title>
5+
<link rel="help" href="https://drafts.csswg.org/css-values-5/#typedef-request-url-modifier-cross-origin-modifier">
6+
<link rel="match" href="/css/reference/ref-filled-green-100px-square.xht">
7+
<meta name="assert" content="cross-origin(anonymous) should allow a cross-origin @import served with CORS headers.">
8+
<style>
9+
@import url("http://{{hosts[][]}}:{{ports[http][1]}}/css/css-values/urls/support/green-style.css?pipe=header(Access-Control-Allow-Origin,*)" cross-origin(anonymous));
10+
div {
11+
width: 100px;
12+
height: 100px;
13+
background-color: red;
14+
}
15+
</style>
16+
</head>
17+
<body>
18+
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
19+
<div></div>
20+
<script>
21+
window.addEventListener("load", () => {
22+
document.documentElement.classList.remove("reftest-wait");
23+
});
24+
</script>
25+
</body>
26+
</html>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html class="reftest-wait">
3+
<head>
4+
<title>Request URL Modifiers: integrity() negative test for @import</title>
5+
<link rel="help" href="https://drafts.csswg.org/css-values-5/#typedef-request-url-modifier-integrity-modifier">
6+
<link rel="match" href="/css/reference/ref-filled-green-100px-square.xht">
7+
<meta name="assert" content="An @import with a non-matching integrity() modifier should not apply the imported styles.">
8+
<style>
9+
@import url("http://{{hosts[][]}}:{{ports[http][0]}}/css/css-values/urls/support/red-style.css?pipe=header(Access-Control-Allow-Origin,*)" cross-origin(anonymous) integrity("sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
10+
div {
11+
width: 100px;
12+
height: 100px;
13+
background-color: green;
14+
}
15+
</style>
16+
</head>
17+
<body>
18+
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
19+
<div></div>
20+
<script>
21+
window.addEventListener("load", () => {
22+
document.documentElement.classList.remove("reftest-wait");
23+
});
24+
</script>
25+
</body>
26+
</html>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html class="reftest-wait">
3+
<head>
4+
<title>Request URL Modifiers: integrity() for @import</title>
5+
<link rel="help" href="https://drafts.csswg.org/css-values-5/#typedef-request-url-modifier-integrity-modifier">
6+
<link rel="match" href="/css/reference/ref-filled-green-100px-square.xht">
7+
<meta name="assert" content="An @import with a matching integrity() modifier should apply the imported styles.">
8+
<style>
9+
@import url("http://{{hosts[][]}}:{{ports[http][0]}}/css/css-values/urls/support/green-style.css?pipe=header(Access-Control-Allow-Origin,*)" cross-origin(anonymous) integrity("sha256-Id1Hm8tP+9lRAbQlLxjIRmzsU5MK+hftN3wiKKt4Hf4="));
10+
div {
11+
width: 100px;
12+
height: 100px;
13+
background-color: red;
14+
}
15+
</style>
16+
</head>
17+
<body>
18+
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
19+
<div></div>
20+
<script>
21+
window.addEventListener("load", () => {
22+
document.documentElement.classList.remove("reftest-wait");
23+
});
24+
</script>
25+
</body>
26+
</html>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<title>Request URL Modifiers: referrer-policy(no-referrer) for @font-face</title>
3+
<link rel="help" href="https://drafts.csswg.org/css-values-5/#typedef-request-url-modifier-referrer-policy-modifier">
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<style>
7+
@font-face {
8+
font-family: "TestFont";
9+
src: url("http://{{hosts[][]}}:{{ports[http][1]}}/css/css-values/urls/support/font-referrer-policy.py?expected_referrer=none" cross-origin(anonymous) referrer-policy(no-referrer)) format("truetype");
10+
}
11+
.test { font-family: "TestFont"; }
12+
</style>
13+
<div class="test">X</div>
14+
<script>
15+
promise_test(async t => {
16+
await document.fonts.ready;
17+
assert_true(document.fonts.check("16px TestFont"),
18+
"Font with referrer-policy(no-referrer) should load when server expects no referrer");
19+
}, "referrer-policy(no-referrer) sends no referrer for @font-face");
20+
</script>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<title>Request URL Modifiers: referrer-policy(no-referrer) for @import</title>
3+
<link rel="help" href="https://drafts.csswg.org/css-values-5/#typedef-request-url-modifier-referrer-policy-modifier">
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<div id="test">X</div>
7+
<script>
8+
promise_test(async t => {
9+
const url = `/css/css-values/urls/support/stylesheet-referrer-policy.py?expected_referrer=none`;
10+
const style = document.createElement("style");
11+
style.textContent = `@import url("${url}" referrer-policy(no-referrer));`;
12+
const { promise, resolve, reject } = Promise.withResolvers();
13+
style.onload = resolve;
14+
style.onerror = reject;
15+
document.head.prepend(style);
16+
await promise;
17+
assert_equals(
18+
getComputedStyle(document.getElementById("test")).color,
19+
"rgb(0, 128, 0)",
20+
"@import with referrer-policy(no-referrer) should apply green style");
21+
}, "referrer-policy(no-referrer) sends no referrer for @import");
22+
</script>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import os.path
2+
3+
HERE = os.path.dirname(__file__)
4+
WPT_ROOT = os.path.abspath(os.path.join(HERE, "../../../.."))
5+
6+
def main(request, response):
7+
expected_referrer = request.GET[b'expected_referrer']
8+
actual_referrer = request.headers.get(b'referer', b'')
9+
10+
if expected_referrer == b'none':
11+
match = actual_referrer == b''
12+
elif expected_referrer == b'origin':
13+
origin = request.GET[b'origin']
14+
match = actual_referrer == origin
15+
elif expected_referrer == b'url':
16+
url = request.GET[b'url']
17+
match = actual_referrer == url
18+
else:
19+
match = False
20+
21+
response.add_required_headers = False
22+
response.writer.write_status(200)
23+
response.writer.write_header(b"access-control-allow-origin", b"*")
24+
response.writer.write_header(b"cache-control", b"no-cache; must-revalidate")
25+
26+
if match:
27+
# Return a valid font.
28+
font_path = os.path.join(WPT_ROOT, u"fonts", u"Ahem.ttf")
29+
with open(font_path, u"rb") as f:
30+
body = f.read()
31+
response.writer.write_header(b"content-type", b"font/truetype")
32+
else:
33+
# Return an empty body, so the font fails to load.
34+
body = b""
35+
response.writer.write_header(b"content-type", b"text/plain")
36+
37+
response.writer.write_header(b"content-length", len(body))
38+
response.writer.end_headers()
39+
response.writer.write(body)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
div { background-color: green !important; }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
div { background-color: red !important; }
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
def main(request, response):
2+
expected_referrer = request.GET[b'expected_referrer']
3+
actual_referrer = request.headers.get(b'referer', b'')
4+
5+
if expected_referrer == b'none':
6+
match = actual_referrer == b''
7+
elif expected_referrer == b'origin':
8+
origin = request.GET[b'origin']
9+
match = actual_referrer == origin
10+
elif expected_referrer == b'url':
11+
url = request.GET[b'url']
12+
match = actual_referrer == url
13+
else:
14+
match = False
15+
16+
response.add_required_headers = False
17+
response.writer.write_status(200)
18+
response.writer.write_header(b"access-control-allow-origin", b"*")
19+
response.writer.write_header(b"content-type", b"text/css")
20+
response.writer.write_header(b"cache-control", b"no-cache; must-revalidate")
21+
22+
if match:
23+
body = b"#test { color: green; }"
24+
else:
25+
body = b"#test { color: red; }"
26+
27+
response.writer.write_header(b"content-length", len(body))
28+
response.writer.end_headers()
29+
response.writer.write(body)

0 commit comments

Comments
 (0)