ruby-changes:34681
From: ko1 <ko1@a...>
Date: Wed, 9 Jul 2014 15:17:06 +0900 (JST)
Subject: [ruby-changes:34681] ko1:r46764 (trunk): * parse.y: change Symbol <-> ID relationship to avoid
ko1 2014-07-09 15:14:41 +0900 (Wed, 09 Jul 2014) New Revision: 46764 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46764 Log: * parse.y: change Symbol <-> ID relationship to avoid exposing IDs from collectable symbols. [Bug #10014] Now, rb_check_id() returns 0 if corresponding symbol is pinned dynamic symbol. There is remaining intern_cstr_without_pindown(), it can return IDs from collectable symbols. We must be careful to use it (only used in parse.y). I think it should be removed if it does not have impact for performance. * parse.y: add: * STATIC_SYM2ID() * STATIC_ID2SYM() rename: * rb_pin_dynamic_symbol() -> dsymbol_pindown() * internal.h: remove: * rb_check_id_without_pindown() * rb_sym2id_without_pindown() add: * rb_check_symbol() * rb_check_symbol_cstr() * load.c: use rb_check_id() or rb_check_id_cstr(). * object.c: ditto. * struct.c: ditto. * thread.c: ditto. * vm_method.c: ditto. * string.c (sym_find): use only rb_check_symbol(). * sprintf.c (rb_str_format): use rb_check_symbol_cstr(). Modified files: trunk/ChangeLog trunk/internal.h trunk/load.c trunk/object.c trunk/parse.y trunk/sprintf.c trunk/string.c trunk/struct.c trunk/thread.c trunk/variable.c trunk/vm_method.c Index: ChangeLog =================================================================== --- ChangeLog (revision 46763) +++ ChangeLog (revision 46764) @@ -1,3 +1,46 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Jul 9 14:45:39 2014 Koichi Sasada <ko1@a...> + + * parse.y: change Symbol <-> ID relationship to avoid + exposing IDs from collectable symbols. + [Bug #10014] + + Now, rb_check_id() returns 0 if corresponding symbol is + pinned dynamic symbol. + + There is remaining intern_cstr_without_pindown(), it can return + IDs from collectable symbols. We must be careful to use it + (only used in parse.y). I think it should be removed if + it does not have impact for performance. + + * parse.y: + add: + * STATIC_SYM2ID() + * STATIC_ID2SYM() + rename: + * rb_pin_dynamic_symbol() -> dsymbol_pindown() + + * internal.h: + remove: + * rb_check_id_without_pindown() + * rb_sym2id_without_pindown() + add: + * rb_check_symbol() + * rb_check_symbol_cstr() + + * load.c: use rb_check_id() or rb_check_id_cstr(). + + * object.c: ditto. + + * struct.c: ditto. + + * thread.c: ditto. + + * vm_method.c: ditto. + + * string.c (sym_find): use only rb_check_symbol(). + + * sprintf.c (rb_str_format): use rb_check_symbol_cstr(). + Wed Jul 9 12:21:55 2014 Koichi Sasada <ko1@a...> * parse.y (symbols_i): delete garbage symbols for Symbol.all_symbols. Index: variable.c =================================================================== --- variable.c (revision 46763) +++ variable.c (revision 46764) @@ -353,7 +353,7 @@ rb_path_to_class(VALUE pathname) https://github.com/ruby/ruby/blob/trunk/variable.c#L353 } while (*p) { while (*p && *p != ':') p++; - id = rb_check_id_cstr_without_pindown(pbeg, p-pbeg, enc); + id = rb_check_id_cstr(pbeg, p-pbeg, enc); if (p[0] == ':') { if (p[1] != ':') goto undefined_class; p += 2; @@ -1404,7 +1404,7 @@ VALUE https://github.com/ruby/ruby/blob/trunk/variable.c#L1404 rb_obj_remove_instance_variable(VALUE obj, VALUE name) { VALUE val = Qnil; - const ID id = rb_check_id_without_pindown(&name); + const ID id = rb_check_id(&name); st_data_t n, v; struct st_table *iv_index_tbl; st_data_t index; @@ -1920,7 +1920,7 @@ rb_public_const_get_at(VALUE klass, ID i https://github.com/ruby/ruby/blob/trunk/variable.c#L1920 VALUE rb_mod_remove_const(VALUE mod, VALUE name) { - const ID id = rb_check_id_without_pindown(&name); + const ID id = rb_check_id(&name); if (!id) { if (rb_is_const_name(name)) { @@ -2569,7 +2569,7 @@ rb_mod_class_variables(int argc, const V https://github.com/ruby/ruby/blob/trunk/variable.c#L2569 VALUE rb_mod_remove_cvar(VALUE mod, VALUE name) { - const ID id = rb_check_id_without_pindown(&name); + const ID id = rb_check_id(&name); st_data_t val, n = id; if (!id) { Index: string.c =================================================================== --- string.c (revision 46763) +++ string.c (revision 46764) @@ -8323,14 +8323,7 @@ str_scrub_bang(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/string.c#L8323 static VALUE sym_find(VALUE dummy, VALUE sym) { - ID id = rb_check_id(&sym); - - if (id) { - return ID2SYM(id); - } - else { - return Qnil; - } + return rb_check_symbol(&sym); } /* Index: object.c =================================================================== --- object.c (revision 46763) +++ object.c (revision 46764) @@ -2135,7 +2135,7 @@ rb_mod_const_get(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/object.c#L2135 if (pbeg == p) goto wrong_name; - id = rb_check_id_cstr_without_pindown(pbeg, len = p-pbeg, enc); + id = rb_check_id_cstr(pbeg, len = p-pbeg, enc); beglen = pbeg-path; if (p < pend && p[0] == ':') { @@ -2277,7 +2277,7 @@ rb_mod_const_defined(int argc, VALUE *ar https://github.com/ruby/ruby/blob/trunk/object.c#L2277 if (pbeg == p) goto wrong_name; - id = rb_check_id_cstr_without_pindown(pbeg, len = p-pbeg, enc); + id = rb_check_id_cstr(pbeg, len = p-pbeg, enc); beglen = pbeg-path; if (p < pend && p[0] == ':') { @@ -2348,7 +2348,7 @@ rb_mod_const_defined(int argc, VALUE *ar https://github.com/ruby/ruby/blob/trunk/object.c#L2348 static VALUE rb_obj_ivar_get(VALUE obj, VALUE iv) { - ID id = rb_check_id_without_pindown(&iv); + ID id = rb_check_id(&iv); if (!id) { if (rb_is_instance_name(iv)) { @@ -2419,7 +2419,7 @@ rb_obj_ivar_set(VALUE obj, VALUE iv, VAL https://github.com/ruby/ruby/blob/trunk/object.c#L2419 static VALUE rb_obj_ivar_defined(VALUE obj, VALUE iv) { - ID id = rb_check_id_without_pindown(&iv); + ID id = rb_check_id(&iv); if (!id) { if (rb_is_instance_name(iv)) { @@ -2456,7 +2456,7 @@ rb_obj_ivar_defined(VALUE obj, VALUE iv) https://github.com/ruby/ruby/blob/trunk/object.c#L2456 static VALUE rb_mod_cvar_get(VALUE obj, VALUE iv) { - ID id = rb_check_id_without_pindown(&iv); + ID id = rb_check_id(&iv); if (!id) { if (rb_is_class_name(iv)) { @@ -2522,7 +2522,7 @@ rb_mod_cvar_set(VALUE obj, VALUE iv, VAL https://github.com/ruby/ruby/blob/trunk/object.c#L2522 static VALUE rb_mod_cvar_defined(VALUE obj, VALUE iv) { - ID id = rb_check_id_without_pindown(&iv); + ID id = rb_check_id(&iv); if (!id) { if (rb_is_class_name(iv)) { Index: load.c =================================================================== --- load.c (revision 46763) +++ load.c (revision 46764) @@ -1108,7 +1108,7 @@ rb_mod_autoload(VALUE mod, VALUE sym, VA https://github.com/ruby/ruby/blob/trunk/load.c#L1108 static VALUE rb_mod_autoload_p(VALUE mod, VALUE sym) { - ID id = rb_check_id_without_pindown(&sym); + ID id = rb_check_id(&sym); if (!id) { return Qnil; } Index: thread.c =================================================================== --- thread.c (revision 46763) +++ thread.c (revision 46764) @@ -2820,7 +2820,7 @@ rb_thread_local_aref(VALUE thread, ID id https://github.com/ruby/ruby/blob/trunk/thread.c#L2820 static VALUE rb_thread_aref(VALUE thread, VALUE key) { - ID id = rb_check_id_without_pindown(&key); + ID id = rb_check_id(&key); if (!id) return Qnil; return rb_thread_local_aref(thread, id); } @@ -2906,7 +2906,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L2906 rb_thread_variable_get(VALUE thread, VALUE key) { VALUE locals; - ID id = rb_check_id_without_pindown(&key); + ID id = rb_check_id(&key); if (!id) return Qnil; locals = rb_ivar_get(thread, id_locals); @@ -2952,7 +2952,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L2952 rb_thread_key_p(VALUE self, VALUE key) { rb_thread_t *th; - ID id = rb_check_id_without_pindown(&key); + ID id = rb_check_id(&key); GetThreadPtr(self, th); @@ -3073,7 +3073,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L3073 rb_thread_variable_p(VALUE thread, VALUE key) { VALUE locals; - ID id = rb_check_id_without_pindown(&key); + ID id = rb_check_id(&key); if (!id) return Qfalse; Index: vm_method.c =================================================================== --- vm_method.c (revision 46763) +++ vm_method.c (revision 46764) @@ -797,7 +797,7 @@ rb_mod_remove_method(int argc, VALUE *ar https://github.com/ruby/ruby/blob/trunk/vm_method.c#L797 for (i = 0; i < argc; i++) { VALUE v = argv[i]; - ID id = rb_check_id_without_pindown(&v); + ID id = rb_check_id(&v); if (!id) { rb_name_error_str(v, "method `%s' not defined in %s", RSTRING_PTR(v), rb_class2name(mod)); @@ -1008,7 +1008,7 @@ rb_mod_undef_method(int argc, VALUE *arg https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1008 int i; for (i = 0; i < argc; i++) { VALUE v = argv[i]; - ID id = rb_check_id_without_pindown(&v); + ID id = rb_check_id(&v); if (!id) { rb_method_name_error(mod, v); } @@ -1048,7 +1048,7 @@ rb_mod_undef_method(int argc, VALUE *arg https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1048 static VALUE rb_mod_method_defined(VALUE mod, VALUE mid) { - ID id = rb_check_id_without_pindown(&mid); + ID id = rb_check_id(&mid); if (!id || !rb_method_boundp(mod, id, 1)) { return Qfalse; } @@ -1062,7 +1062,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1062 check_definition(VALUE mod, VALUE mid, rb_method_flag_t noex) { const rb_method_entry_t *me; - ID id = rb_check_id_without_pindown(&mid); + ID id = rb_check_id(&mid); if (!id) return Qfalse; me = rb_method_entry(mod, id, 0); if (me) { @@ -1691,7 +1691,7 @@ obj_respond_to(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1691 ID id; rb_scan_args(argc, argv, "11", &mid, &priv); - if (!(id = rb_check_id_without_pindown(&mid))) { + if (!(id = rb_check_id(&mid))) { if (!rb_method_basic_definition_p(CLASS_OF(obj), idRespond_to_missing)) { VALUE args[2]; args[0] = ID2SYM(rb_to_id(mid)); Index: struct.c =================================================================== --- struct.c (revision 46763) +++ struct.c (revision 46764) @@ -759,7 +759,7 @@ rb_struct_aref(VALUE s, VALUE idx) https://github.com/ruby/ruby/blob/trunk/struct.c#L759 return rb_struct_aref_sym(s, idx); } else if (RB_TYPE_P(idx, T_STRING)) { - ID id = rb_check_id_without_pindown(&idx); + ID id = rb_check_id(&idx); if (!id) { rb_name_error_str(idx, "no member '%"PRIsVALUE"' in struct", QUOTE(idx)); Index: sprintf.c =================================================================== --- sprintf.c (revision 46763) +++ sprintf.c (revision 46764) @@ -506,7 +506,7 @@ rb_str_format(int argc, const VALUE *arg https://github.com/ruby/ruby/blob/trunk/sprintf.c#L506 for (; p < end; p++) { const char *t; int n; - ID id = 0; + VALUE sym = Qnil; for (t = p; t < end && *t != '%'; t++) ; PUSH(p, t - p); @@ -601,16 +601,16 @@ rb_str_format(int argc, const VALUE *arg https://github.com/ruby/ruby/blob/trunk/sprintf.c#L601 } #endif len = (int)(p - start + 1); /* including parenthesis */ - if (id) { + if (sym != Qnil) { rb_enc_raise(enc, rb_eArgError, "named%.*s after <%s>", - len, start, rb_id2name(id)); + len, start, RSTRING_PTR(rb_sym2str(sym))); } CHECKNAMEARG(start, len, enc); get_hash(&hash, argc, argv); - id = rb_check_id_cstr_without_pindown(start + 1, - len - 2 /* without parenthesis */, - enc); - if (id) nextvalue = rb_hash_lookup2(hash, ID2SYM(id), Qundef); + sym = rb_check_symbol_cstr(start + 1, + len - 2 /* without parenthesis */, + enc); + if (sym != Qnil) nextvalue = rb_hash_lookup2(hash, sym, Qundef); if (nextvalue == Qundef) { rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start); } Index: parse.y =================================================================== --- parse.y (revision 46763) +++ parse.y (revision 46764) @@ -51,7 +51,10 @@ static ID register_static_symid_str(ID, https://github.com/ruby/ruby/blob/trunk/parse.y#L51 #define REGISTER_SYMID(id, name) register_static_symid((id), (name), strlen(name), enc) #include "id.c" #endif + #define ID_DYNAMIC_SYM_P(id) (!(id&ID_STATIC_SYM)&&id>tLAST_TOKEN) +#define STATIC_SYM2ID(sym) RSHIFT((unsigned long)(sym), RUBY_SPECIAL_SHIFT) +#define STATIC_ID2SYM(id) (((VALUE)(id)<<RUBY_SPECIAL_SHIFT)|SYMBOL_FLAG) static inline int id_type(ID); #define is_notop_id(id) ((id)>tLAST_OP_ID) @@ -8831,7 +8834,6 @@ block_dup_check_gen(struct parser_params https://github.com/ruby/ruby/blob/trunk/parse.y#L8834 } } -static ID rb_pin_dynamic_symbol(VALUE); static ID attrsetname_to_attr(VALUE name); static int lookup_id_str(ID id, st_data_t *data); @@ -10481,7 +10483,7 @@ dsymbol_check(const VALUE sym) https://github.com/ruby/ruby/blob/trunk/parse.y#L10483 } static ID -rb_pin_dynamic_symbol(VALUE sym) +dsymbol_pindown(VALUE sym) { must_be_dynamic_symbol(sym); @@ -10496,19 +10498,55 @@ rb_pin_dynamic_symbol(VALUE sym) https://github.com/ruby/ruby/blob/trunk/parse.y#L10498 return (ID)sym; } -static int -lookup_str_id(st_data_t str, st_data_t *data) +static ID +lookup_str_id(st_data_t str, st_data_t *id_datap) { - ID id; + if (st_lookup(global_symbols.str_id, str, id_datap)) { + const ID id = (ID)*id_datap; - if (!st_lookup(global_symbols.str_id, str, data)) { + if (ID_DYNAMIC_SYM_P(id) && !SYMBOL_PINNED_P(id)) { + *id_datap = 0; + return FALSE; + } + else { + return TRUE; + } + } + else { return FALSE; } - id = (ID)*data; +} + +static VALUE +lookup_str_sym(const st_data_t str, st_data_t *sym_datap) +{ + if (st_lookup(global_symbols.str_id, str, sym_datap)) { + const ID id = *sym_datap; + + if (ID_DYNAMIC_SYM_P(id)) { + *sym_datap = dsymbol_check(id); + } + else { + *sym_datap = STATIC_ID2SYM(id); + } + return TRUE; + } + else { + return FALSE; + } +} + +static int +lookup_id_str(ID id, st_data_t *data) +{ if (ID_DYNAMIC_SYM_P(id)) { - *data = (st_data_t)rb_pin_dynamic_symbol((VALUE)id); + *data = RSYMBOL(id)->fstr; + return TRUE; } - return TRUE; + if (st_lookup(global_symbols.id_str, id, data)) { + return TRUE; + } + return FALSE; } static ID @@ -10535,7 +10573,7 @@ rb_intern3(const char *name, long len, r https://github.com/ruby/ruby/blob/trunk/parse.y#L10573 id = intern_cstr_without_pindown(name, len, enc); if (ID_DYNAMIC_SYM_P(id)) { - id = rb_pin_dynamic_symbol((VALUE)id); + id = dsymbol_pindown((VALUE)id); } return id; @@ -10684,10 +10722,12 @@ rb_intern(const char *name) https://github.com/ruby/ruby/blob/trunk/parse.y#L10722 ID rb_intern_str(VALUE str) { - st_data_t id; + st_data_t sym; + + if (lookup_str_sym(str, &sym)) { + return SYM2ID(sym); + } - if (lookup_str_id(str, &id)) - return (ID)id; return intern_str(rb_str_dup(str)); } @@ -10733,15 +10773,9 @@ rb_str_dynamic_intern(VALUE str) https://github.com/ruby/ruby/blob/trunk/parse.y#L10773 { #if USE_SYMBOL_GC rb_encoding *enc, *ascii; - ID id; + VALUE sym; - if (st_lookup(global_symbols.str_id, str, &id)) { - VALUE sym = ID2SYM(id); - if (ID_DYNAMIC_SYM_P(id)) { - /* because of lazy sweep, dynamic symbol may be unmarked already and swept - * at next time */ - sym = dsymbol_check(sym); - } + if (lookup_str_sym(str, &sym)) { return sym; } @@ -10762,40 +10796,17 @@ rb_str_dynamic_intern(VALUE str) https://github.com/ruby/ruby/blob/trunk/parse.y#L10796 #endif } -static int -lookup_id_str(ID id, st_data_t *data) -{ - if (ID_DYNAMIC_SYM_P(id)) { - id = (ID)dsymbol_check((VALUE)id); - *data = RSYMBOL(id)->fstr; - return TRUE; - } - if (st_lookup(global_symbols.id_str, id, data)) { - return TRUE; - } - return FALSE; -} - -ID -rb_sym2id(VALUE x) -{ - if (STATIC_SYM_P(x)) { - return RSHIFT((unsigned long)(x),RUBY_SPECIAL_SHIFT); - } - else { - return rb_pin_dynamic_symbol(x); - } -} - ID -rb_sym2id_without_pindown(VALUE x) +rb_sym2id(VALUE sym) { - if (STATIC_SYM_P(x)) { - return RSHIFT((unsigned long)(x),RUBY_SPECIAL_SHIFT); + if (STATIC_SYM_P(sym)) { + return STATIC_SYM2ID(sym); } else { - must_be_dynamic_symbol(x); - return (ID)x; + if (!SYMBOL_PINNED_P(sym)) { + dsymbol_pindown(sym); + } + return (ID)sym; } } @@ -10803,7 +10814,7 @@ VALUE https://github.com/ruby/ruby/blob/trunk/parse.y#L10814 rb_id2sym(ID x) { if (!ID_DYNAMIC_SYM_P(x)) { - return ((VALUE)(x)<<RUBY_SPECIAL_SHIFT)|SYMBOL_FLAG; + return STATIC_ID2SYM(x); } else { return (VALUE)x; @@ -10814,10 +10825,14 @@ rb_id2sym(ID x) https://github.com/ruby/ruby/blob/trunk/parse.y#L10825 VALUE rb_sym2str(VALUE sym) { - return rb_id2str(rb_sym2id_without_pindown(sym)); + if (DYNAMIC_SYM_P(sym)) { + return RSYMBOL(sym)->fstr; + } + else { + return rb_id2str(STATIC_SYM2ID(sym)); + } } - VALUE rb_id2str(ID id) { @@ -10862,7 +10877,7 @@ rb_id2str(ID id) https://github.com/ruby/ruby/blob/trunk/parse.y#L10877 str = rb_str_dup(str); rb_str_cat(str, "=", 1); register_static_symid_str(id, str); - if (st_lookup(global_symbols.id_str, id, &data)) { + if (lookup_id_str(id, &data)) { VALUE str = (VALUE)data; if (RBASIC(str)->klass == 0) RBASIC_SET_CLASS_RAW(str, rb_cString); @@ -10985,38 +11000,56 @@ rb_is_junk_id(ID id) https://github.com/ruby/ruby/blob/trunk/parse.y#L11000 ID rb_check_id(volatile VALUE *namep) { - ID id; + st_data_t id; + VALUE tmp; + VALUE name = *namep; - id = rb_check_id_without_pindown((VALUE *)namep); - if (ID_DYNAMIC_SYM_P(id)) { - id = rb_pin_dynamic_symbol((VALUE)id); + if (STATIC_SYM_P(name)) { + return STATIC_SYM2ID(name); + } + else if (DYNAMIC_SYM_P(name)) { + if (SYMBOL_PINNED_P(name)) { + return (ID)name; + } + else { + *namep = RSYMBOL(name)->fstr; + return 0; + } + } + else if (!RB_TYPE_P(name, T_STRING)) { + tmp = rb_check_string_type(name); + if (NIL_P(tmp)) { + tmp = rb_inspect(name); + rb_raise(rb_eTypeError, "%s is not a symbol nor a string", + RSTRING_PTR(tmp)); + } + name = tmp; + *namep = name; } - return id; -} + sym_check_asciionly(name); -ID -rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc) -{ - ID id; + if (lookup_str_id(name, &id)) { + return id; + } - id = rb_check_id_cstr_without_pindown(ptr, len, enc); - if (ID_DYNAMIC_SYM_P(id)) { - id = rb_pin_dynamic_symbol((VALUE)id); + { + ID gid = attrsetname_to_attr(name); + if (gid) return rb_id_attrset(gid); } - return id; + return (ID)0; } -ID -rb_check_id_without_pindown(VALUE *namep) +VALUE +rb_check_symbol(volatile VALUE *namep) { - st_data_t id; + st_data_t sym; VALUE tmp; VALUE name = *namep; if (SYMBOL_P(name)) { - return rb_sym2id_without_pindown(name); + return name; } else if (!RB_TYPE_P(name, T_STRING)) { tmp = rb_check_string_type(name); @@ -11031,55 +11064,81 @@ rb_check_id_without_pindown(VALUE *namep https://github.com/ruby/ruby/blob/trunk/parse.y#L11064 sym_check_asciionly(name); - if (st_lookup(global_symbols.str_id, (st_data_t)name, &id)) - return (ID)id; + if (lookup_str_sym(name, &sym)) { + return sym; + } { ID gid = attrsetname_to_attr(name); - if (gid) return rb_id_attrset(gid); + if (gid) return ID2SYM(rb_id_attrset(gid)); } - return (ID)0; + return Qnil; } -static ID -attrsetname_to_attr(VALUE name) +ID +rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc) { - if (rb_is_attrset_name(name)) { - st_data_t id; - struct RString fake_str; - /* make local name by chopping '=' */ - const VALUE localname = setup_fake_str(&fake_str, RSTRING_PTR(name), RSTRING_LEN(name) - 1); - rb_enc_copy(localname, name); - OBJ_FREEZE(localname); + st_data_t id; + struct RString fake_str; + const VALUE name = setup_fake_str(&fake_str, ptr, len); + rb_enc_associate(name, enc); - if (st_lookup(global_symbols.str_id, (st_data_t)localname, &id)) { - return (ID)id; + sym_check_asciionly(name); + + if (lookup_str_id(name, &id)) { + return id; + } + + if (rb_is_attrset_name(name)) { + fake_str.as.heap.len = len - 1; + if (lookup_str_id((st_data_t)name, &id)) { + return rb_id_attrset((ID)id); } - RB_GC_GUARD(name); } return (ID)0; } -ID -rb_check_id_cstr_without_pindown(const char *ptr, long len, rb_encoding *enc) +VALUE +rb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc) { - st_data_t id; + st_data_t sym; struct RString fake_str; const VALUE name = setup_fake_str(&fake_str, ptr, len); rb_enc_associate(name, enc); sym_check_asciionly(name); - if (st_lookup(global_symbols.str_id, (st_data_t)name, &id)) - return (ID)id; + if ( (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/