C23 has qualifier-preserving standard library functions, so calling
strchr with a `const char *` will return a `const char *`. We can change
the type of the local variables because we don't mutate the strings.
(cherry picked from commit 42b3cdc51a)
[PATCH] fix ENV.keys encoding on windows
Fix the encoding of ENV.keys elements to UTF-8 on windows.
They contain UTF-8 byte sequences with locale encoding.
[PATCH] [Bug #20958] Fix test_keys_encoding on hosts without en_US.UTF-8
`EnvUtil.invoke_ruby` forces the C locale on the child process, so the
test set `LC_ALL=en_US.UTF-8` to get a UTF-8 locale back. That locale
is not generated on the debian11 chkbuild host, where `setlocale` falls
back to C and the ENV key comes out as ASCII-8BIT instead of the
default internal encoding. Inherit the locale of the parent process
instead, and omit the test when that locale is not UTF-8.
https://rubyci.s3.amazonaws.com/debian11/ruby-master/log/20260725T093003Z.fail.html.gz
* While perusing code in hash.c I found it suspicious that ar_find_entry_hint()
didn't reread bound in the loop and yet called arbitrary code through #eql?.
* ar_find_entry_hint() before this commit would not check if bound or the storage (AR->ST) changed
and would return a bin index which is not correct to access.
* Check bound in the loop so it's always up-to-date.
* Return RHASH_AR_TABLE_CONVERTED_TO_ST_TABLE when converted to st_table
and make callers retry the operation as a st_table.
[Bug #22120]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
(cherry picked from commit c88430e187)
The "EXIVAR" terminology has been replaced by "gen fields"
AKA "generic fields".
Exivar implies variable, but generic fields include more than
just variables, e.g. `object_id`.
to adopt strict shareable rule.
* (basically) shareable objects only refer shareable objects
* (exception) shareable objects can refere unshareable objects
but should not leak reference to unshareable objects to Ruby world
It does raise an exception rather than just issuing a warning:
```shell
$ docker run -e ALL_RUBY_SINCE=2.7 --rm rubylang/all-ruby ./all-ruby -We 'ENV.clone'
ruby-2.7.0
...
ruby-3.0.7
ruby-3.1.0-preview1 -e:1: warning: ENV.clone is deprecated; use ENV.to_h instead
...
ruby-3.2.0-preview1 -e:1: warning: ENV.clone is deprecated; use ENV.to_h instead
ruby-3.2.0-preview2 -e:1:in `clone': Cannot clone ENV, use ENV.to_h to get a copy of ENV as a hash (TypeError)
from -e:1:in `<main>'
exit 1
...
ruby-3.3.9 -e:1:in `clone': Cannot clone ENV, use ENV.to_h to get a copy of ENV as a hash (TypeError)
from -e:1:in `<main>'
exit 1
ruby-3.4.0-preview1 -e:1:in 'clone': Cannot clone ENV, use ENV.to_h to get a copy of ENV as a hash (TypeError)
from -e:1:in '<main>'
exit 1
...
ruby-3.5.0-preview1 -e:1:in 'clone': Cannot clone ENV, use ENV.to_h to get a copy of ENV as a hash (TypeError)
from -e:1:in '<main>'
exit 1
```
Make sure VM lock is not held when calling `load_transcoder_entry`, as
that causes deadlock inside ractors. `String#encode` now works inside
ractors, among others.
Atomic load the rb_encoding_list
Without this, wbcheck would sometimes hit a missing write barrier.
Co-authored-by: John Hawthorn <john.hawthorn@shopify.com>
Hold VM lock when iterating over global_enc_table.names
This st_table can be inserted into at runtime when autoloading
encodings.
minor optimization when calling Encoding.list
We don't need to delay the freeing of the fstr for the symbol if we store
the hash of the fstr in the dynamic symbol and we use compare-by-identity
for removing the dynamic symbol from the sym_set.
Hash#rehash checks whether the hash is iterating, and with VWA,
RHASH_ST_TABLE() always returns the same thing for the same
hash.
RHASH_ST_TABLE(VALUE h)
{
return (st_table *)((uintptr_t)h + sizeof(struct RHash));
}
So this check can never fail and raise an exception. Remove it.
The write barriers must be run after the st_update callback returns,
as the objects are not on the object until then and there may be
allocation when there is a new object inserted.
This is hard to reproduce, and I haven't seen an actual crash due to it,
but it is detected by wbcheck
RUBY_GC_LIBRARY=wbcheck WBCHECK_VERIFY_AFTER_WB=1 ./miniruby -e '("a".."zz").uniq.to_a'
WBCHECK ERROR: Missed write barrier detected!
Parent object: 0x720db01f99c0 (wb_protected: true)
rb_obj_info_dump: 0x0000720db01f99c0 T_HASH/[S] 18
Reference counts - snapshot: 32, writebarrier: 2, current: 36, missed: 2
Missing reference to: 0x716db02e3450
rb_obj_info_dump: 0x0000716db02e3450 T_STRING/String len: 1, capa: 15 "q"
Missing reference to: 0x716db02e3450
rb_obj_info_dump: 0x0000716db02e3450 T_STRING/String len: 1, capa: 15 "q"
A part of why this is hard to reproduce and it's unlikely to crash is
that the insertion only rarely allocates.
Co-authored-by: Luke Gruber <luke.gruber@shopify.com>
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.
This was missed when adding core Set, because it's handled
implicitly for T_OBJECT.
Keep marshal compatibility between core Set and stdlib Set,
so you can unmarshal core Set with stdlib Set and vice versa.
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>