diff options
Diffstat (limited to 'test/ruby/test_string.rb')
| -rw-r--r-- | test/ruby/test_string.rb | 281 |
1 files changed, 126 insertions, 155 deletions
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index 746471553d..9574ed31c9 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -4,11 +4,6 @@ require 'test/unit' class TestString < Test::Unit::TestCase ENUMERATOR_WANTARRAY = RUBY_VERSION >= "3.0.0" - WIDE_ENCODINGS = [ - Encoding::UTF_16BE, Encoding::UTF_16LE, - Encoding::UTF_32BE, Encoding::UTF_32LE, - ] - def initialize(*args) @cls = String @aref_re_nth = true @@ -17,8 +12,8 @@ class TestString < Test::Unit::TestCase super end - def S(*args, **kw) - @cls.new(*args, **kw) + def S(*args) + @cls.new(*args) end def test_s_new @@ -607,14 +602,18 @@ CODE end def test_clone - for frozen in [ false, true ] - a = S("Cool") - a.freeze if frozen - b = a.clone - - assert_equal(a, b) - assert_not_same(a, b) - assert_equal(a.frozen?, b.frozen?) + for taint in [ false, true ] + for frozen in [ false, true ] + a = S("Cool") + a.taint if taint + a.freeze if frozen + b = a.clone + + assert_equal(a, b) + assert_not_same(a, b) + assert_equal(a.frozen?, b.frozen?) + assert_equal(a.tainted?, b.tainted?) + end end assert_equal("", File.read(IO::NULL).clone, '[ruby-dev:32819] reported by Kazuhiro NISHIYAMA') @@ -661,35 +660,21 @@ CODE assert_raise(ArgumentError) { "foo".count } end - def crypt_supports_des_crypt? - /openbsd/ !~ RUBY_PLATFORM - end - def test_crypt - if crypt_supports_des_crypt? - pass = "aaGUC/JkO9/Sc" - good_salt = "aa" - bad_salt = "ab" - else - pass = "$2a$04$0WVaz0pV3jzfZ5G5tpmHWuBQGbkjzgtSc3gJbmdy0GAGMa45MFM2." - good_salt = "$2a$04$0WVaz0pV3jzfZ5G5tpmHWu" - bad_salt = "$2a$04$0WVaz0pV3jzfZ5G5tpmHXu" - end - assert_equal(S(pass), S("mypassword").crypt(S(good_salt))) - assert_not_equal(S(pass), S("mypassword").crypt(S(bad_salt))) + assert_equal(S('aaGUC/JkO9/Sc'), S("mypassword").crypt(S("aa"))) + assert_not_equal(S('aaGUC/JkO9/Sc'), S("mypassword").crypt(S("ab"))) assert_raise(ArgumentError) {S("mypassword").crypt(S(""))} assert_raise(ArgumentError) {S("mypassword").crypt(S("\0a"))} assert_raise(ArgumentError) {S("mypassword").crypt(S("a\0"))} assert_raise(ArgumentError) {S("poison\u0000null").crypt(S("aa"))} - WIDE_ENCODINGS.each do |enc| + [Encoding::UTF_16BE, Encoding::UTF_16LE, + Encoding::UTF_32BE, Encoding::UTF_32LE].each do |enc| assert_raise(ArgumentError) {S("mypassword").crypt(S("aa".encode(enc)))} assert_raise(ArgumentError) {S("mypassword".encode(enc)).crypt(S("aa"))} end - @cls == String and - assert_no_memory_leak([], "s = ''; salt_proc = proc{#{(crypt_supports_des_crypt? ? '..' : good_salt).inspect}}", "#{<<~"begin;"}\n#{<<~'end;'}") - begin; - 1000.times { s.crypt(-salt_proc.call).clear } + @cls == String and assert_no_memory_leak([], 's = ""', <<~'end;') # do + 1000.times { s.crypt(-"..").clear } end; end @@ -841,20 +826,21 @@ CODE assert_raise(RuntimeError) { S('"\xA"').undump } assert_raise(RuntimeError) { S('"\\"').undump } assert_raise(RuntimeError) { S(%("\0")).undump } - assert_raise_with_message(RuntimeError, /invalid/) { - '"\\u{007F}".xxxxxx'.undump - } end def test_dup - for frozen in [ false, true ] - a = S("hello") - a.freeze if frozen - b = a.dup - - assert_equal(a, b) - assert_not_same(a, b) - assert_not_predicate(b, :frozen?) + for taint in [ false, true ] + for frozen in [ false, true ] + a = S("hello") + a.taint if taint + a.freeze if frozen + b = a.dup + + assert_equal(a, b) + assert_not_same(a, b) + assert_not_predicate(b, :frozen?) + assert_equal(a.tainted?, b.tainted?) + end end end @@ -901,15 +887,20 @@ CODE assert_equal [65, 66, 67], s.bytes {} } else - res = [] - assert_equal s.object_id, s.bytes {|x| res << x }.object_id - assert_equal(65, res[0]) - assert_equal(66, res[1]) - assert_equal(67, res[2]) - s = S("ABC") - res = [] - assert_same s, s.bytes {|x| res << x } - assert_equal [65, 66, 67], res + warning = /passing a block to String#bytes is deprecated/ + assert_warning(warning) { + res = [] + assert_equal s.object_id, s.bytes {|x| res << x }.object_id + assert_equal(65, res[0]) + assert_equal(66, res[1]) + assert_equal(67, res[2]) + } + assert_warning(warning) { + s = S("ABC") + res = [] + assert_same s, s.bytes {|x| res << x } + assert_equal [65, 66, 67], res + } end end @@ -940,15 +931,20 @@ CODE assert_equal [0x3042, 0x3044, 0x3046], s.codepoints {} } else - res = [] - assert_equal s.object_id, s.codepoints {|x| res << x }.object_id - assert_equal(0x3042, res[0]) - assert_equal(0x3044, res[1]) - assert_equal(0x3046, res[2]) - s = S("ABC") - res = [] - assert_same s, s.codepoints {|x| res << x } - assert_equal [65, 66, 67], res + warning = /passing a block to String#codepoints is deprecated/ + assert_warning(warning) { + res = [] + assert_equal s.object_id, s.codepoints {|x| res << x }.object_id + assert_equal(0x3042, res[0]) + assert_equal(0x3044, res[1]) + assert_equal(0x3046, res[2]) + } + assert_warning(warning) { + s = S("ABC") + res = [] + assert_same s, s.codepoints {|x| res << x } + assert_equal [65, 66, 67], res + } end end @@ -973,11 +969,14 @@ CODE assert_equal ["A", "B", "C"], s.chars {} } else - res = [] - assert_equal s.object_id, s.chars {|x| res << x }.object_id - assert_equal("A", res[0]) - assert_equal("B", res[1]) - assert_equal("C", res[2]) + warning = /passing a block to String#chars is deprecated/ + assert_warning(warning) { + res = [] + assert_equal s.object_id, s.chars {|x| res << x }.object_id + assert_equal("A", res[0]) + assert_equal("B", res[1]) + assert_equal("C", res[2]) + } end end @@ -1000,8 +999,8 @@ CODE end [ - ["\u{a 324}", ["\u000A", "\u0324"]], - ["\u{d 324}", ["\u000D", "\u0324"]], + ["\u{a 308}", ["\u000A", "\u0308"]], + ["\u{d 308}", ["\u000D", "\u0308"]], ["abc", ["a", "b", "c"]], ].each do |str, grapheme_clusters| assert_equal grapheme_clusters, str.each_grapheme_cluster.to_a @@ -1024,19 +1023,12 @@ CODE "\u{1F468 200D 1F393}", "\u{1F46F 200D 2642 FE0F}", "\u{1f469 200d 2764 fe0f 200d 1f469}", - ].product([Encoding::UTF_8, *WIDE_ENCODINGS]) do |g, enc| - g = g.encode(enc) + ].each do |g| assert_equal [g], g.grapheme_clusters end - [ - "\u{a 324}", - "\u{d 324}", - "abc", - ].product([Encoding::UTF_8, *WIDE_ENCODINGS]) do |g, enc| - g = g.encode(enc) - assert_equal g.chars, g.grapheme_clusters - end + assert_equal ["\u000A", "\u0308"], "\u{a 308}".grapheme_clusters + assert_equal ["\u000D", "\u0308"], "\u{d 308}".grapheme_clusters assert_equal ["a", "b", "c"], "abc".b.grapheme_clusters if ENUMERATOR_WANTARRAY @@ -1044,13 +1036,15 @@ CODE assert_equal ["A", "B", "C"], "ABC".grapheme_clusters {} } else - s = "ABC".b - res = [] - assert_same s, s.grapheme_clusters {|x| res << x } - assert_equal(3, res.size) - assert_equal("A", res[0]) - assert_equal("B", res[1]) - assert_equal("C", res[2]) + warning = /passing a block to String#grapheme_clusters is deprecated/ + assert_warning(warning) { + s = "ABC".b + res = [] + assert_same s, s.grapheme_clusters {|x| res << x } + assert_equal("A", res[0]) + assert_equal("B", res[1]) + assert_equal("C", res[2]) + } end end @@ -1163,10 +1157,12 @@ CODE assert_equal ["hello\n", "world"], s.lines {} } else - res = [] - assert_equal s.object_id, s.lines {|x| res << x }.object_id - assert_equal(S("hello\n"), res[0]) - assert_equal(S("world"), res[1]) + assert_warning(/passing a block to String#lines is deprecated/) { + res = [] + assert_equal s.object_id, s.lines {|x| res << x }.object_id + assert_equal(S("hello\n"), res[0]) + assert_equal(S("world"), res[1]) + } end end @@ -1199,6 +1195,10 @@ CODE S("hello").gsub(/(hell)(.)/) { |s| $1.upcase + S('-') + $2 }) assert_equal(S("<>h<>e<>l<>l<>o<>"), S("hello").gsub(S(''), S('<\0>'))) + a = S("hello") + a.taint + assert_predicate(a.gsub(/./, S('X')), :tainted?) + assert_equal("z", "abc".gsub(/./, "a" => "z"), "moved from btest/knownbug") assert_raise(ArgumentError) { "foo".gsub } @@ -1243,6 +1243,11 @@ CODE a.gsub!(/(hell)(.)/) { |s| $1.upcase + S('-') + $2 } assert_equal(S("HELL-o"), a) + r = S('X') + r.taint + a.gsub!(/./, r) + assert_predicate(a, :tainted?) + a = S("hello") assert_nil(a.sub!(S('X'), S('Y'))) end @@ -1434,8 +1439,10 @@ CODE assert_equal(S("foobar"), a.replace(S("foobar"))) a = S("foo") + a.taint b = a.replace(S("xyz")) assert_equal(S("xyz"), b) + assert_predicate(b, :tainted?) s = "foo" * 100 s2 = ("bar" * 100).dup @@ -1530,6 +1537,12 @@ CODE a.scan(/(...)/) { |w| res << w } assert_equal([[S("cru")], [S("el ")], [S("wor")]],res) + a = S("hello") + a.taint + res = [] + a.scan(/./) { |w| res << w } + assert_predicate(res[0], :tainted?, '[ruby-core:33338] #4087') + /h/ =~ a a.scan(/x/) assert_nil($~) @@ -1538,6 +1551,8 @@ CODE a.scan('x') assert_nil($~) + assert_equal(3, S("hello hello hello").scan("hello".taint).count(&:tainted?)) + assert_equal(%w[1 2 3], S("a1 a2 a3").scan(/a\K./)) end @@ -1706,51 +1721,10 @@ CODE assert_equal([S("a"), S(""), S("b"), S("c"), S("")], S("a||b|c|").split(S('|'), -1)) assert_equal([], "".split(//, 1)) - ensure - EnvUtil.suppress_warning {$; = fs} - end - - def test_split_with_block - fs, $; = $;, nil - result = []; S(" a b\t c ").split {|s| result << s} - assert_equal([S("a"), S("b"), S("c")], result) - result = []; S(" a b\t c ").split(S(" ")) {|s| result << s} - assert_equal([S("a"), S("b"), S("c")], result) - - result = []; S(" a | b | c ").split(S("|")) {|s| result << s} - assert_equal([S(" a "), S(" b "), S(" c ")], result) - - result = []; S("aXXbXXcXX").split(/X./) {|s| result << s} - assert_equal([S("a"), S("b"), S("c")], result) - - result = []; S("abc").split(//) {|s| result << s} - assert_equal([S("a"), S("b"), S("c")], result) - - result = []; S("a|b|c").split(S('|'), 1) {|s| result << s} - assert_equal([S("a|b|c")], result) - - result = []; S("a|b|c").split(S('|'), 2) {|s| result << s} - assert_equal([S("a"), S("b|c")], result) - result = []; S("a|b|c").split(S('|'), 3) {|s| result << s} - assert_equal([S("a"), S("b"), S("c")], result) - - result = []; S("a|b|c|").split(S('|'), -1) {|s| result << s} - assert_equal([S("a"), S("b"), S("c"), S("")], result) - result = []; S("a|b|c||").split(S('|'), -1) {|s| result << s} - assert_equal([S("a"), S("b"), S("c"), S(""), S("")], result) - - result = []; S("a||b|c|").split(S('|')) {|s| result << s} - assert_equal([S("a"), S(""), S("b"), S("c")], result) - result = []; S("a||b|c|").split(S('|'), -1) {|s| result << s} - assert_equal([S("a"), S(""), S("b"), S("c"), S("")], result) - result = []; "".split(//, 1) {|s| result << s} - assert_equal([], result) - - result = []; "aaa,bbb,ccc,ddd".split(/,/) {|s| result << s.gsub(/./, "A")} - assert_equal(["AAA"]*4, result) + assert_equal("[2, 3]", [1,2,3].slice!(1,10000).inspect, "moved from btest/knownbug") ensure - EnvUtil.suppress_warning {$; = fs} + $; = fs end def test_fs @@ -1758,7 +1732,7 @@ CODE $; = [] } - assert_separately(%W[-W0], "#{<<~"begin;"}\n#{<<~'end;'}") + assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") bug = '[ruby-core:79582] $; must not be GCed' begin; $; = " " @@ -1781,7 +1755,10 @@ CODE def test_split_wchar bug8642 = '[ruby-core:56036] [Bug #8642]' - WIDE_ENCODINGS.each do |enc| + [ + Encoding::UTF_16BE, Encoding::UTF_16LE, + Encoding::UTF_32BE, Encoding::UTF_32LE, + ].each do |enc| s = S("abc,def".encode(enc)) assert_equal(["abc", "def"].map {|c| c.encode(enc)}, s.split(",".encode(enc)), @@ -1808,7 +1785,6 @@ CODE s.split("b", 1).map(&:upcase!) assert_equal("abc", s) end - def test_squeeze assert_equal(S("abc"), S("aaabbbbccc").squeeze) assert_equal(S("aa bb cc"), S("aa bb cc").squeeze(S(" "))) @@ -1914,6 +1890,11 @@ CODE assert_equal(S("a\\&aba"), S("ababa").sub(/b/, '\\\\&')) assert_equal(S("a\\baba"), S("ababa").sub(/b/, '\\\\\&')) + a = S("hello") + a.taint + x = a.sub(/./, S('X')) + assert_predicate(x, :tainted?) + o = Object.new def o.to_str; "bar"; end assert_equal("fooBARbaz", "foobarbaz".sub(o, "BAR")) @@ -1961,6 +1942,11 @@ CODE a=S("hello") assert_nil(a.sub!(/X/, S('Y'))) + r = S('X') + r.taint + a.sub!(/./, r) + assert_predicate(a, :tainted?) + bug16105 = '[Bug #16105] heap-use-after-free' a = S("ABCDEFGHIJKLMNOPQRSTUVWXYZ012345678") b = a.dup @@ -2987,7 +2973,8 @@ CODE def test_ascii_incomat_inspect bug4081 = '[ruby-core:33283]' - WIDE_ENCODINGS.each do |e| + [Encoding::UTF_16LE, Encoding::UTF_16BE, + Encoding::UTF_32LE, Encoding::UTF_32BE].each do |e| assert_equal('"abc"', "abc".encode(e).inspect) assert_equal('"\\u3042\\u3044\\u3046"', "\u3042\u3044\u3046".encode(e).inspect) assert_equal('"ab\\"c"', "ab\"c".encode(e).inspect, bug4081) @@ -3134,22 +3121,6 @@ CODE assert_same(str, -bar, "uminus deduplicates [Feature #13077]") end - def test_uminus_no_freeze_not_bare - str = @cls.new("foo") - assert_instance_of(@cls, -str) - assert_equal(false, str.frozen?) - - str = @cls.new("foo") - str.instance_variable_set(:@iv, 1) - assert_instance_of(@cls, -str) - assert_equal(false, str.frozen?) - assert_equal(1, str.instance_variable_get(:@iv)) - - str = @cls.new("foo") - assert_instance_of(@cls, -str) - assert_equal(false, str.frozen?) - end - def test_ord assert_equal(97, "a".ord) assert_equal(97, "abc".ord) |
