diff options
Diffstat (limited to 'test/-ext-/string')
| -rw-r--r-- | test/-ext-/string/test_capacity.rb | 45 | ||||
| -rw-r--r-- | test/-ext-/string/test_cstr.rb | 6 | ||||
| -rw-r--r-- | test/-ext-/string/test_fstring.rb | 34 | ||||
| -rw-r--r-- | test/-ext-/string/test_interned_str.rb | 5 | ||||
| -rw-r--r-- | test/-ext-/string/test_rb_str_dup.rb | 6 | ||||
| -rw-r--r-- | test/-ext-/string/test_set_len.rb | 57 | ||||
| -rw-r--r-- | test/-ext-/string/test_too_many_dummy_encodings.rb | 15 |
7 files changed, 131 insertions, 37 deletions
diff --git a/test/-ext-/string/test_capacity.rb b/test/-ext-/string/test_capacity.rb index df59e76778..a23892142a 100644 --- a/test/-ext-/string/test_capacity.rb +++ b/test/-ext-/string/test_capacity.rb @@ -2,29 +2,29 @@ require 'test/unit' require '-test-/string' require 'rbconfig/sizeof' +require 'objspace' class Test_StringCapacity < Test::Unit::TestCase - def capa(str) - Bug::String.capacity(str) - end - def test_capacity_embedded - size = RbConfig::SIZEOF['void*'] * 3 - 1 - assert_equal size, capa('foo') + assert_equal pool_slot_size(0) - embed_header_size - 1, capa('foo') + assert_equal max_embed_len, capa('1' * max_embed_len) + assert_equal max_embed_len, capa('1' * (max_embed_len - 1)) end def test_capacity_shared - assert_equal 0, capa(:abcdefghijklmnopqrstuvwxyz.to_s) + sym = ("a" * pool_slot_size(0)).to_sym + assert_equal 0, capa(sym.to_s) end def test_capacity_normal - assert_equal 128, capa('1'*128) + assert_equal max_embed_len + 1, capa('1' * (max_embed_len + 1)) + assert_equal max_embed_len + 100, capa('1' * (max_embed_len + 100)) end def test_s_new_capacity assert_equal("", String.new(capacity: 1000)) assert_equal(String, String.new(capacity: 1000).class) - assert_equal(10000, capa(String.new(capacity: 10000))) + assert_equal(10_000, capa(String.new(capacity: 10_000))) assert_equal("", String.new(capacity: -1000)) assert_equal(capa(String.new(capacity: -10000)), capa(String.new(capacity: -1000))) @@ -39,21 +39,42 @@ class Test_StringCapacity < Test::Unit::TestCase end def test_literal_capacity - s = "I am testing string literal capacity" + s = eval(%{ + # frozen_string_literal: true + "#{"a" * (max_embed_len + 1)}" + }) assert_equal(s.length, capa(s)) end def test_capacity_frozen s = String.new("I am testing", capacity: 1000) - s << "fstring capacity" + s << "a" * pool_slot_size(0) s.freeze assert_equal(s.length, capa(s)) end def test_capacity_fstring - s = String.new("I am testing", capacity: 1000) + s = String.new("a" * max_embed_len, capacity: max_embed_len * 3) s << "fstring capacity" s = -s assert_equal(s.length, capa(s)) end + + private + + def capa(str) + Bug::String.capacity(str) + end + + def embed_header_size + GC::INTERNAL_CONSTANTS[:RBASIC_SIZE] + RbConfig::SIZEOF['void*'] + end + + def pool_slot_size(_idx = 0) + Integer(ObjectSpace.dump("")[/"slot_size":(\d+)/, 1]) + end + + def max_embed_len + GC::INTERNAL_CONSTANTS[:RVARGC_MAX_ALLOCATE_SIZE] - embed_header_size - 1 + end end diff --git a/test/-ext-/string/test_cstr.rb b/test/-ext-/string/test_cstr.rb index d909781700..efc64119dc 100644 --- a/test/-ext-/string/test_cstr.rb +++ b/test/-ext-/string/test_cstr.rb @@ -43,7 +43,11 @@ class Test_StringCStr < Test::Unit::TestCase end def test_rb_str_new_frozen_embed - str = Bug::String.cstr_noembed("rbconfig.rb") + # "rbconfi" is the smallest "maximum embeddable string". VWA adds + # a capacity field, which removes one pointer capacity for embedded objects, + # so if VWA is enabled, but there is only one size pool, then the + # maximum embeddable capacity on 32 bit machines is 8 bytes. + str = Bug::String.cstr_noembed("rbconfi") str = Bug::String.rb_str_new_frozen(str) assert_equal true, Bug::String.cstr_embedded?(str) end diff --git a/test/-ext-/string/test_fstring.rb b/test/-ext-/string/test_fstring.rb index 9b4956ecef..fcec6be543 100644 --- a/test/-ext-/string/test_fstring.rb +++ b/test/-ext-/string/test_fstring.rb @@ -15,19 +15,27 @@ class Test_String_Fstring < Test::Unit::TestCase def test_rb_enc_interned_str_autoloaded_encoding assert_separately([], <<~RUBY) require '-test-/string' - assert_include(Encoding::Windows_31J.inspect, 'autoload') - Bug::String.rb_enc_interned_str(Encoding::Windows_31J) + assert_include(Encoding::CESU_8.inspect, 'autoload') + Bug::String.rb_enc_interned_str(Encoding::CESU_8) RUBY end + def test_rb_enc_interned_str_null_encoding + assert_equal Encoding::ASCII_8BIT, Bug::String.rb_enc_interned_str(nil).encoding + end + def test_rb_enc_str_new_autoloaded_encoding assert_separately([], <<~RUBY) require '-test-/string' - assert_include(Encoding::Windows_31J.inspect, 'autoload') - Bug::String.rb_enc_str_new(Encoding::Windows_31J) + assert_include(Encoding::CESU_8.inspect, 'autoload') + Bug::String.rb_enc_str_new(Encoding::CESU_8) RUBY end + def test_rb_enc_str_new_null_encoding + assert_equal Encoding::ASCII_8BIT, Bug::String.rb_enc_str_new(nil).encoding + end + def test_instance_variable str = __method__.to_s * 3 str.instance_variable_set(:@test, 42) @@ -49,6 +57,10 @@ class Test_String_Fstring < Test::Unit::TestCase assert_raise(TypeError) {fstr.singleton_class} end + def test_fake_str + assert_equal([*"a".."z"].join(""), Bug::String.fstring_fake_str) + end + class S < String end @@ -57,18 +69,4 @@ class Test_String_Fstring < Test::Unit::TestCase str.freeze assert_fstring(str) {|s| assert_instance_of(S, s)} end - - def test_shared_string_safety - _unused = -('a' * 30).force_encoding(Encoding::ASCII) - begin - verbose_back, $VERBOSE = $VERBOSE, nil - str = ('a' * 30).force_encoding(Encoding::ASCII).taint - ensure - $VERBOSE = verbose_back - end - frozen_str = Bug::String.rb_str_new_frozen(str) - assert_fstring(frozen_str) {|s| assert_equal(str, s)} - GC.start - assert_equal('a' * 30, str, "[Bug #16151]") - end end diff --git a/test/-ext-/string/test_interned_str.rb b/test/-ext-/string/test_interned_str.rb index 340dba41e8..a81cb59aa5 100644 --- a/test/-ext-/string/test_interned_str.rb +++ b/test/-ext-/string/test_interned_str.rb @@ -9,4 +9,9 @@ class Test_RbInternedStr < Test::Unit::TestCase src << "b" * 20 assert_equal "a" * 20, interned_str end + + def test_interned_str_encoding + src = :ascii.name + assert_equal Encoding::US_ASCII, Bug::String.rb_interned_str_dup(src).encoding + end end diff --git a/test/-ext-/string/test_rb_str_dup.rb b/test/-ext-/string/test_rb_str_dup.rb index 49b6af9598..c76a90252f 100644 --- a/test/-ext-/string/test_rb_str_dup.rb +++ b/test/-ext-/string/test_rb_str_dup.rb @@ -3,13 +3,15 @@ require '-test-/string' class Test_RbStrDup < Test::Unit::TestCase def test_nested_shared_non_frozen - str = Bug::String.rb_str_dup(Bug::String.rb_str_dup("a" * 50)) + orig_str = "a" * GC::INTERNAL_CONSTANTS[:RVARGC_MAX_ALLOCATE_SIZE] + str = Bug::String.rb_str_dup(Bug::String.rb_str_dup(orig_str)) assert_send([Bug::String, :shared_string?, str]) assert_not_send([Bug::String, :sharing_with_shared?, str], '[Bug #15792]') end def test_nested_shared_frozen - str = Bug::String.rb_str_dup(Bug::String.rb_str_dup("a" * 50).freeze) + orig_str = "a" * GC::INTERNAL_CONSTANTS[:RVARGC_MAX_ALLOCATE_SIZE] + str = Bug::String.rb_str_dup(Bug::String.rb_str_dup(orig_str).freeze) assert_send([Bug::String, :shared_string?, str]) assert_not_send([Bug::String, :sharing_with_shared?, str], '[Bug #15792]') end diff --git a/test/-ext-/string/test_set_len.rb b/test/-ext-/string/test_set_len.rb index 58f51012fb..41e14a293a 100644 --- a/test/-ext-/string/test_set_len.rb +++ b/test/-ext-/string/test_set_len.rb @@ -4,23 +4,25 @@ require "-test-/string" class Test_StrSetLen < Test::Unit::TestCase def setup - @s0 = [*"a".."z"].join("").freeze + # Make string long enough so that it is not embedded + @range_end = ("0".ord + GC.stat_heap(0, :slot_size)).chr + @s0 = [*"0"..@range_end].join("").freeze @s1 = Bug::String.new(@s0) end def teardown - orig = [*"a".."z"].join("") + orig = [*"0"..@range_end].join("") assert_equal(orig, @s0) end def test_non_shared @s1.modify! - assert_equal("abc", @s1.set_len(3)) + assert_equal("012", @s1.set_len(3)) end def test_shared assert_raise(RuntimeError) { - assert_equal("abc", @s1.set_len(3)) + @s1.set_len(3) } end @@ -32,4 +34,51 @@ class Test_StrSetLen < Test::Unit::TestCase assert_equal 128, Bug::String.capacity(str) assert_equal 127, str.set_len(127).bytesize, bug12757 end + + def test_coderange_after_append + u = -"\u3042" + str = Bug::String.new(encoding: Encoding::UTF_8) + bsize = u.bytesize + str.append(u) + assert_equal 0, str.bytesize + str.set_len(bsize) + assert_equal bsize, str.bytesize + assert_predicate str, :valid_encoding? + assert_not_predicate str, :ascii_only? + assert_equal u, str + end + + def test_coderange_after_trunc + u = -"\u3042" + bsize = u.bytesize + str = Bug::String.new(u) + str.set_len(bsize - 1) + assert_equal bsize - 1, str.bytesize + assert_not_predicate str, :valid_encoding? + assert_not_predicate str, :ascii_only? + str.append(u.byteslice(-1)) + str.set_len(bsize) + assert_equal bsize, str.bytesize + assert_predicate str, :valid_encoding? + assert_not_predicate str, :ascii_only? + assert_equal u, str + end + + def test_valid_encoding_after_resized + s = "\0\0".force_encoding(Encoding::UTF_16BE) + str = Bug::String.new(s) + assert_predicate str, :valid_encoding? + str.resize(1) + assert_not_predicate str, :valid_encoding? + str.resize(2) + assert_predicate str, :valid_encoding? + str.resize(3) + assert_not_predicate str, :valid_encoding? + + s = "\xDB\x00\xDC\x00".force_encoding(Encoding::UTF_16BE) + str = Bug::String.new(s) + assert_predicate str, :valid_encoding? + str.resize(2) + assert_not_predicate str, :valid_encoding? + end end diff --git a/test/-ext-/string/test_too_many_dummy_encodings.rb b/test/-ext-/string/test_too_many_dummy_encodings.rb new file mode 100644 index 0000000000..b96b40db7b --- /dev/null +++ b/test/-ext-/string/test_too_many_dummy_encodings.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: false +require 'test/unit' +require "-test-/string" + +class Test_TooManyDummyEncodings < Test::Unit::TestCase + def test_exceed_encoding_table_size + assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + require "-test-/string" + assert_raise_with_message(EncodingError, /too many encoding/) do + 1_000.times{|i| Bug::String.rb_define_dummy_encoding("R_#{i}") } # now 256 entries + end + end; + end +end |
