From 97994c77fb5b82ca959e1188ecaee7d633d60a8e Mon Sep 17 00:00:00 2001 From: Luke Gruber Date: Thu, 12 Jun 2025 11:10:29 -0400 Subject: [PATCH] Only use regex internal reg_cache when in main ractor Using this `reg_cache` is racy across ractors, so don't use it when in a ractor. Also, its use across ractors can cause a regular expression created in 1 ractor to be used in another ractor (an isolation bug). --- common.mk | 3 +++ re.c | 15 ++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/common.mk b/common.mk index 98f4baf938..f94ad33d88 100644 --- a/common.mk +++ b/common.mk @@ -15119,6 +15119,8 @@ re.$(OBJEXT): {$(VPATH)}missing.h re.$(OBJEXT): {$(VPATH)}node.h re.$(OBJEXT): {$(VPATH)}onigmo.h re.$(OBJEXT): {$(VPATH)}oniguruma.h +re.$(OBJEXT): {$(VPATH)}ractor.h +re.$(OBJEXT): {$(VPATH)}ractor_core.h re.$(OBJEXT): {$(VPATH)}re.c re.$(OBJEXT): {$(VPATH)}re.h re.$(OBJEXT): {$(VPATH)}regenc.h @@ -15134,6 +15136,7 @@ re.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h re.$(OBJEXT): {$(VPATH)}thread_native.h re.$(OBJEXT): {$(VPATH)}util.h re.$(OBJEXT): {$(VPATH)}vm_core.h +re.$(OBJEXT): {$(VPATH)}vm_debug.h re.$(OBJEXT): {$(VPATH)}vm_opts.h regcomp.$(OBJEXT): $(hdrdir)/ruby.h regcomp.$(OBJEXT): $(hdrdir)/ruby/ruby.h diff --git a/re.c b/re.c index 3cf99c1210..e666a7c3d4 100644 --- a/re.c +++ b/re.c @@ -28,6 +28,7 @@ #include "ruby/encoding.h" #include "ruby/re.h" #include "ruby/util.h" +#include "ractor_core.h" VALUE rb_eRegexpError, rb_eRegexpTimeoutError; @@ -3499,12 +3500,16 @@ static VALUE reg_cache; VALUE rb_reg_regcomp(VALUE str) { - if (reg_cache && RREGEXP_SRC_LEN(reg_cache) == RSTRING_LEN(str) - && ENCODING_GET(reg_cache) == ENCODING_GET(str) - && memcmp(RREGEXP_SRC_PTR(reg_cache), RSTRING_PTR(str), RSTRING_LEN(str)) == 0) - return reg_cache; + if (rb_ractor_main_p()) { + if (reg_cache && RREGEXP_SRC_LEN(reg_cache) == RSTRING_LEN(str) + && ENCODING_GET(reg_cache) == ENCODING_GET(str) + && memcmp(RREGEXP_SRC_PTR(reg_cache), RSTRING_PTR(str), RSTRING_LEN(str)) == 0) + return reg_cache; - return reg_cache = rb_reg_new_str(str, 0); + return reg_cache = rb_reg_new_str(str, 0); + } else { + return rb_reg_new_str(str, 0); + } } static st_index_t reg_hash(VALUE re);