From bff3c4ccaf9b36455898fb78fa2253cd3df8b133 Mon Sep 17 00:00:00 2001 From: Ethiraric Date: Thu, 18 Jan 2024 19:16:02 +0100 Subject: [PATCH] Fix towards invalid trailing characters. --- parser/src/scanner.rs | 23 +++++++++++++++++++++++ parser/tests/basic.rs | 12 +++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/parser/src/scanner.rs b/parser/src/scanner.rs index c9da122..cd139f4 100644 --- a/parser/src/scanner.rs +++ b/parser/src/scanner.rs @@ -679,6 +679,10 @@ impl> Scanner { && is_blankz(self.buffer[3]) { self.fetch_document_indicator(TokenType::DocumentEnd)?; + self.skip_ws_to_eol(SkipTabs::Yes); + if !is_breakz(self.ch()) { + return Err(ScanError::new(self.mark, "invalid content after document end marker")); + } return Ok(()); } @@ -1809,6 +1813,25 @@ impl> Scanner { // Eat the right quote. self.skip(); + // Ensure there is no invalid trailing content. + self.skip_ws_to_eol(SkipTabs::Yes); + match self.ch() { + // These can be encountered in flow sequences or mappings. + ',' | '}' | ']' if self.flow_level > 0 => {} + // An end-of-line / end-of-stream is fine. No trailing content. + c if is_breakz(c) => {} + // ':' can be encountered if our scalar is a key. + // Outside of flow contexts, keys cannot span multiple lines + ':' if self.flow_level == 0 && start_mark.line == self.mark.line => {} + // Inside a flow context, this is allowed. + ':' if self.flow_level > 0 => {} + _ => { + return Err(ScanError::new( + self.mark, + "invalid trailing content after double-quoted scalar", + )); + } + } let style = if single { TScalarStyle::SingleQuoted diff --git a/parser/tests/basic.rs b/parser/tests/basic.rs index e551776..946843a 100644 --- a/parser/tests/basic.rs +++ b/parser/tests/basic.rs @@ -52,7 +52,9 @@ scalar key: [1, 2]] key1:a2 "; - let Err(error) = YamlLoader::load_from_str(s) else { panic!() }; + let Err(error) = YamlLoader::load_from_str(s) else { + panic!() + }; assert_eq!( error.info(), "mapping values are not allowed in this context" @@ -235,6 +237,14 @@ fn test_issue_65() { assert!(YamlLoader::load_from_str(b).is_err()); } +#[test] +fn test_issue_65_mwe() { + // A MWE for `test_issue_65`. The error over there is that there is invalid trailing content + // after a double quoted string. + let b = r#""foo" l"#; + assert!(YamlLoader::load_from_str(b).is_err()); +} + #[test] fn test_bad_docstart() { assert!(YamlLoader::load_from_str("---This used to cause an infinite loop").is_ok());