From fb3189e8f697b58795440f40e5d982ea74f06870 Mon Sep 17 00:00:00 2001 From: tompng Date: Sat, 12 Sep 2026 15:27:05 +0900 Subject: [PATCH] Guard string VALUEs while parsing their C string StringValueCStr may replace the local VALUE with the result of to_str, leaving the converted String referenced only from a C local. VpAlloc allocates a temporary buffer with rb_str_tmp_new before it scans the C string, so a GC triggered there could free the String while its contents are still being read. Add RB_GC_GUARD after the last use of the pointer in the three places that parse a String argument. Co-Authored-By: Claude Fable 5.1 --- ext/bigdecimal/bigdecimal.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 25468e9c..c15099ff 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -672,6 +672,7 @@ BigDecimal_load(VALUE self, VALUE str) } } v = bdvalue_nonnullable(CreateFromString((char *)pch, self, true, true)); + RB_GC_GUARD(str); return CheckGetValue(v); } @@ -2847,7 +2848,9 @@ rb_str_convert_to_BigDecimal(VALUE val, int raise_exception) { if (!raise_exception && memchr(RSTRING_PTR(val), '\0', RSTRING_LEN(val))) return Qnil; const char *c_str = StringValueCStr(val); - return rb_cstr_convert_to_BigDecimal(c_str, raise_exception); + VALUE bd = rb_cstr_convert_to_BigDecimal(c_str, raise_exception); + RB_GC_GUARD(val); + return bd; } static VALUE @@ -3011,6 +3014,7 @@ BigDecimal_s_interpret_loosely(VALUE klass, VALUE str) { char const *c_str = StringValueCStr(str); NULLABLE_BDVALUE v = CreateFromString(c_str, klass, false, true); + RB_GC_GUARD(str); if (v.bigdecimal_or_nil == Qnil) return Qnil; else