Skip to content

Commit

Permalink
Auto merge of #111 - servo:stack, r=SimonSapin
Browse files Browse the repository at this point in the history
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 -->
  • Loading branch information
bors-servo authored Dec 15, 2016
2 parents ee735e8 + 071323a commit 664111f
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]

name = "cssparser"
version = "0.7.1"
version = "0.7.2"
authors = [ "Simon Sapin <simon.sapin@exyr.org>" ]

description = "Rust implementation of CSS Syntax Level 3"
Expand Down
15 changes: 11 additions & 4 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
10 changes: 10 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,16 @@ fn unquoted_url(b: &mut Bencher) {

struct JsonParser;

#[test]
fn no_stack_overflow_multiple_nested_blocks() {
let mut input: String = "{{".into();
for _ in 0..20 {
let dup = input.clone();
input.push_str(&dup);
}
let mut input = Parser::new(&input);
while let Ok(..) = input.next() { }
}

impl DeclarationParser for JsonParser {
type Declaration = Json;
Expand Down

0 comments on commit 664111f

Please sign in to comment.