Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9c85a94
vcs.rb: Drop support for ruby older than 2.6
nobu Sep 17, 2025
08e7b5f
[ruby/openssl] Revert "pkey: stop retrying after non-retryable error …
rhenium Sep 16, 2025
ce1ed87
Revert "Already git 2.32 is expected in doc/contributing/building_rub…
nobu Sep 17, 2025
0f3c6ca
[ruby/openssl] c_rehash: fix hash_name output for small hashes
orgads Sep 15, 2025
a1f39b4
[ruby/openssl] Add AuthTagError exception for AEAD authentication
samuel-williams-shopify Sep 17, 2025
73b08ff
[ruby/openssl] Fix test_ssl.rb in FIPS.
junaruga Aug 29, 2025
7407561
Remove setting v1, v2, v3 when creating a new object
peterzhu2118 Sep 8, 2025
42b6ec0
Clear memory for newly allocated iseq
peterzhu2118 Sep 8, 2025
3f34975
Clear out memory for newly alloated string
peterzhu2118 Sep 8, 2025
cfc5c56
Clear out memory for newly allocated tmpbuf
peterzhu2118 Sep 8, 2025
2d57e9e
Clear out memory for newly allocated array
peterzhu2118 Sep 8, 2025
f7ddf7b
Clear object_id for newly allocated class
peterzhu2118 Sep 8, 2025
3b2f698
Null terminate newly created embedded strings
peterzhu2118 Sep 12, 2025
a456e79
Clear out memory for newly allocated structs
peterzhu2118 Sep 12, 2025
262838f
Fill more of the slot with garbage
peterzhu2118 Sep 16, 2025
a38b275
Update rb_gc_impl_new_obj in mmtk.c
peterzhu2118 Sep 16, 2025
58ece00
Clear out memory for rb_big_new
peterzhu2118 Sep 16, 2025
dd69a75
fetch-bundled_gems.rb: Fix extraneous newline
nobu Sep 17, 2025
b034a3d
bundled_gems_spec.rb: Remove useless `map`
nobu Jan 17, 2025
e758198
test-bundled-gems.rb: Allow wildcards in `BUNDLED_GEMS`
nobu Aug 12, 2025
df2f462
Skip TestObjSpaceRactor#test_tracing_does_not_crash
peterzhu2118 Sep 17, 2025
c22d84a
ZJIT: Revert documentation indent (#14580)
Sep 17, 2025
3c7a897
[ruby/prism] Reject `1 if foo = bar baz`
Earlopain Sep 17, 2025
3fa1eb7
[ruby/erb] [DOC] Adds section 'Error Reporting'
BurdetteLamar Sep 17, 2025
7ed1b24
Unset RUBY_CRASH_REPORT in tests that crash on purpose
XrXr Sep 15, 2025
4d003ea
GitHub CI: JITs: Dump RUBY_CRASH_REPORT on failure
XrXr Sep 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/workflows/yjit-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ jobs:
ruby -ne 'raise "Disassembly seems broken in dev build (output has too few lines)" unless $_.to_i > 10'
if: ${{ contains(matrix.configure, 'jit=dev') }}

- name: Enable YJIT through ENV
run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV
- name: Set ENV for YJIT
run: |
echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV
echo "RUBY_CRASH_REPORT=$(pwd)/rb_crash_%p.txt" >> $GITHUB_ENV

- name: Set test options for skipped tests
run: |
Expand Down Expand Up @@ -166,6 +168,10 @@ jobs:
if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }}
continue-on-error: ${{ matrix.continue-on-skipped_tests || false }}

- if: ${{ failure() }}
continue-on-error: true
run: tail --verbose --lines=+1 rb_crash_*.txt

- uses: ./.github/actions/slack
with:
label: ${{ matrix.test_task }} ${{ matrix.configure }} ${{ matrix.yjit_opts }}
Expand Down
11 changes: 9 additions & 2 deletions .github/workflows/yjit-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,10 @@ jobs:
ruby -ne 'raise "Disassembly seems broken in dev build (output has too few lines)" unless $_.to_i > 10'
if: ${{ contains(matrix.configure, 'jit=dev') }}

- name: Enable YJIT through ENV
run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV
- name: Set ENV for YJIT
run: |
echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV
echo "RUBY_CRASH_REPORT=$(pwd)/rb_crash_%p.txt" >> $GITHUB_ENV

# Check that the binary was built with YJIT
- name: Check YJIT enabled
Expand Down Expand Up @@ -208,6 +210,11 @@ jobs:
LAUNCHABLE_STDERR: ${{ steps.launchable.outputs.stderr_report_path }}
continue-on-error: ${{ matrix.continue-on-test_task || false }}

- name: Dump crash logs
if: ${{ failure() }}
continue-on-error: true
run: tail --verbose --lines=+1 rb_crash_*.txt

- uses: ./.github/actions/slack
with:
label: ${{ matrix.test_task }} ${{ matrix.configure }}
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/zjit-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ jobs:
ruby -ne 'raise "Disassembly seems broken in dev build (output has too few lines)" unless $_.to_i > 10'
if: ${{ contains(matrix.configure, 'jit=dev') }}

- name: Set ENV for ZJIT
run: |
echo "RUBY_CRASH_REPORT=$(pwd)/rb_crash_%p.txt" >> $GITHUB_ENV

- name: make ${{ matrix.test_task }}
run: >-
make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"}
Expand All @@ -122,6 +126,11 @@ jobs:
TESTS: ${{ matrix.test_all_opts }}
continue-on-error: ${{ matrix.continue-on-test_task || false }}

- name: Dump crash logs
if: ${{ failure() }}
continue-on-error: true
run: tail --verbose --lines=+1 rb_crash_*.txt

- uses: ./.github/actions/slack
with:
label: ${{ matrix.test_task }} ${{ matrix.configure }}
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/zjit-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ jobs:
run: ./miniruby --zjit -v | grep "+ZJIT"
if: ${{ matrix.configure != '--disable-zjit' }}

- name: Set ENV for ZJIT
run: |
echo "RUBY_CRASH_REPORT=$(pwd)/rb_crash_%p.txt" >> $GITHUB_ENV

- name: make ${{ matrix.test_task }}
run: >-
make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"}
Expand All @@ -164,6 +168,11 @@ jobs:
TESTS: ${{ matrix.test_all_opts }}
continue-on-error: ${{ matrix.continue-on-test_task || false }}

- name: Dump crash logs
if: ${{ failure() }}
continue-on-error: true
run: tail --verbose --lines=+1 rb_crash_*.txt

- uses: ./.github/actions/slack
with:
label: ${{ matrix.test_task }} ${{ matrix.configure }}
Expand Down
10 changes: 10 additions & 0 deletions array.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,11 @@ ary_alloc_heap(VALUE klass)
NEWOBJ_OF(ary, struct RArray, klass,
T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
sizeof(struct RArray), 0);

ary->as.heap.len = 0;
ary->as.heap.aux.capa = 0;
ary->as.heap.ptr = NULL;

return (VALUE)ary;
}

Expand Down Expand Up @@ -808,6 +813,11 @@ ec_ary_alloc_heap(rb_execution_context_t *ec, VALUE klass)
NEWOBJ_OF(ary, struct RArray, klass,
T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
sizeof(struct RArray), ec);

ary->as.heap.len = 0;
ary->as.heap.aux.capa = 0;
ary->as.heap.ptr = NULL;

return (VALUE)ary;
}

Expand Down
4 changes: 3 additions & 1 deletion bignum.c
Original file line number Diff line number Diff line change
Expand Up @@ -3055,7 +3055,9 @@ bignew_1(VALUE klass, size_t len, int sign)
VALUE
rb_big_new(size_t len, int sign)
{
return bignew(len, sign != 0);
VALUE obj = bignew(len, sign != 0);
memset(BIGNUM_DIGITS(obj), 0, len * sizeof(BDIGIT));
return obj;
}

VALUE
Expand Down
2 changes: 2 additions & 0 deletions class.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,8 @@ class_alloc0(enum ruby_value_type type, VALUE klass, bool namespaceable)

NEWOBJ_OF(obj, struct RClass, klass, flags, alloc_size, 0);

obj->object_id = 0;

memset(RCLASS_EXT_PRIME(obj), 0, sizeof(rb_classext_t));

/* ZALLOC
Expand Down
5 changes: 3 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,10 @@ AC_ARG_WITH(git,
{
test x"$HAVE_GIT" = xyes &&
command -v "$GIT" > /dev/null &&
# see Dependencies in doc/contributing/building_ruby.md
# `git -C`: 1.8.5
# `git log --no-show-signature`: 2.10.0
AS_CASE([`$GIT -C . --version 2> /dev/null | sed 's/.* //'`],
[0.*|1.*|2.@<:@0-9@:>@.*|2.@<:@12@:>@@<:@0-9@:>@.*|2.3@<:@01@:>@.*], [false],
[0.*|1.*|2.@<:@0-9@:>@.*], [false],
[true])
} || HAVE_GIT=no GIT=never-use
AC_SUBST(GIT)
Expand Down
15 changes: 13 additions & 2 deletions ext/openssl/ossl_cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*/
static VALUE cCipher;
static VALUE eCipherError;
static VALUE eAuthTagError;
static ID id_auth_tag_len, id_key_set;

static VALUE ossl_cipher_alloc(VALUE klass);
Expand Down Expand Up @@ -415,8 +416,17 @@ ossl_cipher_final(VALUE self)

GetCipher(self, ctx);
str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx));
if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len))
ossl_raise(eCipherError, NULL);
if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len)) {
/* For AEAD ciphers, this is likely an authentication failure */
if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) {
/* For AEAD ciphers, EVP_CipherFinal_ex failures are authentication tag verification failures */
ossl_raise(eAuthTagError, "AEAD authentication tag verification failed");
}
else {
/* For non-AEAD ciphers */
ossl_raise(eCipherError, "cipher final failed");
}
}
assert(out_len <= RSTRING_LEN(str));
rb_str_set_len(str, out_len);

Expand Down Expand Up @@ -1027,6 +1037,7 @@ Init_ossl_cipher(void)
*/
cCipher = rb_define_class_under(mOSSL, "Cipher", rb_cObject);
eCipherError = rb_define_class_under(cCipher, "CipherError", eOSSLError);
eAuthTagError = rb_define_class_under(cCipher, "AuthTagError", eCipherError);

rb_define_alloc_func(cCipher, ossl_cipher_alloc);
rb_define_method(cCipher, "initialize_copy", ossl_cipher_copy, 1);
Expand Down
41 changes: 14 additions & 27 deletions ext/openssl/ossl_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,13 @@ ossl_pkey_wrap(EVP_PKEY *pkey)
# include <openssl/decoder.h>

static EVP_PKEY *
ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass,
int *retryable)
ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass)
{
void *ppass = (void *)pass;
OSSL_DECODER_CTX *dctx;
EVP_PKEY *pkey = NULL;
int pos = 0, pos2;

*retryable = 0;
dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, input_type, NULL, NULL,
selection, NULL, NULL);
if (!dctx)
Expand All @@ -102,32 +100,25 @@ ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass,
goto out;
while (1) {
if (OSSL_DECODER_from_bio(dctx, bio) == 1)
goto out;
if (BIO_eof(bio))
break;
// Error queue may not be populated in OpenSSL < 3.0.11 and < 3.1.3
// https://github.com/openssl/openssl/pull/21603
unsigned long err = ERR_peek_error();
if (err && ERR_GET_REASON(err) != ERR_R_UNSUPPORTED)
break;
if (BIO_eof(bio) == 1) {
*retryable = 1;
break;
}
pos2 = BIO_tell(bio);
if (pos2 < 0 || pos2 <= pos) {
*retryable = 1;
if (pos2 < 0 || pos2 <= pos)
break;
}
ossl_clear_error();
pos = pos2;
}
out:
OSSL_BIO_reset(bio);
OSSL_DECODER_CTX_free(dctx);
return pkey;
}

EVP_PKEY *
ossl_pkey_read_generic(BIO *bio, VALUE pass)
{
EVP_PKEY *pkey = NULL;
/* First check DER, then check PEM. */
const char *input_types[] = {"DER", "PEM"};
int input_type_num = (int)(sizeof(input_types) / sizeof(char *));
Expand Down Expand Up @@ -176,22 +167,18 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
EVP_PKEY_PUBLIC_KEY
};
int selection_num = (int)(sizeof(selections) / sizeof(int));
int i, j;

for (int i = 0; i < input_type_num; i++) {
for (int j = 0; j < selection_num; j++) {
if (i || j) {
ossl_clear_error();
BIO_reset(bio);
for (i = 0; i < input_type_num; i++) {
for (j = 0; j < selection_num; j++) {
pkey = ossl_pkey_read(bio, input_types[i], selections[j], pass);
if (pkey) {
goto out;
}

int retryable;
EVP_PKEY *pkey = ossl_pkey_read(bio, input_types[i], selections[j],
pass, &retryable);
if (pkey || !retryable)
return pkey;
}
}
return NULL;
out:
return pkey;
}
#else
EVP_PKEY *
Expand Down
32 changes: 23 additions & 9 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ typedef struct gc_function_map {
void (*stress_set)(void *objspace_ptr, VALUE flag);
VALUE (*stress_get)(void *objspace_ptr);
// Object allocation
VALUE (*new_obj)(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, bool wb_protected, size_t alloc_size);
VALUE (*new_obj)(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size);
size_t (*obj_slot_size)(VALUE obj);
size_t (*heap_id_for_size)(void *objspace_ptr, size_t size);
bool (*size_allocatable_p)(size_t size);
Expand Down Expand Up @@ -984,9 +984,9 @@ gc_validate_pc(void)
}

static inline VALUE
newobj_of(rb_ractor_t *cr, VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, bool wb_protected, size_t size)
newobj_of(rb_ractor_t *cr, VALUE klass, VALUE flags, bool wb_protected, size_t size)
{
VALUE obj = rb_gc_impl_new_obj(rb_gc_get_objspace(), cr->newobj_cache, klass, flags, v1, v2, v3, wb_protected, size);
VALUE obj = rb_gc_impl_new_obj(rb_gc_get_objspace(), cr->newobj_cache, klass, flags, wb_protected, size);

gc_validate_pc();

Expand Down Expand Up @@ -1016,9 +1016,9 @@ newobj_of(rb_ractor_t *cr, VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v
# endif

memset(
(void *)(obj + RVALUE_SIZE),
(void *)(obj + sizeof(struct RBasic)),
GC_DEBUG_SLOT_FILL_SPECIAL_VALUE,
rb_gc_obj_slot_size(obj) - RVALUE_SIZE
rb_gc_obj_slot_size(obj) - sizeof(struct RBasic)
);
#endif

Expand All @@ -1029,14 +1029,14 @@ VALUE
rb_wb_unprotected_newobj_of(VALUE klass, VALUE flags, size_t size)
{
GC_ASSERT((flags & FL_WB_PROTECTED) == 0);
return newobj_of(GET_RACTOR(), klass, flags, 0, 0, 0, FALSE, size);
return newobj_of(GET_RACTOR(), klass, flags, FALSE, size);
}

VALUE
rb_wb_protected_newobj_of(rb_execution_context_t *ec, VALUE klass, VALUE flags, size_t size)
{
GC_ASSERT((flags & FL_WB_PROTECTED) == 0);
return newobj_of(rb_ec_ractor_ptr(ec), klass, flags, 0, 0, 0, TRUE, size);
return newobj_of(rb_ec_ractor_ptr(ec), klass, flags, TRUE, size);
}

#define UNEXPECTED_NODE(func) \
Expand All @@ -1057,7 +1057,14 @@ rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FU
{
RUBY_ASSERT_ALWAYS(dfree != (RUBY_DATA_FUNC)1);
if (klass) rb_data_object_check(klass);
return newobj_of(GET_RACTOR(), klass, T_DATA, (VALUE)dmark, (VALUE)dfree, (VALUE)datap, !dmark, sizeof(struct RTypedData));
VALUE obj = newobj_of(GET_RACTOR(), klass, T_DATA, !dmark, sizeof(struct RTypedData));

struct RData *data = (struct RData *)obj;
data->dmark = dmark;
data->dfree = dfree;
data->data = datap;

return obj;
}

VALUE
Expand All @@ -1074,7 +1081,14 @@ typed_data_alloc(VALUE klass, VALUE typed_flag, void *datap, const rb_data_type_
RBIMPL_NONNULL_ARG(type);
if (klass) rb_data_object_check(klass);
bool wb_protected = (type->flags & RUBY_FL_WB_PROTECTED) || !type->function.dmark;
return newobj_of(GET_RACTOR(), klass, T_DATA | RUBY_TYPED_FL_IS_TYPED_DATA, 0, ((VALUE)type) | typed_flag, (VALUE)datap, wb_protected, size);
VALUE obj = newobj_of(GET_RACTOR(), klass, T_DATA | RUBY_TYPED_FL_IS_TYPED_DATA, wb_protected, size);

struct RTypedData *data = (struct RTypedData *)obj;
data->fields_obj = 0;
*(VALUE *)&data->type = ((VALUE)type) | typed_flag;
data->data = datap;

return obj;
}

VALUE
Expand Down
16 changes: 2 additions & 14 deletions gc/default/default.c
Original file line number Diff line number Diff line change
Expand Up @@ -2096,16 +2096,6 @@ heap_prepare(rb_objspace_t *objspace, rb_heap_t *heap)
GC_ASSERT(heap->free_pages != NULL);
}

static inline VALUE
newobj_fill(VALUE obj, VALUE v1, VALUE v2, VALUE v3)
{
VALUE *p = (VALUE *)(obj + sizeof(struct RBasic));
p[0] = v1;
p[1] = v2;
p[2] = v3;
return obj;
}

#if GC_DEBUG
static inline const char*
rb_gc_impl_source_location_cstr(int *ptr)
Expand Down Expand Up @@ -2146,8 +2136,6 @@ newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace,
#endif

#if RGENGC_CHECK_MODE
newobj_fill(obj, 0, 0, 0);

int lev = RB_GC_VM_LOCK_NO_BARRIER();
{
check_rvalue_consistency(objspace, obj);
Expand Down Expand Up @@ -2469,7 +2457,7 @@ newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, rb_objspace_t *objspace
}

VALUE
rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, bool wb_protected, size_t alloc_size)
rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size)
{
VALUE obj;
rb_objspace_t *objspace = objspace_ptr;
Expand Down Expand Up @@ -2500,7 +2488,7 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
newobj_slowpath_wb_unprotected(klass, flags, objspace, cache, heap_idx);
}

return newobj_fill(obj, v1, v2, v3);
return obj;
}

static int
Expand Down
Loading