summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--string.c7
-rw-r--r--test/ruby/test_string.rb13
3 files changed, 22 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index c28c11de8..ea7d32856 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Aug 12 12:59:51 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * string.c (rb_str_new_frozen): must not change encoding of frozen
+ shared string. [ruby-dev:39068]
+
Wed Aug 12 11:51:51 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* configure.in (rb_cv_broken_crypt): needs more checks.
diff --git a/string.c b/string.c
index 06edf3b8d..39df54b19 100644
--- a/string.c
+++ b/string.c
@@ -671,13 +671,14 @@ rb_str_new_frozen(VALUE orig)
assert(OBJ_FROZEN(str));
ofs = RSTRING_LEN(str) - RSTRING_LEN(orig);
if ((ofs > 0) || (klass != RBASIC(str)->klass) ||
- (!OBJ_TAINTED(str) && OBJ_TAINTED(orig))) {
+ (!OBJ_TAINTED(str) && OBJ_TAINTED(orig)) ||
+ ENCODING_GET(str) != ENCODING_GET(orig)) {
str = str_new3(klass, str);
RSTRING(str)->as.heap.ptr += ofs;
RSTRING(str)->as.heap.len -= ofs;
+ rb_enc_cr_str_exact_copy(str, orig);
+ OBJ_INFECT(str, orig);
}
- rb_enc_cr_str_exact_copy(str, orig);
- OBJ_INFECT(str, orig);
}
else if (STR_EMBED_P(orig)) {
str = str_new(klass, RSTRING_PTR(orig), RSTRING_LEN(orig));
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 1d65c84c1..36968cae3 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -1791,4 +1791,17 @@ class TestString < Test::Unit::TestCase
("aaaaaaaa".."zzzzzzzz").each {|s| s.to_sym }
INPUT
end
+
+ def test_shared_force_encoding
+ s = "\u{3066}\u{3059}\u{3068}".gsub(//, '')
+ h = {}
+ h[s] = nil
+ k = h.keys[0]
+ assert_equal(s, k, '[ruby-dev:39068]')
+ assert_equal(Encoding::UTF_8, k.encoding, '[ruby-dev:39068]')
+ s.dup.force_encoding(Encoding::ASCII_8BIT).gsub(//, '')
+ k = h.keys[0]
+ assert_equal(s, k, '[ruby-dev:39068]')
+ assert_equal(Encoding::UTF_8, k.encoding, '[ruby-dev:39068]')
+ end
end