Skip to content

Commit 664111f

Browse files
author
bors-servo
authored
Auto merge of #111 - servo:stack, r=SimonSapin
Avoid overflowing the stack in consume_until_end_of_block. Fixes: https://bugzilla.mozilla.org/show_bug.cgi?id=1323705 r? @SimonSapin <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-cssparser/111) <!-- Reviewable:end -->
2 parents ee735e8 + 071323a commit 664111f

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
name = "cssparser"
4-
version = "0.7.1"
4+
version = "0.7.2"
55
authors = [ "Simon Sapin <[email protected]>" ]
66

77
description = "Rust implementation of CSS Syntax Level 3"

src/parser.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -691,15 +691,22 @@ impl<'i, 't> Parser<'i, 't> {
691691
}
692692

693693

694-
/// Return value indicates whether the end of the input was reached.
695694
fn consume_until_end_of_block(block_type: BlockType, tokenizer: &mut Tokenizer) {
695+
let mut stack = vec![block_type];
696+
696697
// FIXME: have a special-purpose tokenizer method for this that does less work.
697698
while let Ok(ref token) = tokenizer.next() {
698-
if BlockType::closing(token) == Some(block_type) {
699-
return
699+
if let Some(b) = BlockType::closing(token) {
700+
if *stack.last().unwrap() == b {
701+
stack.pop();
702+
if stack.is_empty() {
703+
return;
704+
}
705+
}
700706
}
707+
701708
if let Some(block_type) = BlockType::opening(token) {
702-
consume_until_end_of_block(block_type, tokenizer);
709+
stack.push(block_type);
703710
}
704711
}
705712
}

src/tests.rs

+10
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,16 @@ fn unquoted_url(b: &mut Bencher) {
603603

604604
struct JsonParser;
605605

606+
#[test]
607+
fn no_stack_overflow_multiple_nested_blocks() {
608+
let mut input: String = "{{".into();
609+
for _ in 0..20 {
610+
let dup = input.clone();
611+
input.push_str(&dup);
612+
}
613+
let mut input = Parser::new(&input);
614+
while let Ok(..) = input.next() { }
615+
}
606616

607617
impl DeclarationParser for JsonParser {
608618
type Declaration = Json;

0 commit comments

Comments
 (0)