diff options
Diffstat (limited to 'test/ruby/test_string.rb')
| -rw-r--r-- | test/ruby/test_string.rb | 377 |
1 files changed, 157 insertions, 220 deletions
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index 4814872789..9574ed31c9 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -2,10 +2,7 @@ require 'test/unit' class TestString < Test::Unit::TestCase - WIDE_ENCODINGS = [ - Encoding::UTF_16BE, Encoding::UTF_16LE, - Encoding::UTF_32BE, Encoding::UTF_32LE, - ] + ENUMERATOR_WANTARRAY = RUBY_VERSION >= "3.0.0" def initialize(*args) @cls = String @@ -15,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 @@ -255,7 +252,6 @@ CODE assert_not_equal(S("CAT"), S('cat')) assert_not_equal(S("CaT"), S('cAt')) - assert_not_equal(S("cat\0""dog"), S("cat\0")) o = Object.new def o.to_str; end @@ -386,8 +382,6 @@ CODE end def test_chomp - verbose, $VERBOSE = $VERBOSE, nil - assert_equal(S("hello"), S("hello").chomp("\n")) assert_equal(S("hello"), S("hello\n").chomp("\n")) save = $/ @@ -453,12 +447,9 @@ CODE assert_equal("foo", s.chomp("\n")) ensure $/ = save - $VERBOSE = verbose end def test_chomp! - verbose, $VERBOSE = $VERBOSE, nil - a = S("hello") a.chomp!(S("\n")) @@ -515,7 +506,6 @@ CODE s = S("").freeze assert_raise_with_message(FrozenError, /frozen/) {s.chomp!} - $VERBOSE = nil # EnvUtil.suppress_warning resets $VERBOSE to the original state s = S("ax") o = Struct.new(:s).new(s) @@ -524,7 +514,6 @@ CODE "x" end assert_raise_with_message(FrozenError, /frozen/) {s.chomp!(o)} - $VERBOSE = nil # EnvUtil.suppress_warning resets $VERBOSE to the original state s = S("hello") assert_equal("hel", s.chomp!('lo')) @@ -575,7 +564,6 @@ CODE assert_equal("foo", s.chomp!("\n")) ensure $/ = save - $VERBOSE = verbose end def test_chop @@ -614,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') @@ -668,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 @@ -758,7 +736,6 @@ CODE assert_equal(S("hello"), S("hello").downcase) assert_equal(S("hello"), S("HELLO").downcase) assert_equal(S("abc hello 123"), S("abc HELLO 123").downcase) - assert_equal(S("h\0""ello"), S("h\0""ELLO").downcase) end def test_downcase! @@ -771,12 +748,6 @@ CODE a=S("hello") assert_nil(a.downcase!) assert_equal(S("hello"), a) - - a = S("h\0""ELLO") - b = a.dup - assert_equal(S("h\0""ello"), a.downcase!) - assert_equal(S("h\0""ello"), a) - assert_equal(S("h\0""ELLO"), b) end def test_dump @@ -855,26 +826,25 @@ 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 def test_each - verbose, $VERBOSE = $VERBOSE, nil - save = $/ $/ = "\n" res=[] @@ -894,7 +864,6 @@ CODE assert_equal(S("world"), res[1]) ensure $/ = save - $VERBOSE = verbose end def test_each_byte @@ -913,15 +882,26 @@ CODE s = S("ABC") assert_equal [65, 66, 67], s.bytes - 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 + if ENUMERATOR_WANTARRAY + assert_warn(/block not used/) { + assert_equal [65, 66, 67], s.bytes {} + } + else + 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 def test_each_codepoint @@ -946,15 +926,26 @@ CODE s = S("\u3042\u3044\u3046") assert_equal [0x3042, 0x3044, 0x3046], s.codepoints - 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 + if ENUMERATOR_WANTARRAY + assert_warn(/block not used/) { + assert_equal [0x3042, 0x3044, 0x3046], s.codepoints {} + } + else + 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 def test_each_char @@ -973,11 +964,20 @@ CODE s = S("ABC") assert_equal ["A", "B", "C"], s.chars - 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]) + if ENUMERATOR_WANTARRAY + assert_warn(/block not used/) { + assert_equal ["A", "B", "C"], s.chars {} + } + else + 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 def test_each_grapheme_cluster @@ -999,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 @@ -1023,33 +1023,32 @@ 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 - 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]) + if ENUMERATOR_WANTARRAY + assert_warn(/block not used/) { + assert_equal ["A", "B", "C"], "ABC".grapheme_clusters {} + } + else + 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 def test_each_line - verbose, $VERBOSE = $VERBOSE, nil - save = $/ $/ = "\n" res=[] @@ -1096,7 +1095,6 @@ CODE end ensure $/ = save - $VERBOSE = verbose end def test_each_line_chomp @@ -1154,10 +1152,18 @@ CODE assert_equal ["hello\n", "world"], s.lines assert_equal ["hello\nworld"], s.lines(nil) - 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]) + if ENUMERATOR_WANTARRAY + assert_warn(/block not used/) { + assert_equal ["hello\n", "world"], s.lines {} + } + else + 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 def test_empty? @@ -1189,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 } @@ -1233,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 @@ -1321,8 +1336,6 @@ CODE assert_nil("foo".index(//, -100)) assert_nil($~) - - assert_equal(2, S("abcdbce").index(/b\Kc/)) end def test_insert @@ -1426,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 @@ -1495,8 +1510,6 @@ CODE assert_equal(3, "foo".rindex(//)) assert_equal([3, 3], $~.offset(0)) - - assert_equal(5, S("abcdbce").rindex(/b\Kc/)) end def test_rjust @@ -1524,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($~) @@ -1532,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 @@ -1588,10 +1609,8 @@ CODE a = S("FooBar") if @aref_slicebang_silent assert_nil( a.slice!(6) ) - assert_nil( a.slice!(6r) ) else assert_raise(IndexError) { a.slice!(6) } - assert_raise(IndexError) { a.slice!(6r) } end assert_equal(S("FooBar"), a) @@ -1702,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 @@ -1754,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; $; = " " @@ -1777,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)), @@ -1804,12 +1785,6 @@ CODE s.split("b", 1).map(&:upcase!) assert_equal("abc", s) end - - def test_split_lookbehind - assert_equal([S("ab"), S("d")], S("abcd").split(/(?<=b)c/)) - assert_equal([S("ab"), S("d")], S("abcd").split(/b\Kc/)) - end - def test_squeeze assert_equal(S("abc"), S("aaabbbbccc").squeeze) assert_equal(S("aa bb cc"), S("aa bb cc").squeeze(S(" "))) @@ -1915,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")) @@ -1962,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 @@ -2089,8 +2074,6 @@ CODE def test_swapcase assert_equal(S("hi&LOW"), S("HI&low").swapcase) - s = S("") - assert_not_same(s, s.swapcase) end def test_swapcase! @@ -2326,7 +2309,6 @@ CODE assert_equal(S("HELLO"), S("hello").upcase) assert_equal(S("HELLO"), S("HELLO").upcase) assert_equal(S("ABC HELLO 123"), S("abc HELLO 123").upcase) - assert_equal(S("H\0""ELLO"), S("H\0""ello").upcase) end def test_upcase! @@ -2339,12 +2321,6 @@ CODE a = S("HELLO") assert_nil(a.upcase!) assert_equal(S("HELLO"), a) - - a = S("H\0""ello") - b = a.dup - assert_equal(S("H\0""ELLO"), a.upcase!) - assert_equal(S("H\0""ELLO"), a) - assert_equal(S("H\0""ello"), b) end def test_upto @@ -2570,10 +2546,6 @@ CODE hello = "hello" hello.partition("hi").map(&:upcase!) assert_equal("hello", hello, bug) - - assert_equal(["", "", "foo"], "foo".partition(/^=*/)) - - assert_equal([S("ab"), S("c"), S("dbce")], S("abcdbce").partition(/b\Kc/)) end def test_rpartition @@ -2598,8 +2570,6 @@ CODE hello = "hello" hello.rpartition("hi").map(&:upcase!) assert_equal("hello", hello, bug) - - assert_equal([S("abcdb"), S("c"), S("e")], S("abcdbce").rpartition(/b\Kc/)) end def test_setter @@ -2667,7 +2637,6 @@ CODE assert_equal(1, "FoO".casecmp("BaR")) assert_equal(-1, "baR".casecmp("FoO")) assert_equal(1, "\u3042B".casecmp("\u3042a")) - assert_equal(-1, "foo".casecmp("foo\0")) assert_nil("foo".casecmp(:foo)) assert_nil("foo".casecmp(Object.new)) @@ -2682,7 +2651,6 @@ CODE assert_equal(false, 'FoO'.casecmp?('BaR')) assert_equal(false, 'baR'.casecmp?('FoO')) assert_equal(true, 'äöü'.casecmp?('ÄÖÜ')) - assert_equal(false, "foo".casecmp?("foo\0")) assert_nil("foo".casecmp?(:foo)) assert_nil("foo".casecmp?(Object.new)) @@ -3005,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) @@ -3152,38 +3121,6 @@ CODE assert_same(str, -bar, "uminus deduplicates [Feature #13077]") end - def test_uminus_frozen - # embedded - str1 = ("foobar" * 3).freeze - str2 = ("foobar" * 3).freeze - assert_not_same str1, str2 - assert_same str1, -str1 - assert_same str1, -str2 - - # regular - str1 = ("foobar" * 4).freeze - str2 = ("foobar" * 4).freeze - assert_not_same str1, str2 - assert_same str1, -str1 - assert_same str1, -str2 - 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) |
