[前][次][番号順一覧][スレッド一覧]

ruby-changes:22880

From: nobu <ko1@a...>
Date: Tue, 6 Mar 2012 16:24:25 +0900 (JST)
Subject: [ruby-changes:22880] nobu:r34929 (trunk): * parse.y (parser_tokadd_string): escape simple regexp meta

nobu	2012-03-06 16:24:07 +0900 (Tue, 06 Mar 2012)

  New Revision: 34929

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=34929

  Log:
    * parse.y (parser_tokadd_string): escape simple regexp meta
      character termninators.

  Modified files:
    trunk/ChangeLog
    trunk/parse.y
    trunk/test/ruby/test_regexp.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 34928)
+++ ChangeLog	(revision 34929)
@@ -1,3 +1,8 @@
+Tue Mar  6 16:24:01 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* parse.y (parser_tokadd_string): escape simple regexp meta
+	  character termninators.
+
 Tue Mar  6 10:11:43 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/io/console/console.c (set_rawmode): clear ECHOE and ECHOK
Index: parse.y
===================================================================
--- parse.y	(revision 34928)
+++ parse.y	(revision 34929)
@@ -6440,6 +6440,18 @@
 
 #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 @@
 		    goto non_ascii;
 		}
 		if (func & STR_FUNC_REGEXP) {
-		    if (c == term) {
+		    if (c == term && !simple_re_meta(c)) {
 			tokadd(c);
 			continue;
 		    }
Index: test/ruby/test_regexp.rb
===================================================================
--- test/ruby/test_regexp.rb	(revision 34928)
+++ test/ruby/test_regexp.rb	(revision 34929)
@@ -1,5 +1,5 @@
 require 'test/unit'
-require_relative 'envutil'
+require 'envutil'
 
 class TestRegexp < Test::Unit::TestCase
   def setup
@@ -161,6 +161,40 @@
     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)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]