More fixes towards invalid tabs.

This commit is contained in:
Ethiraric 2023-12-26 00:34:29 +01:00
parent 5437f5d9cb
commit 06b03f5cf5
2 changed files with 31 additions and 5 deletions

View file

@ -718,9 +718,13 @@ impl<T: Iterator<Item = char>> Scanner<T> {
/// Skip yaml whitespace at most up to eol. Also skips comments. /// Skip yaml whitespace at most up to eol. Also skips comments.
fn skip_ws_to_eol(&mut self, skip_tabs: SkipTabs) -> SkipTabs { fn skip_ws_to_eol(&mut self, skip_tabs: SkipTabs) -> SkipTabs {
let mut encountered_tab = false; let mut encountered_tab = false;
let mut has_yaml_ws = false;
loop { loop {
match self.look_ch() { match self.look_ch() {
' ' => self.skip(), ' ' => {
has_yaml_ws = true;
self.skip();
}
'\t' if skip_tabs != SkipTabs::No => { '\t' if skip_tabs != SkipTabs::No => {
encountered_tab = true; encountered_tab = true;
self.skip(); self.skip();
@ -735,7 +739,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
} }
} }
SkipTabs::Result(encountered_tab) SkipTabs::Result(encountered_tab, has_yaml_ws)
} }
fn fetch_stream_start(&mut self) { fn fetch_stream_start(&mut self) {
@ -1906,6 +1910,19 @@ impl<T: Iterator<Item = char>> Scanner<T> {
fn fetch_value(&mut self) -> ScanResult { fn fetch_value(&mut self) -> ScanResult {
let sk = self.simple_keys.last().unwrap().clone(); let sk = self.simple_keys.last().unwrap().clone();
let start_mark = self.mark; let start_mark = self.mark;
// Skip over ':'.
self.skip();
if self.look_ch() == '\t'
&& !self.skip_ws_to_eol(SkipTabs::Yes).has_valid_yaml_ws()
&& self.ch() == '-'
{
return Err(ScanError::new(
self.mark,
"':' must be followed by a valid YAML whitespace",
));
}
if sk.possible { if sk.possible {
// insert simple key // insert simple key
let tok = Token(sk.mark, TokenType::Key); let tok = Token(sk.mark, TokenType::Key);
@ -1946,7 +1963,6 @@ impl<T: Iterator<Item = char>> Scanner<T> {
self.disallow_simple_key(); self.disallow_simple_key();
} }
} }
self.skip();
self.tokens.push_back(Token(start_mark, TokenType::Value)); self.tokens.push_back(Token(start_mark, TokenType::Value));
Ok(()) Ok(())
@ -2041,6 +2057,8 @@ impl<T: Iterator<Item = char>> Scanner<T> {
} }
/// Behavior to adopt regarding treating tabs as whitespace. /// Behavior to adopt regarding treating tabs as whitespace.
///
/// Although tab is a valid yaml whitespace, it doesn't always behave the same as a space.
#[derive(Copy, Clone, Eq, PartialEq)] #[derive(Copy, Clone, Eq, PartialEq)]
enum SkipTabs { enum SkipTabs {
/// Skip all tabs as whitespace. /// Skip all tabs as whitespace.
@ -2051,6 +2069,8 @@ enum SkipTabs {
Result( Result(
/// Whether tabs were encountered. /// Whether tabs were encountered.
bool, bool,
/// Whether at least 1 valid yaml whitespace has been encountered.
bool,
), ),
} }
@ -2059,6 +2079,13 @@ impl SkipTabs {
/// ///
/// This function must be called after a call to `skip_ws_to_eol`. /// This function must be called after a call to `skip_ws_to_eol`.
fn found_tabs(self) -> bool { fn found_tabs(self) -> bool {
matches!(self, SkipTabs::Result(true)) matches!(self, SkipTabs::Result(true, _))
}
/// Whether a valid YAML whitespace has been found in skipped-over content.
///
/// This function must be called after a call to `skip_ws_to_eol`.
fn has_valid_yaml_ws(self) -> bool {
matches!(self, SkipTabs::Result(_, true))
} }
} }

View file

@ -301,7 +301,6 @@ static EXPECTED_FAILURES: &[&str] = &[
// TAB as start of plain scalar instead of whitespace // TAB as start of plain scalar instead of whitespace
// TABs in whitespace-only lines // TABs in whitespace-only lines
// TABs after marker ? or : (space required?) // TABs after marker ? or : (space required?)
"Y79Y-07",
"Y79Y-09", "Y79Y-09",
// Other TABs // Other TABs
"DK95-01", // in double-quoted scalar "DK95-01", // in double-quoted scalar