summaryrefslogtreecommitdiff
path: root/ruby/src
diff options
context:
space:
mode:
authorJose <pepone@users.noreply.github.com>2020-12-28 14:02:50 +0100
committerGitHub <noreply@github.com>2020-12-28 14:02:50 +0100
commit938d2e5cc9b477681306e4adcdabaeab6050dd78 (patch)
tree83a3d0384459076b1f8746f98d9e550d14897de5 /ruby/src
parentFixed IceGrid/replication client configuration to ensure the sessions don't t... (diff)
downloadice-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.cpp18
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