Skip to content

[pull] master from ruby:master - #1349

Merged
pull[bot] merged 33 commits into
turkdevops:masterfrom
ruby:master
Aug 26, 2026
Merged

[pull] master from ruby:master#1349
pull[bot] merged 33 commits into
turkdevops:masterfrom
ruby:master

Conversation

@pull

@pull pull Bot commented Aug 26, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

dak2 and others added 30 commits August 25, 2026 15:38
Add codegen tests for the Fixnum left shift fastpath and its overflow side exit.
In `install`, `self.to_s` is called by `print_using_message "Using ... from #{self}`.
This in turn calls `current_branch` which if the local git cache
is missing will re-clone it from scratch.

This is an issue, because a common optimization for build system
that are bundler aware is to prune bundler's cache to remove
large git repositories.

See my feature request from 2020 for context:
ruby/rubygems#7018

In our case, these git repositories account for over 50%
of the bundler cache, causing the cache restoration and
persist steps to be very significantly slowed down.

Overall I don't think triggering a full on git clone operation
from a call to `to_s` make sense.

ruby/rubygems@0733910385
Storing an API key in a plain text file leaves it readable by anything
running as the user. This wrapper keeps secrets in the operating system's
own store instead, through the security CLI on macOS, secret-tool on
Linux, and Windows PowerShell's PasswordVault, or through a third-party
backend selected by name. Every public method traps errors and answers
with nil or false so a broken store degrades to the file rather than
breaking the command, and what a store may hold is validated in one place
so a value is stored, or refused for the same reason, on every platform.
Secrets stay off argv, where any other user on the machine could read
them, by traveling over stdin or the environment.

The tests drive the real command lines against a stand-in executable, and
the suite pins the setting so a developer's own keychain is never touched.

ruby/rubygems@66e3a9193c
The :credential_store: gemrc setting, off by default, moves API keys out
of ~/.gem/credentials and into the OS store. A key is read from the store
ahead of the file, so the two never disagree about which one wins, and the
plain text copy is dropped once the store accepts it. A write the store
refuses falls back to the file, and clears whatever it still holds for
that host, since a stored key left behind would outrank the one just
written and never be replaced.

A store that cannot be read is not the same as one holding nothing. The
difference decides whether a command may fall back to another host's key
or quietly downgrade to a password prompt, so a read that failed stops the
command instead. Accounts are derived from the same normalized host the
credentials file uses, with any userinfo dropped, so a password in a host
name never reaches the backend's argv.

ruby/rubygems@d02ca7003e
Signing out has to reach both places a key can live, including the keys
saved for other hosts with gem signin --host. The two halves report
separately, so a credentials file that cannot be removed does not leave
the stored keys behind, and a file marked read-only is still refused the
way it always was rather than deleted because the directory happened to
allow it.

ruby/rubygems@f9d8722dd9
… when it is on

The credential_store setting takes the same values on this side, and
credential_store.<host> picks a different backend for one host, since a
backend gem published for one registry cannot know what its users want
everywhere else. Bundler and RubyGems keep separate account namespaces in
the shared store, so gem signout does not carry off a bundle's host
credentials.

A credential given in the environment still wins, because the store stands
in for the config file and must not override the layer that already
overrides it. bundle config get and list report that a credential lives in
the store without printing it, and the warnings name the host with any
userinfo removed so a password does not reach a CI log.

ruby/rubygems@107774b07e
Bundler reaches Gem::CredentialStore by name, so a bundler installed
against an older RubyGems needs the file itself, the way it already
carries the YAML serializer and the compact index client. Three places
enumerate what bundler ships, and naming the files in only the first is
what failed the ruby-core jobs: the gemspec promised files the build had
never copied.

ruby/rubygems@ea8d8e84cc
Where a credential ends up, what happens when the store cannot be reached,
that the store belongs to the machine rather than to a project, and that
credentials already written in plain text are not migrated on their own.

ruby/rubygems@5369844f32
- In ruby/rubygems@304a98301522 in 2013, "quiet?" was any
  level that was not "debug", "info", or "warn",

- Its last use was removed in ruby/rubygems@64f1294672e2
  in 2014.

- Since ruby/rubygems@1d7eea800d1b in 2017 the `quiet?`
  method has raised an error because "quiet" is not a valid log level:

```ruby
irb(main):004> Bundler::UI::Shell.new.quiet?
/Users/issyl0/repos/ruby/rubygems/lib/bundler/ui/shell.rb:105:in 'Bundler::UI::Shell#level': "quiet" is not a valid level (RuntimeError)
from /Users/issyl0/repos/ruby/rubygems/lib/bundler/ui/shell.rb:80:in 'Bundler::UI::Shell#quiet?'
```

ruby/rubygems@2c3801bbb8
…enqueued?`

- This predicate method has been unused since
  ruby/rubygems@7d1131672a84 in 2021 when the
  `ready_to_enqueue?` method was simplified.

ruby/rubygems@88d7eef941
The response header cap added by #219 applies only once a complete line
has arrived, so a server that never sends a line terminator can still
grow the read buffer without bound, as reported in #315. Read the
status line, header lines, chunk-size lines and chunk trailers through
net-protocol's readuntil(limit:) so they fail with
Net::HTTPBadResponse at MAX_RESPONSE_HEADER_LENGTH, and require the
net-protocol that provides it.

The cumulative header budget stays separate from the per-line limit so
that exhausting the total still reports 'response header too large'
rather than blaming a line that is not long.

ruby/net-http#315

ruby/net-http@132c8cc1b1

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
symbol_id_entry_directory is not an embedded TypedData, so we need to free
the allocated id_entry_dir as well.
A peer that keeps sending 1xx responses keeps the client in the read
loop of transport_request indefinitely, since the per-response header
limit resets for each response. Cap the count at 100, the same value
CPython's http.client uses.

ruby/net-http@39cf5f648a

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(ruby/net-http#324)

`Content-Length` value must have only digits.

See also RFC 9110 Section 8.6:
https://www.rfc-editor.org/rfc/rfc9110.html#section-8.6

    Content-Length = 1*DIGIT

The current implementation accepts garbage before/after digits such as
`abc5` and `5abc`.

This rejects these invalid values.

But this accepts same values in one `Content-Length`

    Content-Length: 5, 5

and in multiple `Content-Length`es:

    Content-Length: 5
    Content-Length: 5

This is for the following part in the RFC:

https://www.rfc-editor.org/rfc/rfc9110.html#section-8.6-13

> Likewise, a sender MUST NOT forward a message with a Content-Length
> header field value that does not match the ABNF above, with one
> exception: a recipient of a Content-Length header field value
> consisting of the same decimal value repeated as a comma-separated
> list (e.g, "Content-Length: 42, 42") MAY either reject the message
> as invalid or replace that invalid field value with a single
> instance of the decimal value, since this likely indicates that a
> duplicate was generated or combined by an upstream message
> processor.

ruby/net-http@23e859e92e
Content-Length parsing became strict in 4.1, so values with anything
around the digits now raise instead of returning the digits.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
TOPLEVEL_BINDING always belongs to the main box, so when Bundler is
loaded inside a user box, gemspecs were evaluated against the main
box's Gem::Specification, which lacks Bundler's monkey patches and
fails with NoMethodError on `source=`. Use a binding from the box
Bundler is loaded in when boxes are enabled.

The spec needs Ruby 4.0.6 or later: boxes load their own RubyGems only
since ruby/ruby ruby/rubygems@99aac00fa13 (Bug #21881), and before it requiring a
path gem inside a box fails in bundled_gems.rb for unrelated reasons.

ruby/rubygems@45c6929db4

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
When several gems come from the same git block, Runtime#cache invokes
the shared Source::Git once per gem, and cache_to re-cloned and
re-checked out the whole worktree every time. For large repositories
this made bundle cache/update/install significantly slower. Memoize the
written app cache path and skip the copy when it was already populated
during the same command.

ruby/rubygems#8592

ruby/rubygems@322ad01962

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Under Ruby::Box (RUBY_BOX=1) the builtin Marshal runs in the root box and
cannot resolve Gem:: constants defined in the main box, so every gem
command failed to start while deep-copying its option defaults.

https://bugs.ruby-lang.org/issues/22090

ruby/rubygems@ec9d92c866

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Under Ruby::Box mkmf makes RbConfig.expand recurse until SystemStackError,
so building a native extension failed even once the CLI itself started.
Build tools are not a target of box isolation.

ruby/rubygems@b488fc7f75

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The unit tests cover each fix on its own, but nothing checks that a boxed
gem command actually gets as far as listing gems.

ruby/rubygems@e6ee031539

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Leading keyword splats must not suppress duplicate literal key
warnings.
A boxed gem CLI subprocess dies with SIGSEGV in
rb_objspace_call_finalizer at exit on Windows. The fix belongs in
Ruby::Box itself, so omit the canary there until it lands.

https://github.com/ruby/ruby/actions/runs/32933358242/job/98069763490

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bumps the github-actions group with 1 update in the / directory: [taiki-e/install-action](https://github.com/taiki-e/install-action).


Updates `taiki-e/install-action` from 2.86.5 to 2.86.6
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](taiki-e/install-action@ba47c86...6cd1350)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.86.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Share the same code between gc.c and hash.c.
…ndex fetcher

Gem::RemoteFetcher#fetch_http has refused a redirect from https to plain
http since 2012, but the compact index path, which is now the default
and decides which versions resolve, followed it. One 302 from a
compromised edge or a misconfigured mirror moved the whole index onto a
channel anyone on the path can rewrite.

ruby/rubygems@72c0196f44

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…x fetcher

Gem::RemoteFetcher#request lets SocketError, Errno::ECONNREFUSED and
their kin through unwrapped, and every caller here rescues FetchError
alone. On a host where only index.rubygems.org is unreachable, the
fallback to the Marshal index never ran and multi-source resolution
aborted on the one source instead of recording it and moving on.

ruby/rubygems@c2754923a3

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dropping Gem::Net::HTTPNotModified from it, or narrowing HTTPSuccess to
HTTPOK, left the suite green even though Updater depends on both the
304 and the 206 reaching it untouched.

ruby/rubygems@b265de4bf7

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
peterzhu2118 and others added 3 commits August 26, 2026 09:53
This fixes tests with Ruby master, where unshareable T_DATA is copied
across Ractor via Marshal.

ruby/openssl@943fe2340e
This commit adds support for using AR tables for identity hashes (hashes
created by method Hash#compare_by_identity). Before this change, identity
hashes always used ST tables. However, this used a lot more memory because
ST tables are quite large. This commit adds a new flag RHASH_COMPARE_BY_IDENTITY
for AR tables that are compare-by-identity.

For example, for an empty identity hash, the size goes from 256 bytes to
160 bytes:

    require "objspace"

    h = {}.compare_by_identity
    puts ObjectSpace.memsize_of(h)
@pull pull Bot locked and limited conversation to collaborators Aug 26, 2026
@pull pull Bot added the ⤵️ pull label Aug 26, 2026
@pull
pull Bot merged commit 0b2edb5 into turkdevops:master Aug 26, 2026
0 of 2 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants