History

Fixed ScriptObjectV8Proxy access after delete

ksuprynowicz committed 3 years ago

Commit 2bcd1101 parent 27554da2 files · +33 −5Browse files

Showing the changes to libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp (1 of 2 files). Show all

Unified · Split

libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp+13−1
@@ -33,8 +33,15 @@ Q_DECLARE_METATYPE(ScriptValue) · 32 unmodified lines
3333 Q_DECLARE_METATYPE(QSharedPointer<ScriptObjectV8Proxy>)
3434 Q_DECLARE_METATYPE(QSharedPointer<ScriptVariantV8Proxy>)
3535
36+
37+// These values are put into internal fields of V8 objects, to signalize what kind of data is the pointer in another
38+// internal field pointing to. Proxy unwrapping functions recognize proxies by checking for these values in internal field 0
39+// of V8 object.
40+
3641 // Value of internal field with index 0 when object contains ScriptObjectV8Proxy pointer in internal field 1
3742 static const void *internalPointsToQObjectProxy = (void *)0x13370000;
43+// Internal field value of object pointing to ScriptObjectV8Proxy is changed to this value upon proxy's deletion
44+static const void *internalPointsToDeletedQObjectProxy = (void *)0x13370008;
3845 static const void *internalPointsToQVariantProxy = (void *)0x13371000;
3946 //static const void *internalPointsToSignalProxy = (void *)0x13372000;
4047 static const void *internalPointsToMethodProxy = (void *)0x13373000;
@@ -211,8 +218,12 @@ ScriptObjectV8Proxy::~ScriptObjectV8Proxy() { · 170 unmodified lines
211218 v8::Locker locker(isolate);
212219 v8::Isolate::Scope isolateScope(isolate);
213220 v8::HandleScope handleScope(isolate);
214− _v8Object.Reset();
215221 if(_object) qDebug(scriptengine) << "Deleting object proxy: " << name();
222+ // V8TODO: once WeakPersistent pointer is added we should check if it's valid before deleting
223+ Q_ASSERT(!_v8Object.Get(isolate)->IsNullOrUndefined());
224+ // This prevents unwrap function from unwrapping proxy that was deleted
225+ _v8Object.Get(isolate)->SetAlignedPointerInInternalField(0, const_cast<void*>(internalPointsToDeletedQObjectProxy));
226+ _v8Object.Reset();
216227 if (_ownsObject) {
217228 QObject* qobject = _object;
218229 if(qobject) qobject->deleteLater();
@@ -880,6 +891,7 @@ void ScriptVariantV8Proxy::v8Set(v8::Local<v8::Name> name, v8::Local<v8::Value> · 661 unmodified lines
880891 }
881892
882893 void ScriptVariantV8Proxy::v8GetPropertyNames(const v8::PropertyCallbackInfo<v8::Array>& info) {
894+ //V8TODO: Only methods from the prototype should be listed.
883895 qDebug(scriptengine) << "ScriptObjectV8Proxy::v8GetPropertyNames called";
884896 v8::HandleScope handleScope(info.GetIsolate());
885897 auto context = info.GetIsolate()->GetCurrentContext();