Store global proxy object in CJS_Document Avoid leaking actual global object back to V8 during callbacks. This triggered a DCHECK() in some recent V8 versions. Bug: chromium:1418955 Change-Id: Iad6173dcd2ac8dd49fb3d6c95825fa7fe9889edb Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/104630 Reviewed-by: Nigi <nigi@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/cfxjs_engine.cpp b/fxjs/cfxjs_engine.cpp index 294452a..2ff6301 100644 --- a/fxjs/cfxjs_engine.cpp +++ b/fxjs/cfxjs_engine.cpp
@@ -236,9 +236,11 @@ return scope.Escape(m_Signature.Get(GetIsolate())); } - void RunConstructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) { + void RunConstructor(CFXJS_Engine* pEngine, + v8::Local<v8::Object> obj, + v8::Local<v8::Object> proxy) { if (m_pConstructor) - m_pConstructor(pEngine, obj); + m_pConstructor(pEngine, obj, proxy); } void RunDestructor(v8::Local<v8::Object> obj) { @@ -522,15 +524,8 @@ for (uint32_t i = 1; i <= maxID; ++i) { CFXJS_ObjDefinition* pObjDef = pIsolateData->ObjDefinitionForID(i); if (pObjDef->GetObjType() == FXJSOBJTYPE_GLOBAL) { - CFXJS_PerObjectData::SetInObject(new CFXJS_PerObjectData(i), - v8Context->Global() - ->GetPrototype() - ->ToObject(v8Context) - .ToLocalChecked()); - pObjDef->RunConstructor(this, v8Context->Global() - ->GetPrototype() - ->ToObject(v8Context) - .ToLocalChecked()); + CFXJS_PerObjectData::SetInObject(new CFXJS_PerObjectData(i), pThis); + pObjDef->RunConstructor(this, pThis, pThisProxy); } else if (pObjDef->GetObjType() == FXJSOBJTYPE_STATIC) { v8::Local<v8::String> pObjName = NewString(pObjDef->GetObjName()); v8::Local<v8::Object> obj = NewFXJSBoundObject(i, FXJSOBJTYPE_STATIC); @@ -625,7 +620,7 @@ CFXJS_PerObjectData* pObjData = new CFXJS_PerObjectData(nObjDefnID); CFXJS_PerObjectData::SetInObject(pObjData, obj); - pObjDef->RunConstructor(this, obj); + pObjDef->RunConstructor(this, obj, obj); if (type == FXJSOBJTYPE_DYNAMIC) { auto* pIsolateData = FXJS_PerIsolateData::Get(GetIsolate()); V8TemplateMap* pObjsMap = pIsolateData->GetDynamicObjsMap();
diff --git a/fxjs/cfxjs_engine.h b/fxjs/cfxjs_engine.h index 3be3662..b0011fc 100644 --- a/fxjs/cfxjs_engine.h +++ b/fxjs/cfxjs_engine.h
@@ -85,8 +85,9 @@ explicit CFXJS_Engine(v8::Isolate* pIsolate); ~CFXJS_Engine() override; - using Constructor = - std::function<void(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj)>; + using Constructor = std::function<void(CFXJS_Engine* pEngine, + v8::Local<v8::Object> obj, + v8::Local<v8::Object> proxy)>; using Destructor = std::function<void(v8::Local<v8::Object> obj)>; static uint32_t GetObjDefnID(v8::Local<v8::Object> pObj);
diff --git a/fxjs/cfxjs_engine_unittest.cpp b/fxjs/cfxjs_engine_unittest.cpp index c6f01ed..8d6c36b 100644 --- a/fxjs/cfxjs_engine_unittest.cpp +++ b/fxjs/cfxjs_engine_unittest.cpp
@@ -49,9 +49,10 @@ // Object: 1 engine()->DefineObj( "perm", FXJSOBJTYPE_DYNAMIC, - [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) { + [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj, + v8::Local<v8::Object> proxy) { pEngine->SetObjectPrivate(obj, - std::make_unique<CJS_Object>(obj, nullptr)); + std::make_unique<CJS_Object>(proxy, nullptr)); perm_created = true; }, [](v8::Local<v8::Object> obj) { @@ -62,9 +63,10 @@ // Object: 2 engine()->DefineObj( "temp", FXJSOBJTYPE_DYNAMIC, - [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) { + [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj, + v8::Local<v8::Object> proxy) { pEngine->SetObjectPrivate(obj, - std::make_unique<CJS_Object>(obj, nullptr)); + std::make_unique<CJS_Object>(proxy, nullptr)); temp_created = true; }, [](v8::Local<v8::Object> obj) {
diff --git a/fxjs/js_define.h b/fxjs/js_define.h index 1228c10..5b6573a 100644 --- a/fxjs/js_define.h +++ b/fxjs/js_define.h
@@ -42,9 +42,11 @@ // to construct native object state. template <class T> -static void JSConstructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) { +static void JSConstructor(CFXJS_Engine* pEngine, + v8::Local<v8::Object> obj, + v8::Local<v8::Object> proxy) { pEngine->SetObjectPrivate( - obj, std::make_unique<T>(obj, static_cast<CJS_Runtime*>(pEngine))); + obj, std::make_unique<T>(proxy, static_cast<CJS_Runtime*>(pEngine))); } // CJS_Object has virtual dtor, template not required.