Visitar URL original
Comparing master...stable · mruby/mruby · GitHub
Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mruby/mruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: mruby/mruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: stable
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 9 commits
  • 11 files changed
  • 3 contributors

Commits on May 29, 2026

  1. mruby-io: cap puts recursion depth to prevent C stack overflow

    io_puts_ary recursed unconditionally on nested arrays. For cyclic
    arrays (a = []; a << a; puts a) or pathologically deep arrays,
    this caused a C stack overflow.
    
    Add a depth cap (IO_PUTS_MAX_DEPTH = 16); on overflow, write
    "[...]\n" and return, matching CRuby's behavior on cycles. The
    pattern mirrors mruby-set's MAX_NESTED_DEPTH for the same problem
    shape (pure C recursion not dispatched as a Ruby method).
    
    Reported by OSS-Fuzz (clusterfuzz testcase 6233530857488384).
    
    Co-authored-by: Claude <noreply@anthropic.com>
    (cherry picked from commit 7dfd560)
    2 people authored and rlitretfhfgh committed May 29, 2026
    Configuration menu
    Copy the full SHA
    3533335 View commit details
    Browse the repository at this point in the history

Commits on May 30, 2026

  1. Merge pull request #6876 from dkgkdfg65/backport/7dfd560d-stable

    [stable] backport: cap IO#puts recursion depth on cyclic arrays (mruby-io)
    matz authored May 30, 2026
    Configuration menu
    Copy the full SHA
    31ea493 View commit details
    Browse the repository at this point in the history

Commits on Sep 4, 2026

  1. Merge master.

    mimaki committed Sep 4, 2026
    Configuration menu
    Copy the full SHA
    83fcecd View commit details
    Browse the repository at this point in the history
  2. Update version to 4.1.0RC.

    mimaki committed Sep 4, 2026
    Configuration menu
    Copy the full SHA
    3cf73ee View commit details
    Browse the repository at this point in the history

Commits on Sep 11, 2026

  1. hash.c: see a delete made from inside an eql? callback

    Every lookup and store can re-enter Ruby through a key's `eql?` or `hash`,
    and H_CHECK_MODIFIED is what stands between that and an iterator reading a
    hash that has moved underneath it. It watched the capacity, the flag bits
    and the two pointers, all of which a reallocation moves.
    
    A delete moves none of them. `ar_delete` and `ht_delete` mark the slot's
    key undef and decrement the count, so a delete performed inside a callback
    was invisible. The scan had read the count once and was left walking for
    more entries than the hash still held: past the used entries, past the
    allocation, and the garbage it found there went to `eql?` as a key, back
    into the array by `ar_rehash`, or out of `Hash#shift`.
    
    The count goes on what the guard compares, which is what the delete
    actually changes. EA_EACH also takes the bound H_EACH has had since
    GHSA-jfmr-44fc-gfhg: the guard speaks only for a callback the loop body
    reached, while the bound holds for a count that disagrees with the array
    for any reason at all. Without it a rehash that lost entries mid-way
    reaches `mrb_assert(size == w_size)` instead of the exception.
    
    Reported as GHSA-2778-fvwg-5m8w. All five variants of the report now
    answer with "hash modified".
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_014EUmgLgPoanCcuMZf8vFmY
    2 people authored and mimaki committed Sep 11, 2026
    Configuration menu
    Copy the full SHA
    db2f511 View commit details
    Browse the repository at this point in the history
  2. gc: put a value on the arena before letting go of what owned it

    Three places took a value out of the structure that held it and asked
    mrb_gc_protect() to keep it afterwards: Task::Queue#__pop_try, Hash#shift
    through ar_shift and ht_shift, and the argument shift in mruby-method.
    
    Between the two the value is owned by a C local, which the collector does
    not scan, and mrb_gc_protect() is not a safe place to stand there: it
    grows the arena through mrb_realloc(), and a refused allocation runs an
    emergency full GC before the value has been published. The value can be
    collected by the call that was meant to keep it, and what comes back to
    Ruby is a pointer to freed memory.
    
    Each one now protects while the array or the entry still holds the value,
    then removes it. Protecting something already reachable costs nothing.
    
    Reported for Task::Queue as GHSA-f3mm-x76x-jmcv; the other two are the
    same shape found beside it.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_014EUmgLgPoanCcuMZf8vFmY
    2 people authored and mimaki committed Sep 11, 2026
    Configuration menu
    Copy the full SHA
    5b804cb View commit details
    Browse the repository at this point in the history
  3. load.c: refuse an irep record with more locals than registers

    The VM sizes a frame's registers by the record's nregs and reaches for its
    locals within that, so a record claiming nlocals > nregs describes a frame
    that cannot exist. OP_ENTER cleared nlocals slots of an nregs-sized stack
    and wrote zeroes past it: with nlocals at 0xffff and nregs at 4, half a
    megabyte of adjacent heap, until an unmapped page stopped it.
    
    The compiler keeps nlocals <= nregs on every record it writes, and the
    loader never said so. Every reader downstream trusts it, so it is stated
    where the numbers arrive rather than where each of them is used. Compiling
    the 99 Ruby sources of the tree gives 4027 records, none of which the check
    turns away.
    
    Reported as GHSA-pmm3-g676-wxm7. Malformed bytecode is not a security
    boundary (SECURITY.md), so this is an ordinary loader fix.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_014EUmgLgPoanCcuMZf8vFmY
    2 people authored and mimaki committed Sep 11, 2026
    Configuration menu
    Copy the full SHA
    7ed5171 View commit details
    Browse the repository at this point in the history
  4. vm.c: ask OP_CALL whether its receiver is a proc

    OP_CALL read ci->stack[0] as an RProc* and dereferenced it. No compiled
    program holds the instruction: the compiler never emits one, and the only
    iseq that has it is call_iseq in src/proc.c, entered where a proc has just
    been put in place. An irep that arrived by another road could hand it
    anything, and the bytes became the pointer: an immediate a misaligned one,
    a heap object one made of the object's own contents, which a forged image
    of eight `A`s took to a read of 0x41414139.
    
    OP_BLKCALL, which reads the same kind of value out of a register, has
    asked since it was written. This asks the same and raises the same
    TypeError.
    
    Reported as GHSA-pv4h-vpp5-5349. Malformed bytecode is not a security
    boundary (SECURITY.md), so this is an ordinary VM fix.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_014EUmgLgPoanCcuMZf8vFmY
    2 people authored and mimaki committed Sep 11, 2026
    Configuration menu
    Copy the full SHA
    78a0555 View commit details
    Browse the repository at this point in the history
  5. Update version to 4.1.0RC2.

    mimaki committed Sep 11, 2026
    Configuration menu
    Copy the full SHA
    c17ffcc View commit details
    Browse the repository at this point in the history
Loading