Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions concurrent_set.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ rb_concurrent_set_foreach_with_replace(VALUE set_obj, int (*callback)(VALUE *key
return;
case ST_DELETE:
set->entries[i].key = CONCURRENT_SET_DELETED;
set->deleted_entries++;
break;
}
break;
Expand Down
12 changes: 6 additions & 6 deletions doc/contributing/documentation_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Use your judgment about what the user needs to know.
Use only US-ASCII-compatible characters in a C source file.
(If you use other characters, the Ruby CI will gently let you know.)

If want to put ASCII-incompatible characters into the documentation
If you want to put ASCII-incompatible characters into the documentation
for a C-coded class, module, or method, there are workarounds
involving new files `doc/*.rdoc`:

Expand All @@ -74,7 +74,7 @@ involving new files `doc/*.rdoc`:
class Foo; end
```

- Similarly, for module `Bar` (defined in file `bar.c`,
- Similarly, for module `Bar` (defined in file `bar.c`),
create file `doc/bar.rdoc`, declare `module Bar; end`,
and place the module documentation above that declaration:

Expand Down Expand Up @@ -284,7 +284,7 @@ Use a full URL-based link for:
- A link in standard library documentation to documentation in a different
standard library package.

Doing so ensures that the link will valid even when the package documentation
Doing so ensures that the link will be valid even when the package documentation
is built independently (separately from the core documentation).

The link should lead to a target in https://docs.ruby-lang.org/en/master/.
Expand Down Expand Up @@ -484,7 +484,7 @@ Return types:
- If the method can return multiple types, use +object+.
- If the method returns the receiver, use +self+.
- If the method returns an object of the same class,
prefix `new_` if an only if the object is not +self+;
prefix `new_` if and only if the object is not +self+;
example: `new_array`.

Aliases:
Expand Down Expand Up @@ -588,7 +588,7 @@ mention `Hash#fetch` as a related method, and `Hash#merge` might mention
`Hash#merge!` as a related method.

- Consider which methods may be related
to the current method, and if you think the reader would benefit it,
to the current method, and if you think the reader would benefit from it,
at the end of the method documentation, add a line starting with
"Related: " (e.g. "Related: #fetch.").
- Don't list more than three related methods.
Expand All @@ -597,7 +597,7 @@ mention `Hash#fetch` as a related method, and `Hash#merge` might mention
- Consider adding:

- A phrase suggesting how the related method is similar to,
or different from,the current method.
or different from, the current method.
See an example at Time#getutc.
- Example code that illustrates the similarities and differences.
See examples at Time#ctime, Time#inspect, Time#to_s.
Expand Down
2 changes: 1 addition & 1 deletion doc/contributing/making_changes_to_stdlibs.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ bundle exec rake test TEST="test/test_foo.rb"
To run a single test case:

```shell
bundle exec rake test TEST="test/test_foo.rb" TESTOPS="--name=/test_mytest/"
bundle exec rake test TEST="test/test_foo.rb" TESTOPTS="--name=/test_mytest/"
```
6 changes: 6 additions & 0 deletions ext/openssl/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,15 @@ def find_openssl_library
have_func("EVP_PKEY_eq(NULL, NULL)", evp_h)
have_func("EVP_PKEY_dup(NULL)", evp_h)

# added in 3.2.0
have_func("SSL_get0_group_name(NULL)", ssl_h)

# added in 3.4.0
have_func("TS_VERIFY_CTX_set0_certs(NULL, NULL)", ts_h)

# added in 3.5.0
have_func("SSL_get0_peer_signature_name(NULL, NULL)", ssl_h)

Logging::message "=== Checking done. ===\n"

# Append flags from environment variables.
Expand Down
69 changes: 69 additions & 0 deletions ext/openssl/ossl_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2644,6 +2644,68 @@ ossl_ssl_tmp_key(VALUE self)
return Qnil;
return ossl_pkey_new(key);
}

#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
/*
* call-seq:
* ssl.sigalg => String or nil
*
* Returns the signature algorithm name, the IANA name of the signature scheme
* used by the local to sign the TLS handshake.
*/
static VALUE
ossl_ssl_get_sigalg(VALUE self)
{
SSL *ssl;
const char *name;

GetSSL(self, ssl);
if (!SSL_get0_signature_name(ssl, &name))
return Qnil;
return rb_str_new_cstr(name);
}

/*
* call-seq:
* ssl.peer_sigalg => String or nil
*
* Returns the signature algorithm name, the IANA name of the signature scheme
* used by the peer to sign the TLS handshake.
*/
static VALUE
ossl_ssl_get_peer_sigalg(VALUE self)
{
SSL *ssl;
const char *name;

GetSSL(self, ssl);
if (!SSL_get0_peer_signature_name(ssl, &name))
return Qnil;
return rb_str_new_cstr(name);
}
#endif

#ifdef HAVE_SSL_GET0_GROUP_NAME
/*
* call-seq:
* ssl.group => String or nil
*
* Returns the name of the group that was used for the key agreement of the
* current TLS session establishment.
*/
static VALUE
ossl_ssl_get_group(VALUE self)
{
SSL *ssl;
const char *name;

GetSSL(self, ssl);
if (!(name = SSL_get0_group_name(ssl)))
return Qnil;
return rb_str_new_cstr(name);
}
#endif

#endif /* !defined(OPENSSL_NO_SOCK) */

void
Expand Down Expand Up @@ -3067,6 +3129,13 @@ Init_ossl_ssl(void)
# ifdef OSSL_USE_NEXTPROTONEG
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
# endif
#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
rb_define_method(cSSLSocket, "sigalg", ossl_ssl_get_sigalg, 0);
rb_define_method(cSSLSocket, "peer_sigalg", ossl_ssl_get_peer_sigalg, 0);
#endif
#ifdef HAVE_SSL_GET0_GROUP_NAME
rb_define_method(cSSLSocket, "group", ossl_ssl_get_group, 0);
#endif

rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
Expand Down
6 changes: 3 additions & 3 deletions gc/default/default.c
Original file line number Diff line number Diff line change
Expand Up @@ -6316,9 +6316,6 @@ gc_start(rb_objspace_t *objspace, unsigned int reason)
{
unsigned int do_full_mark = !!(reason & GPR_FLAG_FULL_MARK);

/* reason may be clobbered, later, so keep set immediate_sweep here */
objspace->flags.immediate_sweep = !!(reason & GPR_FLAG_IMMEDIATE_SWEEP);

if (!rb_darray_size(objspace->heap_pages.sorted)) return TRUE; /* heap is not ready */
if (!(reason & GPR_FLAG_METHOD) && !ready_to_gc(objspace)) return TRUE; /* GC is not allowed */

Expand All @@ -6329,6 +6326,9 @@ gc_start(rb_objspace_t *objspace, unsigned int reason)
unsigned int lock_lev;
gc_enter(objspace, gc_enter_event_start, &lock_lev);

/* reason may be clobbered, later, so keep set immediate_sweep here */
objspace->flags.immediate_sweep = !!(reason & GPR_FLAG_IMMEDIATE_SWEEP);

#if RGENGC_CHECK_MODE >= 2
gc_verify_internal_consistency(objspace);
#endif
Expand Down
39 changes: 17 additions & 22 deletions misc/tsan_suppressions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,16 @@ race_top:rb_ec_vm_lock_rec
race_top:vm_lock_enter
race_top:vm_locked

# Ractors
race:ractor_take
race:ractor_register_take
race:ractor_check_take_basket
race:ractor_selector__wait

# vm->ractor.sched.grq_cnt++
race_top:ractor_sched_enq
race_top:ractor_sched_deq

# Using VM lock instead of rb_native_mutex_unlock?
# Race between vm_remove_ractor writing ractor count and
# native_thread_check_and_create_shared reading it during thread creation.
# The write happens when a ractor thread exits, the read happens when
# checking if new shared threads need to be created.
race:vm_remove_ractor

# cr->sync.wait.wakeup_status
race_top:rb_ractor_sched_sleep

# th->sched.finished at end of co_start
race_top:rb_thread_sched_mark_zombies

Expand All @@ -62,9 +56,6 @@ race_top:thread_sched_wait_events
# At thread start
race_top:rb_ractor_set_current_ec_

# Possible deadlock between Ractor lock and UBF lock
deadlock:ractor_sleep_interrupt

# TSan reports a lock-order-inversion between thread_sched_lock_ and this lock.
# It's unclear if that can cause a deadlock since the lock is on self
deadlock:ractor_lock_self
Expand All @@ -76,16 +67,22 @@ deadlock:rb_ractor_sched_barrier_start
# RVALUE_AGE_SET manipulates flag bits on objects which may be accessed in Ractors
race_top:RVALUE_AGE_SET

# Inline caches
# Inline caches and call cache updates
# Multiple threads can race when updating shared call caches during method lookups
# and argument forwarding. These races involve reading/writing cd->cc fields.
race_top:vm_cc_call_set
race_top:vm_cc_class_check
race_top:vm_search_cc
race_top:vm_search_method_slowpath0
race_top:rb_vm_opt_getconstant_path
race_top:vm_ic_attr_index_set
race:vm_ic_update
race:vm_caller_setup_fwd_args

# Shapes have problems with RCLASS_MAX_IV_COUNT and RCLASS_VARIATION_COUNT
# which are probably benign
# Race in shape_get_next where multiple threads simultaneously access and modify
# RCLASS_MAX_IV_COUNT and RCLASS_VARIATION_COUNT fields in class objects.
# One thread reads the field while another thread calls RCLASS_SET_MAX_IV_COUNT.
# This happens during instance variable shape transitions in multi-threaded code.
race:shape_get_next

# Non-atomic reads/writes
Expand All @@ -99,16 +96,10 @@ race:rb_ec_cleanup
# timer thread
race:after_fork_ruby

# object_id races
race:object_id

# Sets objspace->flags.dont_incremental while writebarrier may be running
race_top:objspace_each_exec
race_top:objspace_each_objects_ensure

# Ractor autoload
race:rb_ractor_autoload_load

# Non-atomic lazy initialized static variable
race_top:rbimpl_intern_const

Expand All @@ -123,3 +114,7 @@ race:rb_tracepoint_enable
# We walk the machine stack looking for markable objects, a thread with the GVL
# released could by mutating the stack with non-Ruby-objects
race:rb_gc_mark_machine_context

# GC enable/disable flag modifications race with object allocation flag reads
race_top:rb_gc_impl_gc_disable
race_top:rb_gc_impl_gc_enable
4 changes: 4 additions & 0 deletions prism/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -5279,6 +5279,10 @@ pm_interpolated_string_node_append(pm_interpolated_string_node_t *node, pm_node_

switch (PM_NODE_TYPE(part)) {
case PM_STRING_NODE:
// If inner string is not frozen, clear flags for this string
if (!PM_NODE_FLAG_P(part, PM_STRING_FLAGS_FROZEN)) {
CLEAR_FLAGS(node);
}
part->flags = (pm_node_flags_t) ((part->flags | PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN) & ~PM_STRING_FLAGS_MUTABLE);
break;
case PM_INTERPOLATED_STRING_NODE:
Expand Down
12 changes: 6 additions & 6 deletions prism_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ parse_regexp_concat(rb_iseq_t *iseq, const pm_scope_node_t *scope_node, const pm
static void pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node);

static int
pm_interpolated_node_compile(rb_iseq_t *iseq, const pm_node_list_t *parts, const pm_node_location_t *node_location, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, rb_encoding *implicit_regexp_encoding, rb_encoding *explicit_regexp_encoding)
pm_interpolated_node_compile(rb_iseq_t *iseq, const pm_node_list_t *parts, const pm_node_location_t *node_location, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, rb_encoding *implicit_regexp_encoding, rb_encoding *explicit_regexp_encoding, bool mutable_result)
{
int stack_size = 0;
size_t parts_size = parts->size;
Expand Down Expand Up @@ -666,7 +666,7 @@ pm_interpolated_node_compile(rb_iseq_t *iseq, const pm_node_list_t *parts, const
if (RTEST(current_string)) {
current_string = rb_fstring(current_string);

if (stack_size == 0 && interpolated) {
if (stack_size == 0 && (interpolated || mutable_result)) {
PUSH_INSN1(ret, current_location, putstring, current_string);
}
else {
Expand All @@ -690,7 +690,7 @@ pm_compile_regexp_dynamic(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_
rb_encoding *explicit_regexp_encoding = parse_regexp_encoding(scope_node, node);
rb_encoding *implicit_regexp_encoding = explicit_regexp_encoding != NULL ? explicit_regexp_encoding : scope_node->encoding;

int length = pm_interpolated_node_compile(iseq, parts, node_location, ret, popped, scope_node, implicit_regexp_encoding, explicit_regexp_encoding);
int length = pm_interpolated_node_compile(iseq, parts, node_location, ret, popped, scope_node, implicit_regexp_encoding, explicit_regexp_encoding, false);
PUSH_INSN2(ret, *node_location, toregexp, INT2FIX(parse_regexp_flags(node) & 0xFF), INT2FIX(length));
}

Expand Down Expand Up @@ -9637,7 +9637,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
}
else {
const pm_interpolated_string_node_t *cast = (const pm_interpolated_string_node_t *) node;
int length = pm_interpolated_node_compile(iseq, &cast->parts, &location, ret, popped, scope_node, NULL, NULL);
int length = pm_interpolated_node_compile(iseq, &cast->parts, &location, ret, popped, scope_node, NULL, NULL, !PM_NODE_FLAG_P(cast, PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN));
if (length > 1) PUSH_INSN1(ret, location, concatstrings, INT2FIX(length));
if (popped) PUSH_INSN(ret, location, pop);
}
Expand All @@ -9648,7 +9648,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// :"foo #{bar}"
// ^^^^^^^^^^^^^
const pm_interpolated_symbol_node_t *cast = (const pm_interpolated_symbol_node_t *) node;
int length = pm_interpolated_node_compile(iseq, &cast->parts, &location, ret, popped, scope_node, NULL, NULL);
int length = pm_interpolated_node_compile(iseq, &cast->parts, &location, ret, popped, scope_node, NULL, NULL, false);

if (length > 1) {
PUSH_INSN1(ret, location, concatstrings, INT2FIX(length));
Expand All @@ -9670,7 +9670,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,

PUSH_INSN(ret, location, putself);

int length = pm_interpolated_node_compile(iseq, &cast->parts, &location, ret, false, scope_node, NULL, NULL);
int length = pm_interpolated_node_compile(iseq, &cast->parts, &location, ret, false, scope_node, NULL, NULL, false);
if (length > 1) PUSH_INSN1(ret, location, concatstrings, INT2FIX(length));

PUSH_SEND_WITH_FLAG(ret, location, idBackquote, INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
Expand Down
25 changes: 25 additions & 0 deletions test/openssl/test_ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2041,6 +2041,27 @@ def test_client_sigalgs
end
end

def test_get_sigalg
# SSL_get0_signature_name() not supported
# SSL_get0_peer_signature_name() not supported
return unless openssl?(3, 5, 0)

server_proc = -> (ctx, ssl) {
assert_equal('rsa_pss_rsae_sha256', ssl.sigalg)
assert_nil(ssl.peer_sigalg)

readwrite_loop(ctx, ssl)
}
start_server(server_proc: server_proc) do |port|
cli_ctx = OpenSSL::SSL::SSLContext.new
server_connect(port, cli_ctx) do |ssl|
assert_nil(ssl.sigalg)
assert_equal('rsa_pss_rsae_sha256', ssl.peer_sigalg)
ssl.puts "abc"; ssl.gets
end
end
end

def test_connect_works_when_setting_dh_callback_to_nil
omit "AWS-LC does not support DHE ciphersuites" if aws_lc?

Expand Down Expand Up @@ -2088,6 +2109,8 @@ def test_set_groups_tls12
server_connect(port, ctx) { |ssl|
cs = ssl.cipher[0]
assert_match (/\AECDH/), cs
# SSL_get0_group_name() is supported on OpenSSL 3.2 or later.
assert_equal "secp384r1", ssl.group if openssl?(3, 2, 0)
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
}
Expand Down Expand Up @@ -2127,6 +2150,8 @@ def test_set_groups_tls13

server_connect(port, ctx) { |ssl|
assert_equal "TLSv1.3", ssl.ssl_version
# SSL_get0_group_name() is supported on OpenSSL 3.2 or later.
assert_equal "secp384r1", ssl.group if openssl?(3, 2, 0)
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
}
Expand Down
5 changes: 5 additions & 0 deletions test/prism/result/static_literals_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

module Prism
class StaticLiteralsTest < TestCase
def test_concatenanted_string_literal_is_not_static
node = Prism.parse_statement("'a' 'b'")
refute_predicate node, :static_literal?
end

def test_static_literals
assert_warning("1")
assert_warning("0xA", "10", "10")
Expand Down