diff options
author | Nobuyoshi Nakada <[email protected]> | 2023-12-01 13:04:42 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2023-12-01 15:04:30 +0900 |
commit | d503e1b95a40e45d7767e0175de60092de4ba54e (patch) | |
tree | 3804881a722be63f4a2b6952cf6f6198fd615c80 | |
parent | 52c2660163240a494b65eb9942c3978896ed807b (diff) |
[Bug #20030] dispatch invalid escaped character without ignoring it
-rw-r--r-- | parse.y | 18 | ||||
-rw-r--r-- | test/ripper/test_scanner_events.rb | 6 | ||||
-rw-r--r-- | test/ruby/test_parse.rb | 4 |
3 files changed, 26 insertions, 2 deletions
@@ -7878,6 +7878,16 @@ tokadd_codepoint(struct parser_params *p, rb_encoding **encp, static int tokadd_mbchar(struct parser_params *p, int c); +static int +tokskip_mbchar(struct parser_params *p) +{ + int len = parser_precise_mbclen(p, p->lex.pcur-1); + if (len > 0) { + p->lex.pcur += len - 1; + } + return len; +} + /* return value is for ?\u3042 */ static void tokadd_utf8(struct parser_params *p, rb_encoding **encp, @@ -8065,7 +8075,11 @@ read_escape(struct parser_params *p, int flags) } else if (c == '?') return 0177; - else if (c == -1 || !ISASCII(c)) goto eof; + else if (c == -1) goto eof; + else if (!ISASCII(c)) { + tokskip_mbchar(p); + goto eof; + } else { int c2 = escaped_control_code(c); if (c2) { @@ -8093,7 +8107,7 @@ read_escape(struct parser_params *p, int flags) eof: case -1: yyerror0("Invalid escape character syntax"); - token_flush(p); + dispatch_scan_event(p, tSTRING_CONTENT); return '\0'; default: diff --git a/test/ripper/test_scanner_events.rb b/test/ripper/test_scanner_events.rb index 8434cc9c40..9739cdb1eb 100644 --- a/test/ripper/test_scanner_events.rb +++ b/test/ripper/test_scanner_events.rb @@ -991,6 +991,12 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase assert_equal("\e", err[2]) end + def test_invalid_escape + err = nil + assert_equal ["\\C-\u{3042}"], scan('tstring_content', %["\\C-\u{3042}"]) {|*e| err = e} + assert_equal [:on_parse_error, "Invalid escape character syntax", "\\C-\u{3042}"], err + end + def test_invalid_hex_escape err = nil assert_equal ['U'], scan('tstring_content', '"\\xU"') {|*e| err = e} diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb index 2960a3c295..6121205857 100644 --- a/test/ruby/test_parse.rb +++ b/test/ruby/test_parse.rb @@ -603,6 +603,10 @@ class TestParse < Test::Unit::TestCase assert_equal(' ^~~~~'"\n", e.message.lines.last) e = assert_syntax_error('"\M-\U0000"', 'Invalid escape character syntax') assert_equal(' ^~~~~'"\n", e.message.lines.last) + + e = assert_syntax_error(%["\\C-\u3042"], 'Invalid escape character syntax') + assert_match(/^\s \^(?# \\ ) ~(?# C ) ~(?# - ) ~+(?# U+3042 )$/x, e.message.lines.last) + assert_not_include(e.message, "invalid multibyte char") end def test_question |