diff options
| author | Ed Page <eopage@gmail.com> | 2025-08-28 15:15:41 -0500 |
|---|---|---|
| committer | Ed Page <eopage@gmail.com> | 2025-09-01 20:51:39 -0500 |
| commit | 6f0da976c5f422ff5b1124d409e7d7e063fc4225 (patch) | |
| tree | fd78a411df7eb377af1978a1e8aa41c99009cbf7 /compiler/rustc_lexer | |
| parent | 428e413414e0719a7758676ac49e07b85eb86dec (diff) | |
| download | rust-6f0da976c5f422ff5b1124d409e7d7e063fc4225.tar.gz rust-6f0da976c5f422ff5b1124d409e7d7e063fc4225.zip | |
fix(lexer): Only allow horizontal whitespace in frontmatter
In writing up the reference for frontmatter, I realized that we probably shouldn't be accepting Unicode Line Ending characters between the code fence and infostring or trailing after the infostring or a code fence. In digging into the unicode specification we use for Whitespace, it divides it up into categories, so I'm deferring to what it says for horizontal whitespace for what should be used within a line. Note, I am leaving out support for Unicde Default Ignorable characters. I figure that can be discussed outside of this change within the reference and tracking issue.
Diffstat (limited to 'compiler/rustc_lexer')
| -rw-r--r-- | compiler/rustc_lexer/src/lib.rs | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index e347a76f6a2..c29ab569f47 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -350,6 +350,21 @@ pub fn is_whitespace(c: char) -> bool { ) } +/// True if `c` is considered horizontal whitespace according to Rust language definition. +pub fn is_horizontal_whitespace(c: char) -> bool { + // This is Pattern_White_Space. + // + // Note that this set is stable (ie, it doesn't change with different + // Unicode versions), so it's ok to just hard-code the values. + + matches!( + c, + // Horizontal space characters + '\u{0009}' // tab (\t) + | '\u{0020}' // space + ) +} + /// True if `c` is valid as a first character of an identifier. /// See [Rust language reference](https://doc.rust-lang.org/reference/identifiers.html) for /// a formal definition of valid identifier name. @@ -536,7 +551,7 @@ impl Cursor<'_> { debug_assert!(length_opening >= 3); // whitespace between the opening and the infostring. - self.eat_while(|ch| ch != '\n' && is_whitespace(ch)); + self.eat_while(|ch| ch != '\n' && is_horizontal_whitespace(ch)); // copied from `eat_identifier`, but allows `-` and `.` in infostring to allow something like // `---Cargo.toml` as a valid opener @@ -545,7 +560,7 @@ impl Cursor<'_> { self.eat_while(|c| is_id_continue(c) || c == '-' || c == '.'); } - self.eat_while(|ch| ch != '\n' && is_whitespace(ch)); + self.eat_while(|ch| ch != '\n' && is_horizontal_whitespace(ch)); let invalid_infostring = self.first() != '\n'; let mut found = false; @@ -586,7 +601,7 @@ impl Cursor<'_> { // on a standalone line. Might be wrong. while let Some(closing) = rest.find("---") { let preceding_chars_start = rest[..closing].rfind("\n").map_or(0, |i| i + 1); - if rest[preceding_chars_start..closing].chars().all(is_whitespace) { + if rest[preceding_chars_start..closing].chars().all(is_horizontal_whitespace) { // candidate found potential_closing = Some(closing); break; |
