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

Commit eb7de7e

Browse files
committed
Fix quadratic behavior in yaml_parser_fetch_more_tokens
1 parent 7440d58 commit eb7de7e

2 files changed

Lines changed: 35 additions & 2 deletions

File tree

src/scanner.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,10 @@ pub(crate) unsafe fn yaml_parser_fetch_more_tokens(parser: *mut yaml_parser_t) -
186186
if yaml_parser_stale_simple_keys(parser).fail {
187187
return FAIL;
188188
}
189-
simple_key = (*parser).simple_keys.start;
189+
simple_key = (*parser)
190+
.simple_keys
191+
.start
192+
.add((*parser).not_simple_keys as usize);
190193
while simple_key != (*parser).simple_keys.top {
191194
if (*simple_key).possible && (*simple_key).token_number == (*parser).tokens_parsed {
192195
need_more_tokens = true;
@@ -334,7 +337,10 @@ unsafe fn yaml_parser_fetch_next_token(parser: *mut yaml_parser_t) -> Success {
334337

335338
unsafe fn yaml_parser_stale_simple_keys(parser: *mut yaml_parser_t) -> Success {
336339
let mut simple_key: *mut yaml_simple_key_t;
337-
simple_key = (*parser).simple_keys.start;
340+
simple_key = (*parser)
341+
.simple_keys
342+
.start
343+
.add((*parser).not_simple_keys as usize);
338344
while simple_key != (*parser).simple_keys.top {
339345
if (*simple_key).possible
340346
&& ((*simple_key).mark.line < (*parser).mark.line
@@ -350,6 +356,14 @@ unsafe fn yaml_parser_stale_simple_keys(parser: *mut yaml_parser_t) -> Success {
350356
return FAIL;
351357
}
352358
(*simple_key).possible = false;
359+
if (*parser)
360+
.simple_keys
361+
.start
362+
.add((*parser).not_simple_keys as usize)
363+
== simple_key
364+
{
365+
(*parser).not_simple_keys += 1;
366+
}
353367
}
354368
simple_key = simple_key.wrapping_offset(1);
355369
}
@@ -372,6 +386,14 @@ unsafe fn yaml_parser_save_simple_key(parser: *mut yaml_parser_t) -> Success {
372386
return FAIL;
373387
}
374388
*(*parser).simple_keys.top.wrapping_offset(-1_isize) = simple_key;
389+
if (*parser)
390+
.simple_keys
391+
.start
392+
.add((*parser).not_simple_keys as usize)
393+
== (*parser).simple_keys.top
394+
{
395+
(*parser).not_simple_keys -= 1;
396+
}
375397
}
376398
OK
377399
}
@@ -418,6 +440,14 @@ unsafe fn yaml_parser_decrease_flow_level(parser: *mut yaml_parser_t) {
418440
if (*parser).flow_level != 0 {
419441
let fresh8 = addr_of_mut!((*parser).flow_level);
420442
*fresh8 -= 1;
443+
if (*parser)
444+
.simple_keys
445+
.start
446+
.add((*parser).not_simple_keys as usize)
447+
== (*parser).simple_keys.top
448+
{
449+
(*parser).not_simple_keys -= 1;
450+
}
421451
let _ = POP!((*parser).simple_keys);
422452
}
423453
}
@@ -497,6 +527,7 @@ unsafe fn yaml_parser_fetch_stream_start(parser: *mut yaml_parser_t) {
497527
let token = token.as_mut_ptr();
498528
(*parser).indent = -1;
499529
PUSH!((*parser).simple_keys, simple_key);
530+
(*parser).not_simple_keys = 1;
500531
(*parser).simple_key_allowed = true;
501532
(*parser).stream_start_produced = true;
502533
memset(

src/yaml.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,8 @@ pub struct yaml_parser_t {
916916
pub(crate) simple_key_allowed: bool,
917917
/// The stack of simple keys.
918918
pub(crate) simple_keys: yaml_stack_t<yaml_simple_key_t>,
919+
/// At least this many leading elements of simple_keys have possible=0.
920+
pub(crate) not_simple_keys: libc::c_int,
919921
/// The parser states stack.
920922
pub(crate) states: yaml_stack_t<yaml_parser_state_t>,
921923
/// The current parser state.

0 commit comments

Comments
 (0)