From eb7de7e85910a0d40dbe3e54af98ede827262453 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 16 Mar 2024 22:20:52 -0700 Subject: [PATCH] Fix quadratic behavior in yaml_parser_fetch_more_tokens --- src/scanner.rs | 35 +++++++++++++++++++++++++++++++++-- src/yaml.rs | 2 ++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/scanner.rs b/src/scanner.rs index 23bccfd..325a348 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -186,7 +186,10 @@ pub(crate) unsafe fn yaml_parser_fetch_more_tokens(parser: *mut yaml_parser_t) - if yaml_parser_stale_simple_keys(parser).fail { return FAIL; } - simple_key = (*parser).simple_keys.start; + simple_key = (*parser) + .simple_keys + .start + .add((*parser).not_simple_keys as usize); while simple_key != (*parser).simple_keys.top { if (*simple_key).possible && (*simple_key).token_number == (*parser).tokens_parsed { need_more_tokens = true; @@ -334,7 +337,10 @@ unsafe fn yaml_parser_fetch_next_token(parser: *mut yaml_parser_t) -> Success { unsafe fn yaml_parser_stale_simple_keys(parser: *mut yaml_parser_t) -> Success { let mut simple_key: *mut yaml_simple_key_t; - simple_key = (*parser).simple_keys.start; + simple_key = (*parser) + .simple_keys + .start + .add((*parser).not_simple_keys as usize); while simple_key != (*parser).simple_keys.top { if (*simple_key).possible && ((*simple_key).mark.line < (*parser).mark.line @@ -350,6 +356,14 @@ unsafe fn yaml_parser_stale_simple_keys(parser: *mut yaml_parser_t) -> Success { return FAIL; } (*simple_key).possible = false; + if (*parser) + .simple_keys + .start + .add((*parser).not_simple_keys as usize) + == simple_key + { + (*parser).not_simple_keys += 1; + } } simple_key = simple_key.wrapping_offset(1); } @@ -372,6 +386,14 @@ unsafe fn yaml_parser_save_simple_key(parser: *mut yaml_parser_t) -> Success { return FAIL; } *(*parser).simple_keys.top.wrapping_offset(-1_isize) = simple_key; + if (*parser) + .simple_keys + .start + .add((*parser).not_simple_keys as usize) + == (*parser).simple_keys.top + { + (*parser).not_simple_keys -= 1; + } } OK } @@ -418,6 +440,14 @@ unsafe fn yaml_parser_decrease_flow_level(parser: *mut yaml_parser_t) { if (*parser).flow_level != 0 { let fresh8 = addr_of_mut!((*parser).flow_level); *fresh8 -= 1; + if (*parser) + .simple_keys + .start + .add((*parser).not_simple_keys as usize) + == (*parser).simple_keys.top + { + (*parser).not_simple_keys -= 1; + } let _ = POP!((*parser).simple_keys); } } @@ -497,6 +527,7 @@ unsafe fn yaml_parser_fetch_stream_start(parser: *mut yaml_parser_t) { let token = token.as_mut_ptr(); (*parser).indent = -1; PUSH!((*parser).simple_keys, simple_key); + (*parser).not_simple_keys = 1; (*parser).simple_key_allowed = true; (*parser).stream_start_produced = true; memset( diff --git a/src/yaml.rs b/src/yaml.rs index ab9cd7e..f2318c5 100644 --- a/src/yaml.rs +++ b/src/yaml.rs @@ -916,6 +916,8 @@ pub struct yaml_parser_t { pub(crate) simple_key_allowed: bool, /// The stack of simple keys. pub(crate) simple_keys: yaml_stack_t, + /// At least this many leading elements of simple_keys have possible=0. + pub(crate) not_simple_keys: libc::c_int, /// The parser states stack. pub(crate) states: yaml_stack_t, /// The current parser state.