summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--re.c9
-rw-r--r--test/ruby/test_regexp.rb12
2 files changed, 17 insertions, 4 deletions
diff --git a/re.c b/re.c
index f3be9a1fce..e51b782cf6 100644
--- a/re.c
+++ b/re.c
@@ -565,8 +565,6 @@ rb_reg_str_with_term(VALUE re, int term)
{
int options, opt;
const int embeddable = ONIG_OPTION_MULTILINE|ONIG_OPTION_IGNORECASE|ONIG_OPTION_EXTEND;
- long len;
- const UChar* ptr;
VALUE str = rb_str_buf_new2("(?");
char optbuf[OPTBUF_SIZE + 1]; /* for '-' */
rb_encoding *enc = rb_enc_get(re);
@@ -575,8 +573,9 @@ rb_reg_str_with_term(VALUE re, int term)
rb_enc_copy(str, re);
options = RREGEXP_PTR(re)->options;
- ptr = (UChar*)RREGEXP_SRC_PTR(re);
- len = RREGEXP_SRC_LEN(re);
+ VALUE src_str = RREGEXP_SRC(re);
+ const UChar *ptr = (UChar *)RSTRING_PTR(src_str);
+ long len = RSTRING_LEN(src_str);
again:
if (len >= 4 && ptr[0] == '(' && ptr[1] == '?') {
int err = 1;
@@ -666,6 +665,8 @@ rb_reg_str_with_term(VALUE re, int term)
}
rb_enc_copy(str, re);
+ RB_GC_GUARD(src_str);
+
return str;
}
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index 4d94702502..77e9ca67f6 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -72,6 +72,18 @@ class TestRegexp < Test::Unit::TestCase
end
end
+ def test_to_s_under_gc_compact_stress
+ EnvUtil.under_gc_compact_stress do
+ 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
+ end
+
def test_to_s_extended_subexp
re = /#\g#{"\n"}/x
re = /#{re}/