Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Commit

Permalink
Fix quadratic behavior in yaml_parser_fetch_more_tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Mar 17, 2024
1 parent 7440d58 commit eb7de7e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
35 changes: 33 additions & 2 deletions src/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
Expand All @@ -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
}
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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(
Expand Down
2 changes: 2 additions & 0 deletions src/yaml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<yaml_simple_key_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<yaml_parser_state_t>,
/// The current parser state.
Expand Down

0 comments on commit eb7de7e

Please sign in to comment.