ruby-changes:35561
From: nobu <ko1@a...>
Date: Fri, 19 Sep 2014 20:06:17 +0900 (JST)
Subject: [ruby-changes:35561] nobu:r47643 (trunk): symbol.c: fix dynamic attrset ID
nobu 2014-09-19 20:06:04 +0900 (Fri, 19 Sep 2014) New Revision: 47643 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47643 Log: symbol.c: fix dynamic attrset ID * symbol.c (rb_str_dynamic_intern): check if the stem ID of attrset ID is already registered as a static ID. [ruby-dev:48559] [Bug #10259] Modified files: trunk/ChangeLog trunk/symbol.c trunk/test/ruby/test_symbol.rb Index: symbol.c =================================================================== --- symbol.c (revision 47642) +++ symbol.c (revision 47643) @@ -103,13 +103,14 @@ Init_sym(void) https://github.com/ruby/ruby/blob/trunk/symbol.c#L103 Init_id(); } -WARN_UNUSED_RESULT(static VALUE dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding *const enc)); +WARN_UNUSED_RESULT(static VALUE dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding *const enc, const ID type)); WARN_UNUSED_RESULT(static VALUE dsymbol_check(const VALUE sym)); WARN_UNUSED_RESULT(static ID dsymbol_pindown(VALUE sym)); WARN_UNUSED_RESULT(static ID lookup_str_id(VALUE str)); WARN_UNUSED_RESULT(static VALUE lookup_str_sym(const VALUE str)); WARN_UNUSED_RESULT(static VALUE lookup_id_str(ID id)); WARN_UNUSED_RESULT(static ID attrsetname_to_attr(VALUE name)); +WARN_UNUSED_RESULT(static ID attrsetname_to_attr_id(VALUE name)); ID rb_id_attrset(ID id) @@ -416,10 +417,9 @@ must_be_dynamic_symbol(VALUE x) https://github.com/ruby/ruby/blob/trunk/symbol.c#L417 } static VALUE -dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding * const enc) +dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding * const enc, const ID type) { const VALUE dsym = rb_newobj_of(klass, T_SYMBOL | FL_WB_PROTECTED); - const ID type = rb_str_symname_type(str, IDSET_ATTRSET_FOR_INTERN); rb_enc_associate(dsym, enc); OBJ_FREEZE(dsym); @@ -441,10 +441,11 @@ dsymbol_check(const VALUE sym) https://github.com/ruby/ruby/blob/trunk/symbol.c#L441 { if (UNLIKELY(rb_objspace_garbage_object_p(sym))) { const VALUE fstr = RSYMBOL(sym)->fstr; + const ID type = RSYMBOL(sym)->type; RSYMBOL(sym)->fstr = 0; unregister_sym(fstr, sym); - return dsymbol_alloc(rb_cSymbol, fstr, rb_enc_get(fstr)); + return dsymbol_alloc(rb_cSymbol, fstr, rb_enc_get(fstr), type); } else { return sym; @@ -737,6 +738,7 @@ rb_str_dynamic_intern(VALUE str) https://github.com/ruby/ruby/blob/trunk/symbol.c#L738 #if USE_SYMBOL_GC rb_encoding *enc, *ascii; VALUE sym = lookup_str_sym(str); + ID type; if (sym) { return sym; @@ -753,7 +755,16 @@ rb_str_dynamic_intern(VALUE str) https://github.com/ruby/ruby/blob/trunk/symbol.c#L755 } } - return dsymbol_alloc(rb_cSymbol, rb_fstring(str), enc); + type = rb_str_symname_type(str, IDSET_ATTRSET_FOR_INTERN); + if (type == ID_ATTRSET) { + ID attr_id = attrsetname_to_attr_id(str); + if (attr_id && !ID_DYNAMIC_SYM_P(attr_id)) { + attr_id = rb_id_attrset(attr_id); + return ID2SYM(attr_id); + } + } + + return dsymbol_alloc(rb_cSymbol, rb_fstring(str), enc, type); #else return rb_str_intern(str); #endif @@ -1083,21 +1094,28 @@ rb_check_symbol_cstr(const char *ptr, lo https://github.com/ruby/ruby/blob/trunk/symbol.c#L1094 } static ID +attrsetname_to_attr_id(VALUE name) +{ + ID id; + struct RString fake_str; + /* make local name by chopping '=' */ + const VALUE localname = rb_setup_fake_str(&fake_str, + RSTRING_PTR(name), RSTRING_LEN(name) - 1, + rb_enc_get(name)); + OBJ_FREEZE(localname); + + if ((id = lookup_str_id(localname)) != 0) { + return id; + } + RB_GC_GUARD(name); + return (ID)0; +} + +static ID attrsetname_to_attr(VALUE name) { if (rb_is_attrset_name(name)) { - ID id; - struct RString fake_str; - /* make local name by chopping '=' */ - const VALUE localname = rb_setup_fake_str(&fake_str, - RSTRING_PTR(name), RSTRING_LEN(name) - 1, - rb_enc_get(name)); - OBJ_FREEZE(localname); - - if ((id = lookup_str_id(localname)) != 0) { - return id; - } - RB_GC_GUARD(name); + return attrsetname_to_attr_id(name); } return (ID)0; Index: ChangeLog =================================================================== --- ChangeLog (revision 47642) +++ ChangeLog (revision 47643) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Sep 19 20:06:00 2014 Nobuyoshi Nakada <nobu@r...> + + * symbol.c (rb_str_dynamic_intern): check if the stem ID of + attrset ID is already registered as a static ID. + [ruby-dev:48559] [Bug #10259] + Fri Sep 19 15:48:09 2014 NAKAMURA Usaku <usa@r...> * win32/win32.c (VCSUP): nothing to do if this worktree is not under Index: test/ruby/test_symbol.rb =================================================================== --- test/ruby/test_symbol.rb (revision 47642) +++ test/ruby/test_symbol.rb (revision 47643) @@ -222,4 +222,12 @@ class TestSymbol < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_symbol.rb#L222 '', child_env: '--disable-gems') end + + def test_dynamic_attrset_id + bug10259 = '[ruby-dev:48559] [Bug #10259]' + class << (obj = Object.new) + attr_writer :unagi + end + assert_nothing_raised(NoMethodError, bug10259) {obj.send("unagi=".intern, 1)} + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/