summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--string.c16
-rw-r--r--test/ruby/test_string.rb7
3 files changed, 28 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 1d97788d0c..0fe3336a1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu Sep 5 18:05:00 2013 Charlie Somerville <charliesome@ruby-lang.org>
+
+ * string.c (fstring_cmp): take string encoding into account when
+ comparing fstrings [ruby-core:57037] [Bug #8866]
+
+ * test/ruby/test_string.rb: add test
+
Thu Sep 5 17:25:49 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* string.c (rb_fstring, rb_str_free): use st_data_t instead of VALUE.
diff --git a/string.c b/string.c
index c1366e834e..af03bc72db 100644
--- a/string.c
+++ b/string.c
@@ -131,11 +131,13 @@ VALUE rb_cSymbol;
#define STR_ENC_GET(str) rb_enc_from_index(ENCODING_GET(str))
+static int fstring_cmp(VALUE a, VALUE b);
+
static st_table* frozen_strings;
static const struct st_hash_type fstring_hash_type = {
- rb_str_cmp,
- rb_str_hash
+ fstring_cmp,
+ rb_str_hash,
};
VALUE
@@ -153,6 +155,16 @@ rb_fstring(VALUE str)
return str;
}
+static int
+fstring_cmp(VALUE a, VALUE b)
+{
+ int cmp = rb_str_hash_cmp(a, b);
+ if (cmp != 0) {
+ return cmp;
+ }
+ return ENCODING_GET(b) - ENCODING_GET(a);
+}
+
static inline int
single_byte_optimizable(VALUE str)
{
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 1387feccf5..4520464105 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -2249,6 +2249,13 @@ class TestString < Test::Unit::TestCase
b = "hello"f
assert_equal a.object_id, b.object_id
end
+
+ def test_frozen_strings_are_deduplicated_with_encoding
+ a = eval("# coding: utf-8\n'hello'f")
+ b = eval("# coding: ascii\n'hello'f")
+ assert_equal Encoding::UTF_8, a.encoding
+ assert_equal Encoding::US_ASCII, b.encoding
+ end
end
class TestString2 < TestString