summaryrefslogtreecommitdiff
path: root/yarp
diff options
context:
space:
mode:
authorMike Dalessio <mike.dalessio@shopify.com>2023-08-25 10:12:13 -0400
committergit <svn-admin@ruby-lang.org>2023-08-25 18:20:49 +0000
commit3525c460f9a916f8089cbeca65fc3e893ca5d633 (patch)
tree00744e62ff3ac00e2875c207415fbfe5997620e7 /yarp
parentbf3d48e18261595ac19057319f378bfd44928045 (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.c40
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;