aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-06 07:24:07 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-06 07:24:07 +0000
commitbc6dde94202d8c75ac2efae6a7667202c6cb3bb6 (patch)
treedc1962ba4783410c1d707f3bd64c6bd63601ddf5
parent8a4de7abf8850f330f9201fb07aba16a622d1fd2 (diff)
downloadruby-bc6dde94202d8c75ac2efae6a7667202c6cb3bb6.tar.gz
* parse.y (parser_tokadd_string): escape simple regexp meta
character termninators. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34929 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--parse.y14
-rw-r--r--test/ruby/test_regexp.rb36
3 files changed, 53 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index f933741bec..5572ee6162 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Mar 6 16:24:01 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (parser_tokadd_string): escape simple regexp meta
+ character termninators.
+
Tue Mar 6 10:11:43 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/io/console/console.c (set_rawmode): clear ECHOE and ECHOK
diff --git a/parse.y b/parse.y
index 4796e7453c..252860bc7e 100644
--- a/parse.y
+++ b/parse.y
@@ -6440,6 +6440,18 @@ parser_tokadd_mbchar(struct parser_params *parser, int c)
#define tokadd_mbchar(c) parser_tokadd_mbchar(parser, (c))
+static inline int
+simple_re_meta(int c)
+{
+ switch (c) {
+ case '$': case '*': case '+': case '.':
+ case '?': case '^': case '|':
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
static int
parser_tokadd_string(struct parser_params *parser,
int func, int term, int paren, long *nest,
@@ -6520,7 +6532,7 @@ parser_tokadd_string(struct parser_params *parser,
goto non_ascii;
}
if (func & STR_FUNC_REGEXP) {
- if (c == term) {
+ if (c == term && !simple_re_meta(c)) {
tokadd(c);
continue;
}
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index 95dbb2b9d3..7e31e99aa7 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -1,5 +1,5 @@
require 'test/unit'
-require_relative 'envutil'
+require 'envutil'
class TestRegexp < Test::Unit::TestCase
def setup
@@ -161,6 +161,40 @@ class TestRegexp < Test::Unit::TestCase
assert_equal(':', %r:\::.source, bug5484)
end
+ def test_source_escaped
+ expected, result = "$*+.?^|".each_char.map {|c|
+ [
+ ["\\#{c}", "\\#{c}", 1],
+ begin
+ re = eval("%r#{c}\\#{c}#{c}", nil, __FILE__, __LINE__)
+ t = eval("/\\#{c}/", nil, __FILE__, __LINE__).source
+ rescue SyntaxError => e
+ [e, t, nil]
+ else
+ [re.source, t, re =~ "a#{c}a"]
+ end
+ ]
+ }.transpose
+ assert_equal(expected, result)
+ end
+
+ def test_source_unescaped
+ expected, result = "!\"#%&',-/:;=@_`~".each_char.map {|c|
+ [
+ ["#{c}", "\\#{c}", 1],
+ begin
+ re = eval("%r#{c}\\#{c}#{c}", nil, __FILE__, __LINE__)
+ t = eval("%r{\\#{c}}", nil, __FILE__, __LINE__).source
+ rescue SyntaxError => e
+ [e, t, nil]
+ else
+ [re.source, t, re =~ "a#{c}a"]
+ end
+ ]
+ }.transpose
+ assert_equal(expected, result)
+ end
+
def test_inspect
assert_equal('//', //.inspect)
assert_equal('//i', //i.inspect)