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).
This commit is contained in:
Luke Gruber 2025-06-12 11:10:29 -04:00 committed by John Hawthorn
parent 6e36841dbd
commit 97994c77fb
Notes: git 2025-06-12 20:13:31 +00:00
2 changed files with 13 additions and 5 deletions

15
re.c
View file

@ -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);