From 782fd488d7abc7ccb0c8072349182ea8beb902f0 Mon Sep 17 00:00:00 2001 From: naruse Date: Thu, 21 Jan 2016 16:09:09 +0000 Subject: [PATCH] * regparse.c (fetch_name_with_level): allow non word characters at the first character. [Feature #11949] * regparse.c (fetch_name): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53610 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 +++++++ regparse.c | 21 ++++++++++++++------- test/ruby/test_regexp.rb | 7 +++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index b6c0c75721..d86197f6a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Fri Jan 22 00:25:57 2016 NARUSE, Yui + + * regparse.c (fetch_name_with_level): allow non word characters + at the first character. [Feature #11949] + + * regparse.c (fetch_name): ditto. + Thu Jan 21 17:34:01 2016 NARUSE, Yui * marshal.c (r_object0): honor Marshal.load post proc diff --git a/regparse.c b/regparse.c index 094332f90e..d3907de7d9 100644 --- a/regparse.c +++ b/regparse.c @@ -2617,6 +2617,7 @@ get_name_end_code_point(OnigCodePoint start) } #ifdef USE_NAMED_GROUP +#define ONIGENC_IS_CODE_NAME(enc, c) TRUE #ifdef USE_BACKREF_WITH_LEVEL /* \k, \k @@ -2662,7 +2663,7 @@ fetch_name_with_level(OnigCodePoint start_code, UChar** src, UChar* end, sign = -1; pnum_head = p; } - else if (!ONIGENC_IS_CODE_WORD(enc, c)) { + else if (!ONIGENC_IS_CODE_NAME(enc, c)) { r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; } } @@ -2684,7 +2685,7 @@ fetch_name_with_level(OnigCodePoint start_code, UChar** src, UChar* end, is_num = 0; } } - else if (!ONIGENC_IS_CODE_WORD(enc, c)) { + else if (!ONIGENC_IS_CODE_NAME(enc, c)) { r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; } } @@ -2785,7 +2786,7 @@ fetch_name(OnigCodePoint start_code, UChar** src, UChar* end, is_num = 0; } } - else if (!ONIGENC_IS_CODE_WORD(enc, c)) { + else if (!ONIGENC_IS_CODE_NAME(enc, c)) { r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; } } @@ -2795,8 +2796,11 @@ fetch_name(OnigCodePoint start_code, UChar** src, UChar* end, name_end = p; PFETCH_S(c); if (c == end_code || c == ')') { - if (is_num == 2) r = ONIGERR_INVALID_GROUP_NAME; - break; + if (is_num == 2) { + r = ONIGERR_INVALID_GROUP_NAME; + goto teardown; + } + break; } if (is_num != 0) { @@ -2808,12 +2812,13 @@ fetch_name(OnigCodePoint start_code, UChar** src, UChar* end, r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; else r = ONIGERR_INVALID_GROUP_NAME; - is_num = 0; + goto teardown; } } else { - if (!ONIGENC_IS_CODE_WORD(enc, c)) { + if (!ONIGENC_IS_CODE_NAME(enc, c)) { r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; + goto teardown; } } } @@ -2821,6 +2826,7 @@ fetch_name(OnigCodePoint start_code, UChar** src, UChar* end, if (c != end_code) { r = ONIGERR_INVALID_GROUP_NAME; name_end = end; + goto err; } if (is_num != 0) { @@ -2839,6 +2845,7 @@ fetch_name(OnigCodePoint start_code, UChar** src, UChar* end, return 0; } else { + teardown: while (!PEND) { name_end = p; PFETCH_S(c); diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb index 96b0bfacb1..db83ee3ee7 100644 --- a/test/ruby/test_regexp.rb +++ b/test/ruby/test_regexp.rb @@ -142,6 +142,8 @@ class TestRegexp < Test::Unit::TestCase assert_equal("a[b]c", "abc".sub(/(?[bc])/, "[\\k]")) assert_equal("o", "foo"[/(?o)/, "bar"]) + assert_equal("o", "foo"[/(?<@bar>o)/, "@bar"]) + assert_equal("o", "foo"[/(?<@bar>.)\g<@bar>\k<@bar>/, "@bar"]) s = "foo" s[/(?o)/, "bar"] = "baz" @@ -175,6 +177,7 @@ class TestRegexp < Test::Unit::TestCase def test_assign_named_capture assert_equal("a", eval('/(?.)/ =~ "a"; foo')) + assert_equal(nil, eval('/(?<@foo>.)/ =~ "a"; defined?(@foo)')) assert_equal("a", eval('foo = 1; /(?.)/ =~ "a"; foo')) assert_equal("a", eval('1.times {|foo| /(?.)/ =~ "a"; break foo }')) assert_nothing_raised { eval('/(?.)/ =~ "a"') } @@ -939,6 +942,10 @@ class TestRegexp < Test::Unit::TestCase h = {a => 42} assert_equal(42, h[b], '[ruby-core:24748]') assert_match(/#\d+): (?.*)/.match("123456: hoge fuga") + assert_equal("123456", h["@time"]) + assert_equal("hoge fuga", h["body"]) end def test_regexp_poped