diff options
| author | Mike Dalessio <mike.dalessio@gmail.com> | 2023-08-19 14:03:35 -0400 |
|---|---|---|
| committer | Kevin Newton <kddnewton@gmail.com> | 2023-08-21 12:22:53 -0400 |
| commit | ac819f4db9bb79ba92547e1abd36336f36633583 (patch) | |
| tree | 326bde22f0a618daf320f435e8574886ccbe32d7 /yarp | |
| parent | f83c1d62bd42c7ba51e715610e9ca2410724d9e0 (diff) | |
[ruby/yarp] fix: support newline-terminated regular expressions
Previously, parsing a snippet like this:
%r\nfoo\n
would result in tracking the second newline twice, resulting in a
failed runtime assertion.
Fixing that issue reveals another bug, which is that the _first_
newline was not being tracked at all. So we introduce a call to
yp_newline_list right when we construct the REGEXP_BEGIN token.
https://github.com/ruby/yarp/commit/0d5d759091
Diffstat (limited to 'yarp')
| -rw-r--r-- | yarp/yarp.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/yarp/yarp.c b/yarp/yarp.c index a61c9e15b8..df6bde14b3 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -6215,6 +6215,9 @@ parser_lex(yp_parser_t *parser) { if (parser->current.end < parser->end) { lex_mode_push_regexp(parser, lex_mode_incrementor(*parser->current.end), lex_mode_terminator(*parser->current.end)); + if (parser->current.end == '\n') { + yp_newline_list_append(&parser->newline_list, parser->current.end); + } parser->current.end++; } @@ -6526,7 +6529,13 @@ parser_lex(yp_parser_t *parser) { // If we've hit a newline, then we need to track that in the // list of newlines. if (*breakpoint == '\n') { - yp_newline_list_append(&parser->newline_list, breakpoint); + // For the special case of a newline-terminated regular expression, we will pass + // through this branch twice -- once with YP_TOKEN_REGEXP_BEGIN and then again + // with YP_TOKEN_STRING_CONTENT. Let's avoid tracking the newline twice, by + // tracking it only in the REGEXP_BEGIN case. + if (!(lex_mode->as.regexp.terminator == '\n' && parser->current.type != YP_TOKEN_REGEXP_BEGIN)) { + yp_newline_list_append(&parser->newline_list, breakpoint); + } if (lex_mode->as.regexp.terminator != '\n') { // If the terminator is not a newline, then we can set |
