diff options
author | Jose <pepone@users.noreply.github.com> | 2020-12-28 14:02:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-28 14:02:50 +0100 |
commit | 938d2e5cc9b477681306e4adcdabaeab6050dd78 (patch) | |
tree | 83a3d0384459076b1f8746f98d9e550d14897de5 /ruby/src | |
parent | Fixed IceGrid/replication client configuration to ensure the sessions don't t... (diff) | |
download | ice-938d2e5cc9b477681306e4adcdabaeab6050dd78.tar.bz2 ice-938d2e5cc9b477681306e4adcdabaeab6050dd78.tar.xz ice-938d2e5cc9b477681306e4adcdabaeab6050dd78.zip |
Prevent dictionary key being GC while unmarshal a value class (#1220)
* Prevent dictionary key being GC while unmarshal a value class
* Fix GC issue with string keys
Diffstat (limited to 'ruby/src')
-rw-r--r-- | ruby/src/IceRuby/Types.cpp | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/ruby/src/IceRuby/Types.cpp b/ruby/src/IceRuby/Types.cpp index fb9aefe3ce8..324f8778793 100644 --- a/ruby/src/IceRuby/Types.cpp +++ b/ruby/src/IceRuby/Types.cpp @@ -1853,7 +1853,18 @@ IceRuby::DictionaryInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallback // keyType->unmarshal(is, keyCB, Qnil, 0, false); assert(!NIL_P(keyCB->key)); - + if (valueType->usesClasses()) + { + // Temporarily set the entry with a Qnil value to ensure the key is not GC + // while unmarshaling a value class + if (RB_TYPE_P(keyCB->key, T_STRING)) + { + // For string keys create a frozen string to ensure that the key used + // in the map matches the one keep in the closure + keyCB->key = rb_str_new_frozen(keyCB->key); + } + callRuby(rb_hash_aset, hash, keyCB->key, Qnil); + } // // The callback will set the dictionary entry with the unmarshaled value, // so we pass it the key. @@ -2744,7 +2755,10 @@ IceRuby::ReadObjectCallback::invoke(const Ice::ObjectPtr& p) ex.expectedType = _info->id; throw ex; } - +#ifndef NDEBUG + // With debug builds we force a GC to ensure that all data members are correctly keep alive. + rb_gc(); +#endif _cb->unmarshaled(obj, _target, _closure); } else |