diff options
author | nagachika <nagachika@ruby-lang.org> | 2021-05-23 15:51:10 +0900 |
---|---|---|
committer | nagachika <nagachika@ruby-lang.org> | 2021-05-23 15:51:10 +0900 |
commit | 44b87adc07621b6a8eddfcf4aaff34ce634179d4 (patch) | |
tree | 3751a240810290e1cc80c0334daf9284ad8c705b /hash.c | |
parent | 86f7e55dfb5938e0c617b8629a1fbb4d24341dc0 (diff) |
merge revision(s) e019dd24df4ed7063ad80d4c2e4070141793f598,7954bb056be30e86c419fe3792064d28990a4999,7d3fdfb27dac456827b004d9e66a44b15f8cd762: [Backport #17736]
Ensure the receiver is modifiable before shrinking [Bug #17736]
* Ensure the receiver is modifiable before shinking [Bug #17736]
* Assert the receivers are not modified
---
array.c | 1 +
test/ruby/test_array.rb | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
Some Hash destructive methods ensure the receiver modifiable [Bug
#17736]
refs:
* https://bugs.ruby-lang.org/issues/17736
* https://github.com/ruby/ruby/pull/4296
This commit aims to cover following methods
* Hash#select!
* Hash#filter!
* Hash#keep_if
* Hash#reject!
* Hash#delete_if
I think these are not all.
---
* Ensure the receiver is modifiable or not
* Assert the receiver is not modified
---
hash.c | 2 ++
test/ruby/test_hash.rb | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)
Hash#transform_values! ensures receiver modifiable in block [Bug
#17736]
---
hash.c | 1 +
test/ruby/test_hash.rb | 9 +++++++++
2 files changed, 10 insertions(+)
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 3 |
1 files changed, 3 insertions, 0 deletions
@@ -2476,6 +2476,7 @@ static int delete_if_i(VALUE key, VALUE value, VALUE hash) { if (RTEST(rb_yield_values(2, key, value))) { + rb_hash_modify(hash); return ST_DELETE; } return ST_CONTINUE; @@ -2753,6 +2754,7 @@ static int keep_if_i(VALUE key, VALUE value, VALUE hash) { if (!RTEST(rb_yield_values(2, key, value))) { + rb_hash_modify(hash); return ST_DELETE; } return ST_CONTINUE; @@ -3322,6 +3324,7 @@ transform_values_foreach_replace(st_data_t *key, st_data_t *value, st_data_t arg { VALUE new_value = rb_yield((VALUE)*value); VALUE hash = (VALUE)argp; + rb_hash_modify(hash); RB_OBJ_WRITE(hash, value, new_value); return ST_CONTINUE; } |