Skip to content

Commit e4679cd

Browse files
committed
fix(frontatter): Only allow horizontal whitespace after fences
This is to align with rust-lang/rust#146106. While no tests were affected by this, I definitely broke a lot of tests when making this change.
1 parent 24ef070 commit e4679cd

File tree

1 file changed

+35
-16
lines changed

1 file changed

+35
-16
lines changed

src/cargo/util/frontmatter.rs

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ impl<'s> ScriptSource<'s> {
8686
.push_visible_span(open_start..open_end));
8787
};
8888
let info = input.next_slice(info_nl.start);
89-
let info = info.trim_matches(is_whitespace);
89+
let info = info.strip_suffix('\r').unwrap_or(info); // already excludes `\n`
90+
let info = info.trim_matches(is_horizontal_whitespace);
9091
if !info.is_empty() {
9192
let info_start = info.offset_from(&raw);
9293
let info_end = info_start + info.len();
@@ -147,7 +148,8 @@ impl<'s> ScriptSource<'s> {
147148
)
148149
.push_visible_span(open_start..open_end));
149150
} else {
150-
let after_closing_fence = after_closing_fence.trim_matches(is_whitespace);
151+
let after_closing_fence = strip_newline(after_closing_fence);
152+
let after_closing_fence = after_closing_fence.trim_matches(is_horizontal_whitespace);
151153
if !after_closing_fence.is_empty() {
152154
// extra characters beyond the original fence pattern
153155
let after_start = after_closing_fence.offset_from(&raw);
@@ -261,8 +263,6 @@ pub fn strip_ws_lines(input: &str) -> Option<usize> {
261263
/// True if `c` is considered a whitespace according to Rust language definition.
262264
/// See [Rust language reference](https://doc.rust-lang.org/reference/whitespace.html)
263265
/// for definitions of these classes.
264-
///
265-
/// See rust-lang/rust's compiler/rustc_lexer/src/lib.rs `is_whitespace`
266266
fn is_whitespace(c: char) -> bool {
267267
// This is Pattern_White_Space.
268268
//
@@ -271,27 +271,46 @@ fn is_whitespace(c: char) -> bool {
271271

272272
matches!(
273273
c,
274-
// Usual ASCII suspects
275-
'\u{0009}' // \t
276-
| '\u{000A}' // \n
274+
// End-of-line characters
275+
| '\u{000A}' // line feed (\n)
277276
| '\u{000B}' // vertical tab
278277
| '\u{000C}' // form feed
279-
| '\u{000D}' // \r
280-
| '\u{0020}' // space
281-
282-
// NEXT LINE from latin1
283-
| '\u{0085}'
278+
| '\u{000D}' // carriage return (\r)
279+
| '\u{0085}' // next line (from latin1)
280+
| '\u{2028}' // LINE SEPARATOR
281+
| '\u{2029}' // PARAGRAPH SEPARATOR
284282

285-
// Bidi markers
283+
// `Default_Ignorable_Code_Point` characters
286284
| '\u{200E}' // LEFT-TO-RIGHT MARK
287285
| '\u{200F}' // RIGHT-TO-LEFT MARK
288286

289-
// Dedicated whitespace characters from Unicode
290-
| '\u{2028}' // LINE SEPARATOR
291-
| '\u{2029}' // PARAGRAPH SEPARATOR
287+
// Horizontal space characters
288+
| '\u{0009}' // tab (\t)
289+
| '\u{0020}' // space
290+
)
291+
}
292+
293+
/// True if `c` is considered horizontal whitespace according to Rust language definition.
294+
fn is_horizontal_whitespace(c: char) -> bool {
295+
// This is Pattern_White_Space.
296+
//
297+
// Note that this set is stable (ie, it doesn't change with different
298+
// Unicode versions), so it's ok to just hard-code the values.
299+
300+
matches!(
301+
c,
302+
// Horizontal space characters
303+
'\u{0009}' // tab (\t)
304+
| '\u{0020}' // space
292305
)
293306
}
294307

308+
fn strip_newline(text: &str) -> &str {
309+
text.strip_suffix("\r\n")
310+
.or_else(|| text.strip_suffix('\n'))
311+
.unwrap_or(text)
312+
}
313+
295314
#[derive(Debug)]
296315
pub struct FrontmatterError {
297316
message: String,

0 commit comments

Comments
 (0)