Skip to content

Commit 89df295

Browse files
committed
fixup! fixup! rustdoc font links only emit crossorigin when needed
1 parent f10e91e commit 89df295

File tree

2 files changed

+47
-17
lines changed

2 files changed

+47
-17
lines changed

src/librustdoc/html/layout.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use super::static_files::{STATIC_FILES, StaticFiles};
88
use crate::externalfiles::ExternalHtml;
99
use crate::html::render::{StylePath, ensure_trailing_slash};
1010

11+
#[cfg(test)]
12+
mod tests;
1113
pub(crate) struct Layout {
1214
pub(crate) logo: String,
1315
pub(crate) favicon: String,
@@ -69,24 +71,9 @@ struct PageLayout<'a> {
6971
}
7072

7173
impl PageLayout<'_> {
72-
/// Conservatively determines if [`Self::static_root_path`] is relative to the current origin,
73-
/// so that `crossorigin` may be safely removed from `<link>` elements.
74+
/// See [`may_remove_crossorigin`].
7475
fn static_root_path_may_remove_crossorigin(&self) -> bool {
75-
let href = &*self.static_root_path;
76-
// Reject scheme-relative URLs (`//example.com/`).
77-
if href.starts_with("//") {
78-
return false;
79-
}
80-
// URL is interpreted as having a scheme iff: it starts with an ascii alpha, and only
81-
// contains ascii alphanumeric or `+` `-` `.` up to the `:`.
82-
// https://url.spec.whatwg.org/#url-parsing
83-
let has_scheme = href.split_once(':').is_some_and(|(scheme, _rest)| {
84-
let mut chars = scheme.chars();
85-
chars.next().is_some_and(|c| c.is_ascii_alphabetic())
86-
&& chars.all(|c| c.is_ascii_alphanumeric() || c == '+' || c == '-' || c == '.')
87-
});
88-
// Reject anything with a scheme (`http:`, etc.).
89-
!has_scheme
76+
may_remove_crossorigin(&self.static_root_path)
9077
}
9178
}
9279

@@ -156,3 +143,22 @@ pub(crate) fn redirect(url: &str) -> String {
156143
</html>"##,
157144
)
158145
}
146+
147+
/// Conservatively determines if `href` is relative to the current origin,
148+
/// so that `crossorigin` may be safely removed from `<link>` elements.
149+
pub(crate) fn may_remove_crossorigin(href: &str) -> bool {
150+
// Reject scheme-relative URLs (`//example.com/`).
151+
if href.starts_with("//") {
152+
return false;
153+
}
154+
// URL is interpreted as having a scheme iff: it starts with an ascii alpha, and only
155+
// contains ascii alphanumeric or `+` `-` `.` up to the `:`.
156+
// https://url.spec.whatwg.org/#url-parsing
157+
let has_scheme = href.split_once(':').is_some_and(|(scheme, _rest)| {
158+
let mut chars = scheme.chars();
159+
chars.next().is_some_and(|c| c.is_ascii_alphabetic())
160+
&& chars.all(|c| c.is_ascii_alphanumeric() || c == '+' || c == '-' || c == '.')
161+
});
162+
// Reject anything with a scheme (`http:`, etc.).
163+
!has_scheme
164+
}

src/librustdoc/html/layout/tests.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#[test]
2+
fn test_may_remove_crossorigin() {
3+
use super::may_remove_crossorigin;
4+
5+
assert!(may_remove_crossorigin("font.woff2"));
6+
assert!(may_remove_crossorigin("/font.woff2"));
7+
assert!(may_remove_crossorigin("./font.woff2"));
8+
assert!(may_remove_crossorigin(":D/font.woff2"));
9+
assert!(may_remove_crossorigin("../font.woff2"));
10+
11+
assert!(!may_remove_crossorigin("//example.com/static.files"));
12+
assert!(!may_remove_crossorigin("http://example.com/static.files"));
13+
assert!(!may_remove_crossorigin("https://example.com/static.files"));
14+
assert!(!may_remove_crossorigin("https://example.com:8080/static.files"));
15+
16+
assert!(!may_remove_crossorigin("ftp://example.com/static.files"));
17+
assert!(!may_remove_crossorigin("blob:http://example.com/static.files"));
18+
assert!(!may_remove_crossorigin("javascript:alert('Hello, world!')"));
19+
assert!(!may_remove_crossorigin("//./C:"));
20+
assert!(!may_remove_crossorigin("file:////C:"));
21+
assert!(!may_remove_crossorigin("file:///./C:"));
22+
assert!(!may_remove_crossorigin("data:,Hello%2C%20World%21"));
23+
assert!(!may_remove_crossorigin("hi...:hello"));
24+
}

0 commit comments

Comments
 (0)