<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/test/ruby/test_hash.rb, branch v3_3_11</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>merge revision(s) 056497319658cbefe22351c6ec5c9fa6e4df72bd: [Backport #21357]</title>
<updated>2025-05-24T01:25:59+00:00</updated>
<author>
<name>nagachika</name>
<email>nagachika@ruby-lang.org</email>
</author>
<published>2025-05-24T01:25:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=24c994b91a67f0023e8fe22a5428581110564332'/>
<id>24c994b91a67f0023e8fe22a5428581110564332</id>
<content type='text'>
	[Bug #21357] Fix crash in Hash#merge with block

	Prior to https://github.com/ruby/ruby/commit/49b306ecb9e2e9e06e0b1590bacc5f4b38169c3c
	the `optional_arg` passed from `rb_hash_update_block_i` to `tbl_update`
	was a hash value (i.e. a VALUE). After that commit it changed to an
	`update_call_args`.

	If the block sets or changes the value, `tbl_update_modify` will set the
	`arg.value` back to an actual value and we won't crash. But in the case
	where the block returns the original value we end up calling
	`RB_OBJ_WRITTEN` with the `update_call_args` which is not expected and
	may crash.

	`arg.value` appears to only be used to pass to `RB_OBJ_WRITTEN` (others
	who need the `update_call_args` get it from `arg.arg`), so I don't think
	it needs to be set to anything upfront. And `tbl_update_modify` will set
	the `arg.value` in the cases we need the write barrier.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	[Bug #21357] Fix crash in Hash#merge with block

	Prior to https://github.com/ruby/ruby/commit/49b306ecb9e2e9e06e0b1590bacc5f4b38169c3c
	the `optional_arg` passed from `rb_hash_update_block_i` to `tbl_update`
	was a hash value (i.e. a VALUE). After that commit it changed to an
	`update_call_args`.

	If the block sets or changes the value, `tbl_update_modify` will set the
	`arg.value` back to an actual value and we won't crash. But in the case
	where the block returns the original value we end up calling
	`RB_OBJ_WRITTEN` with the `update_call_args` which is not expected and
	may crash.

	`arg.value` appears to only be used to pass to `RB_OBJ_WRITTEN` (others
	who need the `update_call_args` get it from `arg.arg`), so I don't think
	it needs to be set to anything upfront. And `tbl_update_modify` will set
	the `arg.value` in the cases we need the write barrier.
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) 49b306ecb9e2e9e06e0b1590bacc5f4b38169c3c: [Backport #21333]</title>
<updated>2025-05-24T01:24:22+00:00</updated>
<author>
<name>nagachika</name>
<email>nagachika@ruby-lang.org</email>
</author>
<published>2025-05-24T01:24:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8f895758d9512466e9ec24ce8e588f059c16136c'/>
<id>8f895758d9512466e9ec24ce8e588f059c16136c</id>
<content type='text'>
	[Bug #21333] Prohibit hash modification inside Hash#update block
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	[Bug #21333] Prohibit hash modification inside Hash#update block
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) 7793b59c8d2a13c124fe276e11723db23facce04: [Backport #21331]</title>
<updated>2025-05-17T06:57:05+00:00</updated>
<author>
<name>nagachika</name>
<email>nagachika@ruby-lang.org</email>
</author>
<published>2025-05-17T06:57:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=cb49400d680894d69534b0b4cd10b085de325e2a'/>
<id>cb49400d680894d69534b0b4cd10b085de325e2a</id>
<content type='text'>
	[Bug #21331] Prohibit hash modification during stlike loop
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	[Bug #21331] Prohibit hash modification during stlike loop
</pre>
</div>
</content>
</entry>
<entry>
<title>Replace tombstone when converting AR to ST hash</title>
<updated>2025-03-08T07:43:58+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2025-03-05T22:21:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ef523984f0c16ec3ec1ea3b5b74ed24e6b03d561'/>
<id>ef523984f0c16ec3ec1ea3b5b74ed24e6b03d561</id>
<content type='text'>
[Bug #21170]

st_table reserves -1 as a special hash value to indicate that an entry
has been deleted. So that that's a valid value to be returned from the
hash function, do_hash replaces -1 with 0 so that it is not mistaken for
the sentinel.

Previously, when upgrading an AR table to an ST table,
rb_st_add_direct_with_hash was used which did not perform the same
conversion, this could lead to a hash in a broken state where one if its
entries which was supposed to exist being marked as a tombstone.

The hash could then become further corrupted when the ST table required
resizing as the falsely tombstoned entry would be skipped but it would
be counted in num entries, leading to an uninitialized entry at index
15.

In most cases this will be really rare, unless using a very poorly
implemented custom hash function.

This also adds two debug assertions, one that st_add_direct_with_hash
does not receive the reserved hash value, and a second in
rebuild_table_with, which ensures that after we rebuild/compact a table
it contains the expected number of elements.

Co-authored-by: Alan Wu &lt;alanwu@ruby-lang.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Bug #21170]

st_table reserves -1 as a special hash value to indicate that an entry
has been deleted. So that that's a valid value to be returned from the
hash function, do_hash replaces -1 with 0 so that it is not mistaken for
the sentinel.

Previously, when upgrading an AR table to an ST table,
rb_st_add_direct_with_hash was used which did not perform the same
conversion, this could lead to a hash in a broken state where one if its
entries which was supposed to exist being marked as a tombstone.

The hash could then become further corrupted when the ST table required
resizing as the falsely tombstoned entry would be skipped but it would
be counted in num entries, leading to an uninitialized entry at index
15.

In most cases this will be really rare, unless using a very poorly
implemented custom hash function.

This also adds two debug assertions, one that st_add_direct_with_hash
does not receive the reserved hash value, and a second in
rebuild_table_with, which ensures that after we rebuild/compact a table
it contains the expected number of elements.

Co-authored-by: Alan Wu &lt;alanwu@ruby-lang.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) f36a71e26995b69ff72bc132bbcf40ad89571414: [Backport #20307]</title>
<updated>2024-05-28T22:17:51+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2024-05-28T22:15:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=917f3e5d22b3364002eb1fdc2f94b35ff76f6a73'/>
<id>917f3e5d22b3364002eb1fdc2f94b35ff76f6a73</id>
<content type='text'>
	[Bug #20307] Fix `Hash#update` to make frozen copy of string keys
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	[Bug #20307] Fix `Hash#update` to make frozen copy of string keys
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) 6c252912af4981f016a9abdb4c1689307a4f1d2f: [Backport #20145]</title>
<updated>2024-02-01T00:08:06+00:00</updated>
<author>
<name>NARUSE, Yui</name>
<email>naruse@airemix.jp</email>
</author>
<published>2024-02-01T00:08:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=aeffb5e21de6000a3dcfa0ca88c6ba3c3c42d8db'/>
<id>aeffb5e21de6000a3dcfa0ca88c6ba3c3c42d8db</id>
<content type='text'>
	Memory leak when duplicating identhash

	[Bug #20145]

	Before this commit, both copy_compare_by_id and hash_copy will create a
	copy of the ST table, so the ST table created in copy_compare_by_id will
	be leaked.

	    h = { 1 =&gt; 2 }.compare_by_identity

	    10.times do
	      1_000_000.times do
	        h.select { false }
	      end

	      puts `ps -o rss= -p #{$$}`
	    end

	Before:

	    110736
	    204352
	    300272
	    395520
	    460704
	    476736
	    542000
	    604704
	    682624
	    770528

	After:

	    15504
	    16048
	    16144
	    16256
	    16320
	    16320
	    16752
	    16752
	    16752
	    16752
	---
	 hash.c                 | 10 +++++++++-
	 test/ruby/test_hash.rb | 10 ++++++++++
	 2 files changed, 19 insertions(+), 1 deletion(-)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	Memory leak when duplicating identhash

	[Bug #20145]

	Before this commit, both copy_compare_by_id and hash_copy will create a
	copy of the ST table, so the ST table created in copy_compare_by_id will
	be leaked.

	    h = { 1 =&gt; 2 }.compare_by_identity

	    10.times do
	      1_000_000.times do
	        h.select { false }
	      end

	      puts `ps -o rss= -p #{$$}`
	    end

	Before:

	    110736
	    204352
	    300272
	    395520
	    460704
	    476736
	    542000
	    604704
	    682624
	    770528

	After:

	    15504
	    16048
	    16144
	    16256
	    16320
	    16320
	    16752
	    16752
	    16752
	    16752
	---
	 hash.c                 | 10 +++++++++-
	 test/ruby/test_hash.rb | 10 ++++++++++
	 2 files changed, 19 insertions(+), 1 deletion(-)
</pre>
</div>
</content>
</entry>
<entry>
<title>add a test</title>
<updated>2023-12-15T02:58:43+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2023-12-15T02:21:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=406d4bb59905903cf7b9fa62c2d590e963edda5c'/>
<id>406d4bb59905903cf7b9fa62c2d590e963edda5c</id>
<content type='text'>
proposed at https://bugs.ruby-lang.org/issues/20050#note-5
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
proposed at https://bugs.ruby-lang.org/issues/20050#note-5
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix memory leak in Hash#compare_by_identity</title>
<updated>2023-12-13T17:43:09+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2023-12-13T17:11:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=a3b48ac9ad8a5d4eb7ae6c3d4fe9d040361daa7a'/>
<id>a3b48ac9ad8a5d4eb7ae6c3d4fe9d040361daa7a</id>
<content type='text'>
We didn't free the old ST before overwriting it which caused a leak.
Found with RUBY_FREE_ON_EXIT.

Co-authored-by: Peter Zhu &lt;peter@peterzhu.ca&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We didn't free the old ST before overwriting it which caused a leak.
Found with RUBY_FREE_ON_EXIT.

Co-authored-by: Peter Zhu &lt;peter@peterzhu.ca&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Do not change hash type in Hash#assoc</title>
<updated>2023-11-21T06:15:23+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2023-11-07T03:10:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f5c3cda7d6e9053ae5ed66e36d13e568595ff1ec'/>
<id>f5c3cda7d6e9053ae5ed66e36d13e568595ff1ec</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Raise an exception when Hash#compare_by_identity during its iteration</title>
<updated>2023-11-21T06:15:23+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2023-11-08T08:34:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=1cf2fa3af50203f261341ff4c250735c9da5767b'/>
<id>1cf2fa3af50203f261341ff4c250735c9da5767b</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
</feed>
