diff --git a/.github/workflows/annocheck.yml b/.github/workflows/annocheck.yml index ecaca98b8b6b10..769d06db204527 100644 --- a/.github/workflows/annocheck.yml +++ b/.github/workflows/annocheck.yml @@ -73,7 +73,7 @@ jobs: builddir: build makeup: true - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/auto_review_pr.yml b/.github/workflows/auto_review_pr.yml index 1eb931e82ee4fe..9cb8cf0f2e1ad4 100644 --- a/.github/workflows/auto_review_pr.yml +++ b/.github/workflows/auto_review_pr.yml @@ -23,7 +23,7 @@ jobs: with: persist-credentials: false - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: '3.4' bundler: none diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml index 223b30e7e86042..9ac48df2406118 100644 --- a/.github/workflows/baseruby.yml +++ b/.github/workflows/baseruby.yml @@ -48,7 +48,7 @@ jobs: - ruby-3.3 steps: - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: ${{ matrix.ruby }} bundler: none diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml index 7254aa669e0a29..4a0dce7847673d 100644 --- a/.github/workflows/bundled_gems.yml +++ b/.github/workflows/bundled_gems.yml @@ -38,7 +38,7 @@ jobs: with: token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: 4.0 diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml index 29ddfa80d697f3..63ee1909bbc06c 100644 --- a/.github/workflows/check_dependencies.yml +++ b/.github/workflows/check_dependencies.yml @@ -42,7 +42,7 @@ jobs: - uses: ./.github/actions/setup/directories - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml index a75b564654856e..a91b6a6f6e89ac 100644 --- a/.github/workflows/check_misc.yml +++ b/.github/workflows/check_misc.yml @@ -23,7 +23,7 @@ jobs: token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} persist-credentials: false - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: head diff --git a/.github/workflows/check_sast.yml b/.github/workflows/check_sast.yml index b02f6fb76ad047..6e2b9099e87570 100644 --- a/.github/workflows/check_sast.yml +++ b/.github/workflows/check_sast.yml @@ -45,7 +45,7 @@ jobs: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@0dce2577a4760a2749d8cfb7a84b7d5585ebcb7d # v0.5.0 + uses: zizmorcore/zizmor-action@195d10ad90f31d8cd6ea1efd6ecc12969ddbe73f # v0.5.1 continue-on-error: true analyze: diff --git a/.github/workflows/modgc.yml b/.github/workflows/modgc.yml index 435efaea0b80af..997e3e8617b7ec 100644 --- a/.github/workflows/modgc.yml +++ b/.github/workflows/modgc.yml @@ -62,7 +62,7 @@ jobs: uses: ./.github/actions/setup/ubuntu if: ${{ contains(matrix.os, 'ubuntu') }} - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/parse_y.yml b/.github/workflows/parse_y.yml index ec34cc742c2f4c..77d7a8ea07208a 100644 --- a/.github/workflows/parse_y.yml +++ b/.github/workflows/parse_y.yml @@ -59,7 +59,7 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 23c6689042e7f1..71eca66d83efe1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -19,7 +19,7 @@ jobs: with: persist-credentials: false - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: 3.3.4 diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml index 0314269a32594c..f944e92a2ae199 100644 --- a/.github/workflows/spec_guards.yml +++ b/.github/workflows/spec_guards.yml @@ -49,7 +49,7 @@ jobs: with: persist-credentials: false - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: ${{ matrix.ruby }} bundler: none diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index 3ffe0cc1a5a1f2..f09c8ce88f153f 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -36,7 +36,7 @@ jobs: with: token: ${{ github.repository == 'ruby/ruby' && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: '3.4' bundler: none diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index d0491f4482d278..ac9f8187efa771 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -70,7 +70,7 @@ jobs: with: arch: ${{ matrix.arch }} - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index 0196fa51cf5616..a25348a56407c5 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -99,7 +99,7 @@ jobs: run: | echo "WASI_SDK_PATH=/opt/wasi-sdk" >> $GITHUB_ENV - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index ae01cf3ebb5d56..15437089f200c0 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -59,7 +59,7 @@ jobs: - run: md build working-directory: - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: # windows-11-arm has only 3.4.1, 3.4.2, 3.4.3, head ruby-version: ${{ !endsWith(matrix.os, 'arm') && '3.1' || '3.4' }} diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml index 0f40de798ceb3d..4e2ccd980831e4 100644 --- a/.github/workflows/yjit-ubuntu.yml +++ b/.github/workflows/yjit-ubuntu.yml @@ -133,7 +133,7 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/zjit-macos.yml b/.github/workflows/zjit-macos.yml index 12b4fc08412e31..32279d9f053ae7 100644 --- a/.github/workflows/zjit-macos.yml +++ b/.github/workflows/zjit-macos.yml @@ -92,7 +92,7 @@ jobs: rustup install ${{ matrix.rust_version }} --profile minimal rustup default ${{ matrix.rust_version }} - - uses: taiki-e/install-action@385db9cc6bf65d19775b02084a4b698eaca9a4f2 # v2.68.19 + - uses: taiki-e/install-action@a37010ded18ff788be4440302bd6830b1ae50d8b # v2.68.25 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index 20e6b456756c2e..7a42d0efa1499d 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -114,12 +114,12 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@19a43a6a2428d455dbd1b85344698725179c9d8c # v1.289.0 + - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0 with: ruby-version: '3.1' bundler: none - - uses: taiki-e/install-action@385db9cc6bf65d19775b02084a4b698eaca9a4f2 # v2.68.19 + - uses: taiki-e/install-action@a37010ded18ff788be4440302bd6830b1ae50d8b # v2.68.25 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} diff --git a/NEWS.md b/NEWS.md index 1dea7f4cdc1950..273074dc89d99c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -65,7 +65,7 @@ releases. * RubyGems 4.1.0.dev * bundler 4.1.0.dev * json 2.19.1 - * 2.18.0 to [v2.18.1][json-v2.18.1], [v2.19.0][json-v2.19.0] + * 2.18.0 to [v2.18.1][json-v2.18.1], [v2.19.0][json-v2.19.0], [v2.19.1][json-v2.19.1] * openssl 4.0.1 * 4.0.0 to [v4.0.1][openssl-v4.0.1] * prism 1.9.0 @@ -135,6 +135,7 @@ A lot of work has gone into making Ractors more stable, performant, and usable. [Feature #21785]: https://bugs.ruby-lang.org/issues/21785 [json-v2.18.1]: https://github.com/ruby/json/releases/tag/v2.18.1 [json-v2.19.0]: https://github.com/ruby/json/releases/tag/v2.19.0 +[json-v2.19.1]: https://github.com/ruby/json/releases/tag/v2.19.1 [openssl-v4.0.1]: https://github.com/ruby/openssl/releases/tag/v4.0.1 [prism-v1.9.0]: https://github.com/ruby/prism/releases/tag/v1.9.0 [resolv-v0.7.1]: https://github.com/ruby/resolv/releases/tag/v0.7.1 diff --git a/lib/rubygems/ext/cargo_builder.rb b/lib/rubygems/ext/cargo_builder.rb index 42dca3b102546c..516459dd6007b8 100644 --- a/lib/rubygems/ext/cargo_builder.rb +++ b/lib/rubygems/ext/cargo_builder.rb @@ -227,10 +227,9 @@ def cargo_crate_name(cargo_dir, manifest_path, results) raise Gem::InstallError, "cargo metadata failed#{exit_reason}" end - # cargo metadata output is specified as json, but with the - # --format-version 1 option the output is compatible with YAML, so we can - # avoid the json dependency - metadata = Gem::SafeYAML.safe_load(output) + # cargo metadata output is specified as json + require "json" + metadata = JSON.parse(output) package = metadata["packages"].find {|pkg| normalize_path(pkg["manifest_path"]) == manifest_path } unless package found = metadata["packages"].map {|md| "#{md["name"]} at #{md["manifest_path"]}" } diff --git a/lib/timeout.rb b/lib/timeout.rb index eb66e586df20e3..903a831d44b612 100644 --- a/lib/timeout.rb +++ b/lib/timeout.rb @@ -282,19 +282,21 @@ def self.timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+ message ||= "execution expired" if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after) - return scheduler.timeout_after(sec, klass || Error, message, &block) - end - - state = State.instance - state.ensure_timeout_thread_created - - perform = Proc.new do |exc| - request = Request.new(Thread.current, sec, exc, message) - state.add_request(request) - begin - return yield(sec) - ensure - request.finished + perform = Proc.new do |exc| + scheduler.timeout_after(sec, exc, message, &block) + end + else + state = State.instance + state.ensure_timeout_thread_created + + perform = Proc.new do |exc| + request = Request.new(Thread.current, sec, exc, message) + state.add_request(request) + begin + return yield(sec) + ensure + request.finished + end end end diff --git a/random.c b/random.c index ad7cbca426361c..b6c96f1b4d25ff 100644 --- a/random.c +++ b/random.c @@ -353,15 +353,23 @@ random_alloc(VALUE klass) static VALUE rand_init_default(const rb_random_interface_t *rng, rb_random_t *rnd) { - VALUE seed, buf0 = 0; + VALUE seed; size_t len = roomof(rng->default_seed_bits, 32); - uint32_t *buf = ALLOCV_N(uint32_t, buf0, len+1); - fill_random_seed(buf, len, true); - rng->init(rnd, buf, len); - seed = make_seed_value(buf, len); - explicit_bzero(buf, len * sizeof(*buf)); - ALLOCV_END(buf0); + if (LIKELY(len)) { + VALUE buf0 = 0; + uint32_t *buf = ALLOCV_N(uint32_t, buf0, len); + fill_random_seed(buf, len, true); + rng->init(rnd, buf, len); + seed = make_seed_value(buf, len); + explicit_bzero(buf, len * sizeof(*buf)); + ALLOCV_END(buf0); + } + else { + uint32_t minimul[1] = {0}; + rng->init(rnd, minimul, 0); + seed = INT2FIX(0); + } return seed; } @@ -1783,8 +1791,10 @@ st_index_t rb_memhash(const void *ptr, long len) { sip_uint64_t h = sip_hash13(hash_salt.key.sip, ptr, len); -#ifdef HAVE_UINT64_T +#if SIZEOF_ST_INDEX_T >= 8 return (st_index_t)h; +#elif defined HAVE_UINT64_T + return (st_index_t)((h >> 32) ^ h); #else return (st_index_t)(h.u32[0] ^ h.u32[1]); #endif diff --git a/test/test_timeout.rb b/test/test_timeout.rb index b11fc92aeab1cb..5db355a7da162d 100644 --- a/test/test_timeout.rb +++ b/test/test_timeout.rb @@ -459,4 +459,77 @@ def test_timeout_in_trap_handler trap(signal, original_handler) end end + + if Fiber.respond_to?(:current_scheduler) + # Stubs Fiber.current_scheduler for the duration of the block, then restores it. + def with_mock_scheduler(mock) + original = Fiber.method(:current_scheduler) + Fiber.define_singleton_method(:current_scheduler) { mock } + begin + yield + ensure + Fiber.define_singleton_method(:current_scheduler, original) + end + end + + def test_fiber_scheduler_delegates_to_timeout_after + received = nil + mock = Object.new + mock.define_singleton_method(:timeout_after) do |sec, exc, msg, &blk| + received = [sec, exc, msg] + blk.call(sec) + end + + with_mock_scheduler(mock) do + assert_equal :ok, Timeout.timeout(5) { :ok } + end + + assert_equal 5, received[0] + assert_instance_of Timeout::ExitException, received[1], "scheduler should receive an ExitException instance when no klass given" + assert_equal "execution expired", received[2] + end + + def test_fiber_scheduler_delegates_to_timeout_after_with_custom_exception + custom_error = Class.new(StandardError) + received = nil + mock = Object.new + mock.define_singleton_method(:timeout_after) do |sec, exc, msg, &blk| + received = [sec, exc, msg] + blk.call(sec) + end + + with_mock_scheduler(mock) do + assert_equal :ok, Timeout.timeout(5, custom_error, "custom message") { :ok } + end + + assert_equal [5, custom_error, "custom message"], received + end + + def test_fiber_scheduler_timeout_raises_timeout_error + mock = Object.new + mock.define_singleton_method(:timeout_after) do |sec, exc, msg, &blk| + raise exc # simulate timeout firing + end + + with_mock_scheduler(mock) do + assert_raise(Timeout::Error) do + Timeout.timeout(5) { :should_not_reach } + end + end + end + + def test_fiber_scheduler_timeout_raises_custom_error + custom_error = Class.new(StandardError) + mock = Object.new + mock.define_singleton_method(:timeout_after) do |sec, exc, msg, &blk| + raise exc, msg + end + + with_mock_scheduler(mock) do + assert_raise_with_message(custom_error, "custom message") do + Timeout.timeout(5, custom_error, "custom message") { :should_not_reach } + end + end + end + end end