diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp index 117f75c52..0f77ea83d 100644 --- a/fxjs/xfa/cfxjse_engine.cpp +++ b/fxjs/xfa/cfxjse_engine.cpp @@ -963,8 +963,9 @@ CXFA_Object* CFXJSE_Engine::ToXFAObject(v8::Local obj) { } v8::Local CFXJSE_Engine::NewNormalXFAObject(CXFA_Object* obj) { - v8::EscapableHandleScope scope(GetIsolate()); - v8::Local object = obj->JSObject()->NewBoundV8Object( - GetIsolate(), GetJseNormalClass()->GetTemplate(GetIsolate())); - return scope.Escape(object); + // BANDAID: route through the binding map so a cppgc::Persistent roots the + // bound CJX_Object for as long as this engine lives. Without this, the raw + // pointer stored in the v8 wrapper's internal field can dangle after a + // standalone cppgc GC, leading to UAF in ToObject()/NormalPropertyGetter(). + return GetOrCreateJSBindingFromMap(obj); }