From 52f2d414939b83021a5ceec2fb53a2539b19572d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 15 Dec 2016 12:46:14 +0100 Subject: [PATCH 1/4] Add a stack overflow test for nested block. --- src/tests.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tests.rs b/src/tests.rs index ab85f418..d0653010 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -603,6 +603,18 @@ fn unquoted_url(b: &mut Bencher) { struct JsonParser; +#[test] +fn no_stack_overflow_multiple_nested_blocks() { + let mut input: String = "{{".into(); + for _ in 0..30 { + let dup = input.clone(); + input.push_str(&dup); + } + let mut input = Parser::new(&input); + while !input.is_exhausted() { + input.next().expect("What?"); + } +} impl DeclarationParser for JsonParser { type Declaration = Json; From b7376a24538dd8c603f4d7214be5353a594be856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 15 Dec 2016 13:59:45 +0100 Subject: [PATCH 2/4] Avoid overflowing the stack with a lot of nested blocks. --- src/parser.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 6abe2b34..9a1ef3d6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -691,15 +691,22 @@ impl<'i, 't> Parser<'i, 't> { } -/// Return value indicates whether the end of the input was reached. fn consume_until_end_of_block(block_type: BlockType, tokenizer: &mut Tokenizer) { + let mut stack = vec![block_type]; + // FIXME: have a special-purpose tokenizer method for this that does less work. while let Ok(ref token) = tokenizer.next() { - if BlockType::closing(token) == Some(block_type) { - return + if let Some(b) = BlockType::closing(token) { + if *stack.last().unwrap() == b { + stack.pop(); + if stack.is_empty() { + return; + } + } } + if let Some(block_type) = BlockType::opening(token) { - consume_until_end_of_block(block_type, tokenizer); + stack.push(block_type); } } } From fc9e074cf3ab1450b3e7401c31d865356c7be8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 15 Dec 2016 14:16:07 +0100 Subject: [PATCH 3/4] Reduce the test so travis is happy. --- src/tests.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/tests.rs b/src/tests.rs index d0653010..ba824399 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -606,14 +606,12 @@ struct JsonParser; #[test] fn no_stack_overflow_multiple_nested_blocks() { let mut input: String = "{{".into(); - for _ in 0..30 { + for _ in 0..20 { let dup = input.clone(); input.push_str(&dup); } let mut input = Parser::new(&input); - while !input.is_exhausted() { - input.next().expect("What?"); - } + while let Ok(..) = input.next() { } } impl DeclarationParser for JsonParser { From 071323ade1862b5adeddf490debdeef2ea01122a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 15 Dec 2016 21:50:03 +0100 Subject: [PATCH 4/4] Version bump. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f48a848b..414003dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cssparser" -version = "0.7.1" +version = "0.7.2" authors = [ "Simon Sapin " ] description = "Rust implementation of CSS Syntax Level 3"