diff options
author | Jeremy Evans <[email protected]> | 2022-11-09 09:23:45 -0800 |
---|---|---|
committer | Jeremy Evans <[email protected]> | 2023-03-24 10:55:13 -0700 |
commit | d3197def882b47e7c57cdddfe8d62f62fef9d3f7 (patch) | |
tree | 52ab45b683bcc6e7f718dbdca1007d5a82928ed9 /hash.c | |
parent | 35e9b5348d91eff13d2bdc487003f46a19586d42 (diff) |
Do not copy compare_by_identity flag for non-empty hashes in Hash.[]
It wasn't copied for empty hashes, and Hash.[] doesn't copy the
default value, so copying the compare_by_identity flag does not
make sense.
Partially Fixes [Bug #19113]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6702
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -1801,6 +1801,8 @@ rb_hash_initialize(int argc, VALUE *argv, VALUE hash) return hash; } +static VALUE rb_hash_to_a(VALUE hash); + /* * call-seq: * Hash[] -> new_empty_hash @@ -1844,12 +1846,22 @@ rb_hash_s_create(int argc, VALUE *argv, VALUE klass) if (argc == 1) { tmp = rb_hash_s_try_convert(Qnil, argv[0]); if (!NIL_P(tmp)) { - hash = hash_alloc(klass); - hash_copy(hash, tmp); - return hash; + if (!RHASH_EMPTY_P(tmp) && rb_hash_compare_by_id_p(tmp)) { + /* hash_copy for non-empty hash will copy compare_by_identity + flag, but we don't want it copied. Work around by + converting hash to flattened array and using that. */ + tmp = rb_hash_to_a(tmp); + } + else { + hash = hash_alloc(klass); + hash_copy(hash, tmp); + return hash; + } + } + else { + tmp = rb_check_array_type(argv[0]); } - tmp = rb_check_array_type(argv[0]); if (!NIL_P(tmp)) { long i; |