diff options
| author | Mike Dalessio <mike.dalessio@shopify.com> | 2023-08-25 10:12:13 -0400 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2023-08-25 18:20:49 +0000 |
| commit | 3525c460f9a916f8089cbeca65fc3e893ca5d633 (patch) | |
| tree | 00744e62ff3ac00e2875c207415fbfe5997620e7 /yarp | |
| parent | bf3d48e18261595ac19057319f378bfd44928045 (diff) | |
[ruby/yarp] fix: regexes and strings with escaped newline around a heredoc
Found via the fuzzer.
https://github.com/ruby/yarp/commit/501757135a
Co-authored-by: Kevin Newton <kddnewton@gmail.com>
Diffstat (limited to 'yarp')
| -rw-r--r-- | yarp/yarp.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/yarp/yarp.c b/yarp/yarp.c index a7b2290aa2..fdcc303b7f 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -6614,7 +6614,13 @@ parser_lex(yp_parser_t *parser) { case YP_LEX_REGEXP: { // First, we'll set to start of this token to be the current end. - parser->current.start = parser->current.end; + if (parser->next_start == NULL) { + parser->current.start = parser->current.end; + } else { + parser->current.start = parser->next_start; + parser->current.end = parser->next_start; + parser->next_start = NULL; + } // We'll check if we're at the end of the file. If we are, then we need to // return the EOF token. @@ -6693,9 +6699,19 @@ parser_lex(yp_parser_t *parser) { if (*breakpoint == '\\') { size_t difference = yp_unescape_calculate_difference(parser, breakpoint, YP_UNESCAPE_ALL, false); - // If the result is an escaped newline, then we need to - // track that newline. - yp_newline_list_check_append(&parser->newline_list, breakpoint + difference - 1); + // If the result is an escaped newline ... + if (*(breakpoint + difference - 1) == '\n') { + if (parser->heredoc_end) { + // ... if we are on the same line as a heredoc, flush the heredoc and + // continue parsing after heredoc_end. + parser->current.end = breakpoint + difference; + parser_flush_heredoc_end(parser); + LEX(YP_TOKEN_STRING_CONTENT); + } else { + // ... else track the newline. + yp_newline_list_append(&parser->newline_list, breakpoint + difference - 1); + } + } breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); continue; @@ -6833,9 +6849,19 @@ parser_lex(yp_parser_t *parser) { yp_unescape_type_t unescape_type = parser->lex_modes.current->as.string.interpolation ? YP_UNESCAPE_ALL : YP_UNESCAPE_MINIMAL; size_t difference = yp_unescape_calculate_difference(parser, breakpoint, unescape_type, false); - // If the result is an escaped newline, then we need to - // track that newline. - yp_newline_list_check_append(&parser->newline_list, breakpoint + difference - 1); + // If the result is an escaped newline ... + if (*(breakpoint + difference - 1) == '\n') { + if (parser->heredoc_end) { + // ... if we are on the same line as a heredoc, flush the heredoc and + // continue parsing after heredoc_end. + parser->current.end = breakpoint + difference; + parser_flush_heredoc_end(parser); + LEX(YP_TOKEN_STRING_CONTENT); + } else { + // ... else track the newline. + yp_newline_list_append(&parser->newline_list, breakpoint + difference - 1); + } + } breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); break; |
