From: s.wanabe@... Date: 2019-04-26T20:21:26+00:00 Subject: [ruby-core:92424] [Ruby trunk Bug#15792] GC can leave strings used as hash keys in a corrupted state Issue #15792 has been updated by wanabe (_ wanabe). I guess it is caused by the combination of `str_duplicate` and `rb_fstring` from r52074. ``` $ cat bug15792.rb a = ('a' * 24).b.strip ->{ eval "", binding, a, 1 }.call puts "Before garbage_collection: a=#{a.inspect}" 4.times { GC.start } puts "After garbage_collection: a=#{a.inspect}" $ ./miniruby -v bug15792.rb ruby 2.3.0dev (2015-10-07 trunk 52074) [x86_64-linux] Before garbage_collection: a="aaaaaaaaaaaaaaaaaaaaaaaa" After garbage_collection: a="\x00B\xFB\xCCmU\x00\x00\x10\x10\xE7\xCCmU\x00\x00aaaaaaaa" ``` ---------------------------------------- Bug #15792: GC can leave strings used as hash keys in a corrupted state https://bugs.ruby-lang.org/issues/15792#change-77780 * Author: byroot (Jean Boussier) * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: 2.6.2 * Backport: 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: UNKNOWN ---------------------------------------- The following script showcase the issue: ``` #!/usr/bin/env ruby --disable-gems a = ('a' * 24).encode(Encoding::ASCII).gsub('x', '') b = ('b' * 24).encode(Encoding::ASCII).gsub('x', '') hash = {} hash[a] = true hash[b] = true puts "Bebore garbage_collection: a=#{a.inspect} b=#{b.inspect}" 4.times { GC.start } puts "After garbage_collection: a=#{a.inspect} b=#{b.inspect}" ``` Expected output: ``` Bebore garbage_collection: a="aaaaaaaaaaaaaaaaaaaaaaaa" b="bbbbbbbbbbbbbbbbbbbbbbbb" After garbage_collection: a="aaaaaaaaaaaaaaaaaaaaaaaa" b="bbbbbbbbbbbbbbbbbbbbbbbb" ``` Actual output: ``` Ruby: 2.6.2 Bebore garbage_collection: a="aaaaaaaaaaaaaaaaaaaaaaaa" b="bbbbbbbbbbbbbbbbbbbbbbbb" After garbage_collection: a="}\x0Eu\xDB\xFC\a\x00\x80\xE9\ru\xDB\xFC\a\x00\x10\x04\x00aaaaaa" b="\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x00\xC0\x02\x00bbbbbb" ``` We reduced the repro script as much as we could, both the `.encode(ASCII)` and the `gsub` are necessary for the bug to manifest itself. We also used `ObjectSpace.dump()` to analyze the corrupted string. ``` b = "shared":true, "encoding":"US-ASCII", "references":["0x7faf4a01aeb8"] 0x7faf4a01aeb8 = "frozen":true, "fstring":true, "bytesize":24, "value":"bbbbbbbbbbbbbbbbbbbbbbbb", "encoding":"US-ASCII" ``` Big thanks to �douard Chin who did most of the initial repro reduction. -- https://bugs.ruby-lang.org/ Unsubscribe: