Skip to content

[pull] master from ruby:master - #1352

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

[pull] master from ruby:master#1352
pull[bot] merged 19 commits into
turkdevops:masterfrom
ruby:master

Conversation

@pull

@pull pull Bot commented Aug 27, 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 : )

hsbt and others added 19 commits August 27, 2026 10:42
box_entry_free could run before other T_DATA objects are finalized in
rb_objspace_call_finalizer, and FreeLibrary there unmapped the
rb_data_type_t and dfree functions that later finalization still
dereferences, crashing any boxed process that leaves extension objects
alive at exit. Keep the copied DLLs loaded until ruby_vm_destruct, then
unload and delete them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A label longer than 255 octets wrapped its length octet mod 256 while the
data was written unchanged, so the wire bytes decoded to a different name
than the caller asked for. A hostname that passed an application's
allowlist could be sent as a query for an unrelated domain.

The 63 octet limit goes on the label path. put_string also writes
character-strings, which may legitimately be 255 octets, so it keeps the
wider limit that its single length octet can represent.

ruby/resolv@137df11fc0

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The counter started at -1, which measures the presentation form, so a name
encoding to 257 octets passed the 255 octet limit of RFC 1035 section 3.1.
The encoded form includes each label's length octet and the root label's
terminating zero octet.

ruby/resolv@0a5ef9b498

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A hostname is runtime data rather than a programming mistake, and callers
already wrap name resolution in rescue Resolv::ResolvError. Rejecting an
oversized name with ArgumentError escaped that rescue, since
Config#generate_candidates runs outside Config#resolv's own handler.

No new exception class: resolv raises ResolvError directly in nine other
places and subclasses it only where a caller has to tell cases apart.

ruby/resolv@346416498a

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Checking in Name.create left two ways to build an over-long label: Name.new,
which Config#generate_candidates uses to append search domains, and the
search list itself, which Config splits without going through Name.create.
Label::Str is the one place every label is built, so enforcing it there
covers both, and the encoder guard becomes a backstop rather than the only
line of defence.

Callers keep the error their own contract promises. Name.create still reports
ResolvError, and get_label reports DecodeError, which also means a length
octet in the reserved 64..191 range is no longer read as a label.

ruby/resolv@07f3b7d098

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s it

The comment predates the check moving into Label::Str and read as though a
label of 64 octets already overflowed its length octet. It does not: 64 to 255
write a reserved or compression pointer value, and only 256 or more wrap. Say
which is which, and say that this guard now only catches a raw string passed
straight to put_labels.

Both messages also name the limit they enforce, as the other size checks do.

ruby/resolv@972ec472e3

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… and SvcParamKeys

Decoding a response with unknown (type, class) pairs or unknown
SvcParamKeys generated an anonymous class per value and registered it in
a constant and in ClassHash permanently, so a spoofed or malicious
response carrying many unknown values could exhaust memory even after the
response was discarded and GC ran (a denial of service). Generate the
classes on demand without registering them so they stay collectable; the
default RR and SvcParam classes are still registered at require time.

ruby/resolv@fa5e689c46

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Dropping the class cache made every decode build a fresh class for an
unknown type, so comparing the classes by identity reported two otherwise
identical resources, questions, and messages as different.

ruby/resolv@05185b4322

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e zipped array

Generic#== accepted only direct subclasses while Message compared any
descendant, so an instance of a subclass of a generated class compared
unequal. Both now go through Generic.type_class_equal?. Passing a block
to zip also avoids allocating the paired array and stops at the first
mismatch.

ruby/resolv@fcff0a19e4

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Block param minimization was introduced here #17311, but a few tests did not properly eliminate redundant block params.
This is because I used `Vec::resize`. For most passes this was fine, especially when trivial block params were discovered. However, in the case where the number of params is not reduced, the vec is not properly cleared between analyses. In some cases, this leaves a dangling trivial param that can be changed if _other_ blocks remove trivial params.

In addition to resize, we use `Vec::truncate` which fixes the problem.

This test also requires the removal of a test that has issues due to pass ordering. Unless we develop a mechanism to run single analysis passes in tests, we may run into more such issues.
We shouldn't record JIT information before the JIT is actually enabled.

This change doesn't seem to affect ZJIT or YJIT performance beyond the
margin of error:

    ZJIT:

      --------------  ------------  ------------  --------------  -------------
      bench            master (ms)   branch (ms)  branch 1st itr  master/branch
      activerecord     50.1 ± 7.4%   49.0 ± 5.7%           0.948          1.022
      chunky-png      164.2 ± 2.1%  166.8 ± 2.8%           0.985          0.985
      erubi-rails     247.0 ± 2.8%  264.6 ± 2.2%           0.945          0.934
      hexapdf         571.3 ± 1.0%  565.4 ± 1.2%           0.959          1.010
      liquid-c        17.6 ± 13.1%  19.2 ± 12.9%           0.976          0.920
      liquid-compile  15.7 ± 11.0%   15.6 ± 7.5%           0.978          1.003
      liquid-il        79.8 ± 2.0%   78.2 ± 2.2%           0.993          1.021
      liquid-render    32.3 ± 6.8%   32.3 ± 6.3%           1.001          0.999
      lobsters        243.8 ± 4.9%  242.8 ± 4.7%           0.976          1.004
      mail             38.8 ± 3.1%   39.5 ± 5.1%           0.993          0.982
      psych-load      612.4 ± 1.5%  610.0 ± 1.9%           1.001          1.004
      railsbench      343.8 ± 2.9%  350.8 ± 2.2%           0.991          0.980
      rubocop         50.0 ± 10.6%  51.2 ± 12.0%           1.019          0.978
      ruby-lsp         42.9 ± 3.8%   43.2 ± 3.7%           0.974          0.993
      sequel           18.5 ± 6.6%   18.7 ± 6.6%           1.021          0.991
      shipit          344.3 ± 1.3%  339.8 ± 3.4%           0.981          1.013
      --------------  ------------  ------------  --------------  -------------

    YJIT:

      --------------  ------------  ------------  --------------  -------------
      bench            master (ms)   branch (ms)  branch 1st itr  master/branch
      activerecord     42.6 ± 7.7%   40.6 ± 5.5%           1.099          1.048
      chunky-png      164.7 ± 1.3%  164.8 ± 1.1%           1.060          0.999
      erubi-rails     256.7 ± 3.3%  241.3 ± 2.3%           1.035          1.064
      hexapdf         445.6 ± 1.0%  444.6 ± 1.0%           1.012          1.002
      liquid-c        16.4 ± 11.2%  16.7 ± 13.3%           1.037          0.986
      liquid-compile  14.5 ± 11.5%   14.3 ± 7.8%           0.990          1.011
      liquid-il        74.9 ± 2.6%   73.4 ± 3.6%           0.993          1.021
      liquid-render    23.1 ± 8.9%   23.3 ± 8.7%           1.001          0.992
      lobsters        239.9 ± 9.9%  238.7 ± 9.3%           0.989          1.005
      mail             29.2 ± 4.6%   30.0 ± 5.8%           0.977          0.973
      psych-load      515.5 ± 1.2%  511.5 ± 0.7%           0.973          1.008
      railsbench      317.4 ± 2.2%  317.9 ± 2.5%           1.008          0.998
      rubocop         42.1 ± 18.5%  42.0 ± 14.4%           1.052          1.004
      ruby-lsp         41.5 ± 3.8%   41.6 ± 3.8%           1.013          0.998
      sequel           18.5 ± 6.6%   18.2 ± 5.4%           1.150          1.018
      shipit          282.8 ± 3.8%  285.5 ± 5.2%           1.000          0.991
      --------------  ------------  ------------  --------------  -------------
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.6 to 2.86.7
- [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@6cd1350...b6ff580)

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

Signed-off-by: dependabot[bot] <support@github.com>
… flag

Every documented spelling of the flag raises before reaching it, so the
only way in was Thor resolving `--skip-no-prune` to a negated value,
which `flag_passed?` does not match. That let an undocumented spelling
change a setting the documented one is refused for.

ruby/rubygems@197eccbeed

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The `prune` vocabulary is being reused for a new setting, and `no_prune`
was already a poor name for a flag that only decides whether `bundle
cache` keeps gems that dropped out of the resolution. `no_prune` is
still read until Bundler 5 removes it, resolved one priority level at a
time so that an old name set locally keeps beating a current name set
globally, the way the documented order promises.

ruby/rubygems@98eaec7e9e

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
In the following code,

```ruby
def test(cond)
  if cond
    x = 1
  else
    x = 1
  end
  x
end
```

the `x` after the conditional would ordinarily get a block param merging two constant `1`. Even if we had dominator-based GVN, this would still happen; each `1` is in a sibling block (they would need to be hoisted).

This also happens a lot with nil-filled locals; interpreter and JIT entry blocks nil-fill the FrameState for each local variable and these nils get passed around when they don't need to.

Instead of doing that, determine if we know the value of a parameter even if it has multiple input SSA values; joining two `nil` will always produce a `nil`, for eaxmple.

This speeds up some local-heavy benchmarks such as protoboeuf.

Before:

```
plum% WARMUP_ITRS=0 MIN_BENCH_ITRS=10 MIN_BENCH_TIME=0 ruby --zjit benchmarks/protoboeuf/benchmark.rb
ruby 4.1.0dev (2026-08-18T13:12:35Z master 6b719ac) +ZJIT stats +PRISM [arm64-darwin25]
itr:   time
 #1:   96ms
 #2:   22ms
 #3:   33ms
 #4:   21ms
 #5:   19ms
 #6:   20ms
 #7:   19ms
 #8:   19ms
 #9:   20ms
#10:   20ms
```

After:

```
plum% WARMUP_ITRS=0 MIN_BENCH_ITRS=10 MIN_BENCH_TIME=0 ruby --zjit benchmarks/protoboeuf/benchmark.rb
ruby 4.1.0dev (2026-08-18T15:51:16Z mb-remove-constant.. 2fbcac7) +ZJIT stats +PRISM [arm64-darwin25]
itr:   time
 #1:   81ms
 #2:   16ms
 #3:   26ms
 #4:   15ms
 #5:   14ms
 #6:   14ms
 #7:   14ms
 #8:   14ms
 #9:   14ms
#10:   14ms
```
…ication

`Bundler.load_gemspec_uncached` returns nil when the gemspec evaluates
to nil, which an empty file does. `CLI::Init` was the only caller not
guarding against that, so it crashed with a `NoMethodError` backtrace
after already writing a partial Gemfile.

ruby/rubygems@fc20938c4f

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
In iseq_scan_bits, we only update original_iseq if the element at code
moved. However, this isn't correct as it's possible that code has already
gotten updated but not original_iseq. This will cause original_iseq to not
get updated.
@pull pull Bot locked and limited conversation to collaborators Aug 27, 2026
@pull pull Bot added the ⤵️ pull label Aug 27, 2026
@pull
pull Bot merged commit b4322d9 into turkdevops:master Aug 27, 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.

4 participants