summaryrefslogtreecommitdiff
path: root/symbol.c
diff options
context:
space:
mode:
authorPeter Zhu <[email protected]>2024-02-07 11:30:20 -0500
committerPeter Zhu <[email protected]>2024-02-08 10:12:56 -0500
commit01fd262e62076277a41af72ea13f20deb1b462a2 ()
treeb6fab7e83c82f23766b0fe09a4473ebe400594a8 /symbol.c
parent6756dbf3bbdd71967472ade018c84ddedefd8a6c (diff)
Fix crash when checking symbol encoding
[Bug #20245] We sometimes pass in a fake string to sym_check_asciionly. This can crash if sym_check_asciionly raises because it creates a CFP with the fake string as the receiver which will crash if GC tries to mark the CFP. For example, the following script crashes: GC.stress = true Object.const_defined?("\xC3")
-rw-r--r--symbol.c17
1 files changed, 10 insertions, 7 deletions
@@ -581,11 +581,14 @@ register_static_symid_str(ID id, VALUE str)
}
static int
-sym_check_asciionly(VALUE str)
{
if (!rb_enc_asciicompat(rb_enc_get(str))) return FALSE;
switch (rb_enc_str_coderange(str)) {
case ENC_CODERANGE_BROKEN:
rb_raise(rb_eEncodingError, "invalid symbol in encoding %s :%+"PRIsVALUE,
rb_enc_name(rb_enc_get(str)), str);
case ENC_CODERANGE_7BIT:
@@ -778,7 +781,7 @@ intern_str(VALUE str, int mutable)
id = rb_str_symname_type(str, IDSET_ATTRSET_FOR_INTERN);
if (id == (ID)-1) id = ID_JUNK;
- if (sym_check_asciionly(str)) {
if (!mutable) str = rb_str_dup(str);
rb_enc_associate(str, rb_usascii_encoding());
}
@@ -869,7 +872,7 @@ rb_str_intern(VALUE str)
else if (USE_SYMBOL_GC) {
rb_encoding *enc = rb_enc_get(str);
rb_encoding *ascii = rb_usascii_encoding();
- if (enc != ascii && sym_check_asciionly(str)) {
str = rb_str_dup(str);
rb_enc_associate(str, ascii);
OBJ_FREEZE(str);
@@ -1116,7 +1119,7 @@ rb_check_id(volatile VALUE *namep)
*namep = name;
}
- sym_check_asciionly(name);
return lookup_str_id(name);
}
@@ -1175,7 +1178,7 @@ rb_check_symbol(volatile VALUE *namep)
*namep = name;
}
- sym_check_asciionly(name);
if ((sym = lookup_str_sym(name)) != 0) {
return sym;
@@ -1190,7 +1193,7 @@ rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
struct RString fake_str;
const VALUE name = rb_setup_fake_str(&fake_str, ptr, len, enc);
- sym_check_asciionly(name);
return lookup_str_id(name);
}
@@ -1202,7 +1205,7 @@ rb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc)
struct RString fake_str;
const VALUE name = rb_setup_fake_str(&fake_str, ptr, len, enc);
- sym_check_asciionly(name);
if ((sym = lookup_str_sym(name)) != 0) {
return sym;