Skip to content

fix(lexer): Avoid infinite loop on lone CR, U+2028 and U+2029 - #742

Open
jeff-grimes-pplx wants to merge 1 commit into
eemeli:mainfrom
jeff-grimes-pplx:fix/lexer-line-terminators
Open

jeff-grimes-pplx wants to merge 1 commit into
eemeli:mainfrom
jeff-grimes-pplx:fix/lexer-line-terminators

Conversation

@jeff-grimes-pplx

Copy link
Copy Markdown

Summary

  • Fixes an infinite loop in Lexer.lex() when a lone \r, U+2028 (LS), or U+2029 (PS) appears where emptyLineOrComment or directiveLine is matched (e.g. YAML.parse('\u2028'), YAML.parse('\r'), or YAML.parse('# comment\u2028\nkey: value\n')).
  • Also fixes premature comment termination after --- # comment when the comment contains \r, U+2028, or U+2029.
  • Replaces . and multiline $ (/my) in blockScalarHeader, directiveLine, docMarker, and emptyLineOrComment with (?:[^\n\r]|\r(?!\n))* and (?=\r?\n|$) so they match the YAML 1.2 line-break rules used by newline() and toLineEnd().

Since the lexer was moved to regexps in fc0a803, the directive, comment,
document marker and block scalar header patterns used `.` and a multiline
`$`. In JS those also treat a lone \r, U+2028 and U+2029 as line
terminators, while the rest of the lexer (newline(), toLineEnd()) only
breaks lines on \n and \r\n.

In the stream context this matched an empty line that ended just before
such a character, consumed nothing, and returned to the same state, so
parsing never terminated. `YAML.parse('\u2028')`, `YAML.parse('\r')` or a
leading comment line like `# note\u2028` all hung with 100% CPU.
Comments after `---` and `...` were also cut short at those characters,
leaking the rest of the comment into the document contents.

Use `[^\n\r]|\r(?!\n)` for line content and `(?=\r?\n|$)` for line ends,
matching the lexer's own line handling and the 2.x behaviour.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant