From fda83cd2d6f7622fcef18e79070ecf5cc726b16d Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 21 Jul 2026 13:35:05 +0900 Subject: [PATCH] Promote Ripper DSL array elements to VALUE Ensure arguments passed through `rb_ary_new_from_args` have type `VALUE`, including when the statement-expression optimization is unavailable. This avoids undefined behavior in variadic calls. --- ext/ripper/tools/dsl.rb | 3 ++- test/ripper/test_ripper.rb | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ext/ripper/tools/dsl.rb b/ext/ripper/tools/dsl.rb index 38f859dd97..9b8796442c 100644 --- a/ext/ripper/tools/dsl.rb +++ b/ext/ripper/tools/dsl.rb @@ -37,7 +37,8 @@ class DSL if empty? "rb_ary_new()" else - "rb_ary_new_from_args(#{size}, #{map(&:to_s).join(', ')})" + values = map {|value| "(VALUE)0|(#{value})"} + "rb_ary_new_from_args(#{size}, #{values.join(', ')})" end end end diff --git a/test/ripper/test_ripper.rb b/test/ripper/test_ripper.rb index 2b3421d827..4baca69b57 100644 --- a/test/ripper/test_ripper.rb +++ b/test/ripper/test_ripper.rb @@ -225,3 +225,12 @@ end Ripper::Lexer::State.new(Ripper.const_get(name)) end end if ripper_test + +class TestRipper::DSL < Test::Unit::TestCase + def test_array_elements_are_values + require_relative "../../ext/ripper/tools/dsl" + + code = DSL.line?("/*% ripper: [$:$, 0] %*/").generate + assert_include(code, "rb_ary_new_from_args(2, (VALUE)0|(p->s_lvalue), (VALUE)0|(0))") + end +end if ripper_test