summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--re.c26
-rw-r--r--test/ruby/test_regexp.rb8
3 files changed, 37 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index bb8aaccdcc..d0689e0da3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Thu Jul 25 17:49:42 2013 NARUSE, Yui <naruse@ruby-lang.org>
+
+ * re.c (rb_reg_to_s): convert closing parenthes to the target encoding
+ if it is ASCII incompatible encoding. [ruby-core:56063] [Bug #8650]
+
Thu Jul 25 17:21:21 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* encoding.c (is_obj_encoding): new macro to check if obj is an
diff --git a/re.c b/re.c
index e5cc79d445..dd40918f05 100644
--- a/re.c
+++ b/re.c
@@ -597,8 +597,30 @@ rb_reg_to_s(VALUE re)
}
rb_str_buf_cat2(str, ":");
- rb_reg_expr_str(str, (char*)ptr, len, enc, NULL);
- rb_str_buf_cat2(str, ")");
+ if (rb_enc_asciicompat(enc)) {
+ rb_reg_expr_str(str, (char*)ptr, len, enc, NULL);
+ rb_str_buf_cat2(str, ")");
+ }
+ else {
+ const char *s, *e;
+ char *paren;
+ ptrdiff_t n;
+ rb_str_buf_cat2(str, ")");
+ rb_enc_associate(str, rb_usascii_encoding());
+ str = rb_str_encode(str, rb_enc_from_encoding(enc), 0, Qnil);
+
+ /* backup encoded ")" to paren */
+ s = RSTRING_PTR(str);
+ e = RSTRING_END(str);
+ s = rb_enc_left_char_head(s, e-1, e, enc);
+ n = e - s;
+ paren = ALLOCA_N(char, n);
+ memcpy(paren, s, n);
+ rb_str_resize(str, RSTRING_LEN(str) - n);
+
+ rb_reg_expr_str(str, (char*)ptr, len, enc, NULL);
+ rb_str_buf_cat(str, paren, n);
+ }
rb_enc_copy(str, re);
OBJ_INFECT(str, re);
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index 11e86ec09d..c32b48fe4c 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -64,6 +64,14 @@ class TestRegexp < Test::Unit::TestCase
def test_to_s
assert_equal '(?-mix:\x00)', Regexp.new("\0").to_s
+
+ str = "abcd\u3042"
+ [:UTF_16BE, :UTF_16LE, :UTF_32BE, :UTF_32LE].each do |es|
+ enc = Encoding.const_get(es)
+ rs = Regexp.new(str.encode(enc)).to_s
+ assert_equal("(?-mix:abcd\u3042)".encode(enc), rs)
+ assert_equal(enc, rs.encoding)
+ end
end
def test_union