Skip to content

🚨 [security] Update oj 3.16.6 → 3.17.3 (minor)#196

Open
depfu[bot] wants to merge 1 commit into
masterfrom
depfu/update/oj-3.17.3
Open

🚨 [security] Update oj 3.16.6 → 3.17.3 (minor)#196
depfu[bot] wants to merge 1 commit into
masterfrom
depfu/update/oj-3.17.3

Conversation

@depfu

@depfu depfu Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

🚨 Your current dependencies have known security vulnerabilities 🚨

This dependency update fixes known security vulnerabilities. Please see the details below and assess their impact carefully. We recommend to merge and deploy this as soon as possible!


Here is everything you need to know about this update. Please take a good look at what changed and the test results before merging this pull request.

What changed?

✳️ oj (3.16.6 → 3.17.3) · Repo · Changelog

Security Advisories 🚨

🚨 Oj: Use-After-Free in Oj::Parser Symbol Key Cache Toggle

Summary

Disabling symbol_keys on a reused Oj::Parser instance triggers a heap use-after-free. When symbol_keys is toggled from true to false, opt_symbol_keys_set frees the internal key cache (cache_free) but does not clear the pointer. The next parse call reads from the freed cache via cache_intern, producing a use-after-free.

Version

  • Software: oj gem
  • Affected: all versions with ext/oj/usual.c
  • Latest tested: 3.17.1 (confirmed present)

Details

ext/oj/usual.c, opt_symbol_keys_set:

// usual.c:1043–1051
if (symbol_keys) {
    d->key_cache = cache_create(...);   // allocate
} else {
    cache_free(d->key_cache);           // free — but d->key_cache pointer not NULLed
}

On the next parse call, cache_keycache_intern reads from d->key_cache which now points to freed memory.

ASAN report:

==145265==ERROR: AddressSanitizer: heap-use-after-free on address 0x50b00001a318
READ of size 8 at 0x50b00001a318 thread T0
    #0 cache_intern            /ext/oj/cache.c:328
    #1 cache_key               /ext/oj/usual.c:161
    #2 close_object            /ext/oj/usual.c:285
    #3 parse                   /ext/oj/parser.c:693
    #4 parser_parse            /ext/oj/parser.c:1408
freed by thread T0 here:
    #0 free
    #1 cache_free              /ext/oj/cache.c:277
    #2 opt_symbol_keys_set     /ext/oj/usual.c:1051
    #3 option                  /ext/oj/usual.c:1111
    #4 parser_missing          /ext/oj/parser.c:1362
0x50b00001a318 is 40 bytes inside freed 112-byte region [fd]fd fd fd fd fd fd fd

Reproduce

require 'oj'
p = Oj::Parser.new(:usual, symbol_keys: true)
p.symbol_keys = false     # frees cache without nulling pointer
p.parse('{"attacker":1}') # UAF: reads freed cache

🚨 Oj: Stack Buffer Overflow in Oj.dump via Large Indent

Summary

Oj.dump is vulnerable to a stack-based buffer overflow when a large :indent value is provided by the developer. fill_indent in dump.h calls memset(indent_str, ' ', (size_t)opts->indent) without validating the size. When opts->indent is set to INT_MAX (2,147,483,647), the (size_t) cast preserves the large value and memset writes 2 GB into the stack-allocated out buffer (4,184 bytes), corrupting the stack and crashing the process.

Version

  • Software: oj gem
  • Affected: all versions with ext/oj/dump.h
  • Latest tested: 3.17.1 (confirmed present)

Details

ext/oj/dump.h, line 77:

static void fill_indent(Out out, int depth) {
    if (0 < out->opts->indent) {
        size_t len = (size_t)(out->opts->indent * depth);
        // ...
        memset(out->buf + ..., ' ', len);  // len = 2147483647 * depth

The indent option is accepted as a plain Ruby integer and stored as int without range validation. Multiplying by depth can produce a value larger than any stack or heap buffer.

ASAN report:

==69820==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fd1fc201278
WRITE of size 2147483647 at 0x7fd1fc201278 thread T0
    #0 memset
    #1 fill_indent  /ext/oj/dump.h:77
    #2 dump_array   /ext/oj/dump_compat.c:165
    #3 oj_dump_obj_to_json_using_params  /ext/oj/dump.c:818
    #4 dump_body    /ext/oj/oj.c:1429
    #5 dump         /ext/oj/oj.c:1480
Address is in stack of thread T0 at offset 4728 in frame:
    #0 dump /ext/oj/oj.c:1453
  [544, 4728) 'out'  <== Memory access at offset 4728 overflows this variable

Reproduce

require "oj"
obj = [0]
Oj.dump(obj, mode: :compat, indent: 2_147_483_647)

Workaround

The develop should not use extreme indents and should not offer the option for users to dump Ruby data with unlimited indentation size.

🚨 Oj: intern.c form_attr (uninitialized stack read)

Summary

Oj.load in :object mode reads uninitialized stack memory (and, for long
keys, reads out of bounds) when parsing a JSON object whose key is 254 bytes
or longer. The interned bytes can surface to the caller, disclosing process
stack memory.

Details

In ext/oj/intern.c, form_attr() handles the long-key path by allocating a
heap buffer b, populating it with the attribute name, and then freeing it —
but it passed the uninitialized stack buffer buf (not b) to
rb_intern3():

static VALUE form_attr(const char *str, size_t len) {
    char buf[256];
    if (sizeof(buf) - 2 <= len) {        // long-key path (len >= 254)
        char *b = OJ_R_ALLOC_N(char, len + 2);
        // ... b is filled correctly ...
        id = rb_intern3(buf, len + 1, oj_utf8_encoding);   // BUG: reads `buf`
        OJ_R_FREE(b);
        return id;
    }
    // ...
}

rb_intern3 therefore reads len + 1 bytes of uninitialized stack memory.
When the key length is >= 256, it also reads out of bounds past the 256-byte
buf (CWE-125). The resulting bytes are interned and can reach the caller via
the produced Symbol or via the EncodingError message raised on invalid
UTF-8, leaking process stack contents.

This is the same defect previously fixed in ext/oj/usual.c; intern.c held
a duplicated copy of form_attr that was missed.

Proof of Concept

require 'oj'
key  = "A" * 300
json = %Q[{"^o":"Object","#{key}":1}]
Oj.load(json, mode: :object)

On affected versions this raises an EncodingError whose message contains
~1500 bytes of uninitialized stack memory (not the supplied "A"s). The leaked
byte count varies between runs with the identical payload (e.g. 1491 vs 1516
bytes), confirming the content is uninitialized memory rather than fixed data.

Impact

Information disclosure of process stack memory to a caller that parses
untrusted JSON with Oj.load(..., mode: :object). For keys >= 256 bytes it is
also an out-of-bounds read (CWE-125).

Severity is bounded by several preconditions: it requires :object mode
(which is already discouraged for untrusted input), the leaked bytes are
uncontrolled (the attacker cannot choose what is disclosed), and the data only
reaches an attacker if the application surfaces the resulting Symbol or
EncodingError back to them. Scored CVSS 5.3 (Medium) on that basis.

Patches

Fixed in 3.17.3: form_attr() now passes b to rb_intern3 (a
one-character change mirroring the earlier usual.c fix). Verified on the
fixed build: the same payload returns cleanly with no leak across repeated
runs.

Credit

Reported by Zac Wang (@7a6163).

🚨 Oj: Stack Buffer Overflow in Oj::Doc#each_child via Deeply Nested Input

Summary

Oj::Doc#each_child, when invoked recursively over a deeply nested JSON
document, overflows a fixed-size stack buffer and aborts the process. This is a
denial of service reachable from untrusted JSON.

Details

Two-step chain in ext/oj/fast.c:

  1. doc_each_child (~line 1501) increments doc->where past the
    where_path[MAX_STACK = 100] array with no bounds check, and never restores
    it (doc->where-- is missing). Calling each_child recursively from inside
    the yield block therefore drives doc->where beyond the array.

  2. On the next entry (~line 1478) the function copies the path into a
    stack-local buffer:

    Leaf  save_path[MAX_STACK];           // 800-byte stack buffer
    size_t wlen = doc->where - doc->where_path;
    if (0 < wlen) {
        memcpy(save_path, doc->where_path, sizeof(Leaf) * (wlen + 1));
    }

    When the previous recursive call left doc->where past where_path[100],
    wlen exceeds MAX_STACK and the memcpy overflows save_path on the C
    stack.

The Oj::Doc parser imposes no JSON nesting-depth limit (it relies on a
C-stack pressure check), so deeply nested attacker input reaches this path.

Proof of Concept

require 'oj'
depth = 200
payload = '[' * depth + '1' + ']' * depth
Oj::Doc.open(payload) do |doc|
  r = lambda { doc.each_child { |_| r.call } }
  r.call
end

Recursion depth <= 99 iterates normally; depth >= 101 aborts. lldb backtrace
on the affected build (ruby 3.3.8 / arm64-darwin24):

SIGABRT
#2 __abort
#3 __stack_chk_fail
#4 doc_each_child   (oj.bundle, fast.c)

Impact

Reliable denial of service: any endpoint that calls
Oj::Doc.open(untrusted) { |d| d.each_child ... } recursively can be crashed
with a small deeply-nested payload. On builds with a stack protector (the
default, -fstack-protector-strong) the canary aborts the process before the
saved return address is used. The Step-1 heap OOB writes into struct _doc
fields do occur, but are masked in practice because the Step-2 stack overflow
crashes first; turning them into anything beyond a crash has not been
demonstrated.

Patches

Fixed in 3.17.3: doc_each_child now bounds-checks before incrementing
doc->where (raising Oj::DepthError) and restores doc->where after the
loop, matching the existing each_leaf pattern. Verified on the fixed build:
depth >= 101 raises a clean Oj::DepthError instead of aborting.

Credit

Reported by Zac Wang (@7a6163).

🚨 Oj: Heap Buffer Overflow in Oj.dump Exception Serialization via Large Indent

Summary

Oj.dump in object mode is vulnerable to a heap buffer overflow when serializing Exception objects with a large :indent value. The serializer allocates a buffer sized for the object's attributes but does not account for the indent bytes added on each write. With indent: 5000, the accumulation of 5,000-byte indent strings overflows the 13,150-byte heap allocation, corrupting adjacent heap memory.

Version

  • Software: oj gem
  • Affected: all versions with ext/oj/dump.h
  • Latest tested: 3.17.1 (confirmed present)

Details

ext/oj/dump.h, line 75–77:

static void fill_indent(Out out, int depth) {
    if (0 < out->opts->indent) {
        memset(out->buf + out->cur, ' ', (size_t)(out->opts->indent * depth));

When dumping an Exception object in :object mode, dump_obj_attrs calls fill_indent repeatedly for each attribute. The buffer is pre-allocated based on the serialized content but not the indentation overhead. With indent: 5000 the indent block for a nested object exceeds the remaining buffer space, producing a heap-buffer-overflow of size 5,000 at the end of the allocated region.

ASAN report:

==101656==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x527000022c5e
WRITE of size 5000 at 0x527000022c5e thread T0
    #0 memset
    #1 fill_indent       /ext/oj/dump.h:77
    #2 dump_obj_attrs    /ext/oj/dump_object.c:552
    #3 dump_obj          /ext/oj/dump_object.c:80
    #4 oj_dump_obj_val   /ext/oj/dump_object.c:708
    #5 oj_dump_obj_to_json_using_params  /ext/oj/dump.c:817
    #6 dump_body         /ext/oj/oj.c:1429
    #7 dump              /ext/oj/oj.c:1480
0x527000022c5e is located 0 bytes after 13150-byte region [0x52700001f900, 0x527000022c5e)

Reproduce

require "oj"
obj = Oj.load('{"^o":"RuntimeError"}', mode: :object)
Oj.dump(obj, mode: :object, indent: 5000)

Workarounds

This is at the discretion of the developer and not a public facing option so the workaround is the develop should not use extreme indents and should not offer the option for users to dump Ruby data with unlimited indentation size.

🚨 Oj: Use-After-Free in Oj::Doc Iterators via Reentrant Close

Summary

Oj::Doc iterators (each_value, each_child, each_leaf) are vulnerable to a heap use-after-free. When a Ruby block yielded during iteration calls doc.close or d.close, the document's heap memory is freed while the C iterator is still running. When control returns from the block, the iterator reads from the freed region, producing a use-after-free accessible from pure Ruby.

Version

  • Software: oj gem
  • Affected: all versions with ext/oj/fast.c
  • Latest tested: 3.17.1 (confirmed present)

Details

The iterators in ext/oj/fast.c follow the pattern:

// fast.c:1505 (doc_each_child)
static VALUE doc_each_child(VALUE self, ...) {
    ...
    while (cur != NULL) {
        rb_yield(...);       // ← Ruby block executes here
        cur = cur->next;     // ← cur is now freed if block called close()
    }
}

rb_yield can invoke arbitrary Ruby code, including calling close() on the Doc or any child node, which calls ruby_sized_xfree on the backing buffer. On return, the C code reads cur->next from the freed region. All three iterators are affected.

ASAN report (each_child variant):

==253632==ERROR: AddressSanitizer: heap-use-after-free on address 0x5210000bd080
READ of size 8 at 0x5210000bd080 thread T0
    #0 doc_each_child  /ext/oj/fast.c:1505
0x5210000bd080 is located 896 bytes inside of 4064-byte region [0x5210000bcd00, 0x5210000bdce0)
freed by thread T0 here:
    #0 free
    #1 ruby_sized_xfree  (libruby-3.3.so.3.3)

All three iterators trigger the same freed region (fd shadow bytes):

0x5210000bd080:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd

Reproduce

require 'oj'
# each_child
Oj::Doc.open('[1,2]') { |doc| doc.each_child { |d| d.close } }
# each_value
Oj::Doc.open('[1,2]') { |doc| doc.each_value { |v| doc.close } }
# each_leaf
Oj::Doc.open('[1,[2]]') { |doc| doc.each_leaf { |d| d.close } }

🚨 Oj: Use-After-Free in Oj::Parser SAJ Callback via Input Mutation

Summary

Oj::Parser#parse is vulnerable to a heap use-after-free when a SAJ/SAJ2 callback mutates the input JSON string during parsing. The C engine holds a raw const byte * pointer into the Ruby string's internal buffer. If a callback (e.g. hash_start) resizes the string — for example by calling String#replace with a longer value — Ruby reallocates the string buffer and frees the old one. The C parser's pointer is left dangling; the next character read at parser.c:607 is a use-after-free.

Version

  • Software: oj gem
  • Affected: all versions with ext/oj/parser.c
  • Latest tested: 3.17.1 (confirmed present)

Details

ext/oj/parser.c, parser_parseparse:

static VALUE parser_parse(VALUE self, VALUE json) {
    const byte *ptr = (const byte *)StringValuePtr(json);  // raw pointer into Ruby string
    // ...
    parse(p, ptr);   // ptr used throughout; any realloc frees the backing buffer
}
// parser.c:607
static void parse(ojParser p, const byte *json) {
    const byte *b = json;
    // ...
    for (; '\0' != *b; b++) {   // ← UAF: reads freed memory after callback resizes json

Ruby's String#replace (or <<, gsub!, etc.) can trigger a reallocation of the string's internal buffer if the new content is larger than the embedded capacity, freeing the old buffer that ptr still points to.

ASAN report:

==372273==ERROR: AddressSanitizer: heap-use-after-free on address 0x51900008ed81
READ of size 1 at 0x51900008ed81 thread T0
    #0 parse          /ext/oj/parser.c:607
    #1 parser_parse   /ext/oj/parser.c:1408
0x51900008ed81 is located 1 bytes inside of 1023-byte region [0x51900008ed80, 0x51900008f17f)
freed by thread T0 here:
    #0 free
    #1 ruby_sized_xfree  (libruby-3.3.so.3.3)
Shadow bytes: [fd]fd fd fd fd fd ...  (entire region freed)

Reproduce

require 'oj'

class Mutator
def initialize(json) = (@json = json; @done = false)

def hash_start(key)
return if @done; @done = true
@json.replace('x' * 1_000_000) # triggers String realloc, frees original buffer
end

def hash_end(key); end
def array_start(key); end
def array_end(key); end
def add_value(value, key); end
end

json = '{"a":1,"pad":"' + ('A' * 1000) + '","z":2}'
parser = Oj::Parser.new(:saj)
parser.handler = Mutator.new(json)
parser.parse(json)

🚨 Oj: Negative-Size memcpy in Oj::Parser create_id Attribute Handling

Summary

Oj::Parser#parse in usual mode with create_id enabled is vulnerable to heap corruption via a negative-size memcpy. When a JSON object key is exactly 65,535 bytes long, an integer truncation in form_attr (usual.c:63) converts the length to -1 before passing it to memcpy. This causes memcpy to copy SIZE_MAX bytes (interpreted as a huge size_t), corrupting heap memory and crashing the process.

Version

  • Software: oj gem
  • Affected: all versions with ext/oj/usual.c
  • Latest tested: 3.17.1 (confirmed present)

Details

ext/oj/usual.c, form_attr:

// usual.c:55–64
static ID form_attr(const char *str, size_t slen) {
    char        buf[4096];
    // ...
    int  blen = (int)slen + 1;    // ← truncates: 65535 + 1 = 65536 → wraps to 0
                                  //   or: 65535 cast to int = 65535 (fits),
                                  //   but blen = 65536 → INT overflow on +1 if slen=INT_MAX
    // ...
    memcpy(buf, "@", 1);
    memcpy(buf + 1, str, (size_t)blen);  // ← size_t(-1) = SIZE_MAX
}

The cache (cache_intern) uses a fixed 65,536-byte slab. When slen = 65535, the arithmetic wraps and memcpy is called with (size_t)-1.

ASAN report:

==80452==ERROR: AddressSanitizer: negative-size-param: (size=-1)
    #0 memcpy
    #1 form_attr          /ext/oj/usual.c:63
    #2 cache_intern       /ext/oj/cache.c:326
    #3 get_attr_id        /ext/oj/usual.c:186
    #4 close_object_create  /ext/oj/usual.c:374
    #5 parse              /ext/oj/parser.c:693
    #6 parser_parse       /ext/oj/parser.c:1408
0x531000528800 is located 0 bytes inside of 65536-byte region [0x531000528800, 0x531000538800)

Reproduce

Generate the payload:

key = 'A' * 65535
with open('poc.json', 'w') as f:
    f.write('{"json_class":"Oj::Bag","' + key + '":1}')

Trigger:

require 'oj'
Oj::Parser.new(:usual, create_id: 'json_class').parse(STDIN.read)

🚨 Oj: Use-After-Free in Oj::Parser array_class/hash_class GC Marking

Summary

Oj::Parser in usual mode does not mark array_class and hash_class references during garbage collection. If GC runs after the class is assigned but before a parse, the class object is reclaimed, leaving the parser holding a dangling VALUE. The subsequent parse call dereferences the freed object, producing a segfault.

Version

  • Software: oj gem
  • Affected: all versions with ext/oj/usual.c / ext/oj/parser.c
  • Latest tested: 3.17.1 (confirmed present)

Details

The parser_mark function in ext/oj/parser.c is registered as the GC mark callback for the parser's TypedData. If array_class (stored as d->array_class in the Usual struct) is not passed to rb_gc_mark, the GC does not know it is referenced and may collect it.

When close_array_class (usual.c:405) later calls rb_funcallv on the collected class VALUE, it accesses freed memory, crashing at RIP: 0x7f... / 0x0000000000000000.

Crash output:

array_class finalized
about to parse
[BUG] Segmentation fault at 0x0000000000000000
    close_array_class+0x194  /ext/oj/usual.c:405
    parse+0x17b3             /ext/oj/parser.c:715
    parser_parse+0x10b       /ext/oj/parser.c:1408
RIP: 0x7fd1b46d68b7  RBP: 0x0000000000000000

Reproduce

require 'oj'
p = Oj::Parser.new(:usual,
  array_class: (ac = Class.new { def <<(_x); end }))
ObjectSpace.define_finalizer(ac, proc { warn 'array_class finalized' })
ac = nil
GC.start(full_mark: true, immediate_sweep: true)  # collect the class
p.parse('[1]')  # segfault

🚨 Oj: Use-After-Free in Oj::Parser SAJ Long Key Callback

Summary

Oj::Parser in SAJ mode does not protect cached object keys (≥ 35 bytes) from garbage collection. A Ruby callback that triggers GC inside hash_end can cause the key string to be reclaimed while the C parser still holds a pointer to it. The subsequent access to the freed string VALUE results in a segfault, confirmed by an RIP pointing to address 0x4242 (a canary-style pattern suggesting control over the freed memory's content).

Version

  • Software: oj gem
  • Affected: all versions with ext/oj/saj2.c / ext/oj/parser.c
  • Latest tested: 3.17.1 (confirmed present)

Details

Short keys (≤ 34 bytes) are stored inline on the C stack and are safe. Long keys (≥ 35 bytes) are stored as heap-allocated Ruby String objects passed to rb_funcall as the key argument. Between the key being resolved and the callback completing, a GC triggered inside the callback (e.g. GC.start) can collect the key String, leaving a dangling VALUE.

Crash output:

long_key_trigger
[BUG] Segmentation fault at 0x0000000000004242
    close_object+0x260    /ext/oj/usual.c:405  (calls rb_funcall with freed key)
    parse+0x11ff          /ext/oj/parser.c:693
    parser_parse+0x145    /ext/oj/parser.c:1408

RIP: 0x7fd1b46d68b7 RDI: 0x0000000000004242 (freed key VALUE)
R12: 0x0000000000004242

The freed VALUE 0x4242 shows the attacker-controlled content of the key string was loaded as a pointer — a classic use-after-free indicator.

Reproduce

require 'oj'

class H < Oj::Saj
def add_value(value, key)
GC.start(full_mark: true, immediate_sweep: true) if key == 'x'
end
def hash_start(key); end
def hash_end(key); end
end

p = Oj::Parser.new(:saj)
p.handler = H.new
p.parse('{"' + 'A' * 35 + '":{"x":1}}') # long outer key, GC fires on inner key

🚨 Oj: Integer Overflow in Oj.load 2GB String Handling

Summary

Oj.load is vulnerable to heap corruption when parsing a JSON string longer than 2 GB. An integer overflow in buf_append_string (buf.h:61) converts the string length to a large negative size_t, causing memcpy to copy an astronomically large amount of data out of bounds. This crashes the process and can corrupt adjacent heap memory.

Version

  • Software: oj gem
  • Affected: all versions with ext/oj/buf.h and ext/oj/parse.c
  • Latest tested: 3.17.1 (confirmed present)

Details

ext/oj/buf.h, line 61:

inline static void buf_append_string(Buf buf, const char *s, size_t slen) {
    // ...
    memcpy(buf->tail, s, slen);   // slen derived from 32-bit int that wrapped negative

In parse.c, escape sequence handling computes the remaining string length as an int:

// parse.c:402 (read_escaped_str)
int  slen = (int)(s - str);   // ← wraps to negative when string > 2 GB
buf_append_string(buf, str, (size_t)slen);  // ← (size_t)(-2147483648) = 0x80000000...

ASAN report:

==399019==ERROR: AddressSanitizer: negative-size-param: (size=-2147483648)
    #0 __asan_memcpy
    #1 buf_append_string  /ext/oj/buf.h:61
    #2 read_escaped_str   /ext/oj/parse.c:402
    #3 read_str           /ext/oj/parse.c:542
    #4 oj_parse2          /ext/oj/parse.c:882
    #5 oj_pi_parse        /ext/oj/parse.c:1256
    #6 oj_object_parse    /ext/oj/object.c:701
    #7 load               /ext/oj/oj.c:1259
0x7f5a26ff0801 is located 1 bytes inside of 2147483657-byte region [0x7f5a26ff0800, 0x7f5aa6ff0809)

Reproduce

require 'oj'
n = 1 << 31                         # 2 GB
json = '"' + ('A' * n) + 'A"'  # >2GB JSON string with a trailing escape
Oj.load(json)
Release Notes

Too many releases to show here. View the full release notes.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ bigdecimal (indirect, 3.1.8 → 4.1.2) · Repo · Changelog

Release Notes

4.1.2

More info than we can show here.

4.1.1

More info than we can show here.

4.1.0

More info than we can show here.

4.0.1

More info than we can show here.

4.0.0

More info than we can show here.

3.3.1

More info than we can show here.

3.3.0

More info than we can show here.

3.2.3

More info than we can show here.

3.2.2

More info than we can show here.

3.2.1

More info than we can show here.

3.2.0

More info than we can show here.

3.1.9 (from changelog)

More info than we can show here.

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ ostruct (indirect, 0.6.0 → 0.6.3) · Repo · Changelog

Release Notes

0.6.3

More info than we can show here.

0.6.2

More info than we can show here.

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.


Depfu Status

Depfu will automatically keep this PR conflict-free, as long as you don't add any commits to this branch yourself. You can also trigger a rebase manually by commenting with @depfu rebase.

All Depfu comment commands
@​depfu rebase
Rebases against your default branch and redoes this update
@​depfu recreate
Recreates this PR, overwriting any edits that you've made to it
@​depfu merge
Merges this PR once your tests are passing and conflicts are resolved
@​depfu cancel merge
Cancels automatic merging of this PR
@​depfu close
Closes this PR and deletes the branch
@​depfu reopen
Restores the branch and reopens this PR (if it's closed)
@​depfu pause
Ignores all future updates for this dependency and closes this PR
@​depfu pause [minor|major]
Ignores all future minor/major updates for this dependency and closes this PR
@​depfu resume
Future versions of this dependency will create PRs again (leaves this PR as is)

@depfu depfu Bot added the depfu label Jun 13, 2026
@depfu depfu Bot changed the title Update oj 3.16.6 → 3.17.3 (minor) 🚨 [security] Update oj 3.16.6 → 3.17.3 (minor) Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants