Clear v8 object binding in CXFA_Object destructor. Noticed this possibility while looking at another issue, this is a best practice to ensure validity. - Rename some functions for clarity. - Insist on a non-null return for GetOrCreate...() - Handle dependence in CFXA_Object destruction on the object that owns it (and may be cleaning it up in its own destructor). Change-Id: I129817f636455f630d9d911f6fff5022faa72e7b Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/52850 Commit-Queue: Tom Sepez <tsepez@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/xfa/cfxjse_context.cpp b/fxjs/xfa/cfxjse_context.cpp index 5dec89c..7a3b593 100644 --- a/fxjs/xfa/cfxjse_context.cpp +++ b/fxjs/xfa/cfxjse_context.cpp
@@ -144,6 +144,13 @@ hObject->SetAlignedPointerInInternalField(1, lpNewBinding); } +void FXJSE_ClearObjectBinding(v8::Local<v8::Object> hObject) { + ASSERT(!hObject.IsEmpty()); + ASSERT(hObject->InternalFieldCount() == 2); + hObject->SetAlignedPointerInInternalField(0, nullptr); + hObject->SetAlignedPointerInInternalField(1, nullptr); +} + CFXJSE_HostObject* FXJSE_RetrieveObjectBinding( v8::Local<v8::Object> hJSObject) { ASSERT(!hJSObject.IsEmpty());
diff --git a/fxjs/xfa/cfxjse_context.h b/fxjs/xfa/cfxjse_context.h index 347a69d..b519e77 100644 --- a/fxjs/xfa/cfxjse_context.h +++ b/fxjs/xfa/cfxjse_context.h
@@ -52,6 +52,7 @@ void FXJSE_UpdateObjectBinding(v8::Local<v8::Object> hObject, CFXJSE_HostObject* lpNewBinding); +void FXJSE_ClearObjectBinding(v8::Local<v8::Object> hJSObject); CFXJSE_HostObject* FXJSE_RetrieveObjectBinding(v8::Local<v8::Object> hJSObject); #endif // FXJS_XFA_CFXJSE_CONTEXT_H_
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp index 8c20211..e4675fd 100644 --- a/fxjs/xfa/cfxjse_engine.cpp +++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -118,6 +118,9 @@ CFXJSE_Engine::~CFXJSE_Engine() { for (const auto& pair : m_mapVariableToContext) delete ToThisProxy(pair.second->GetGlobalObject().get()); + + for (const auto& pair : m_mapObjectToValue) + pair.second->ClearHostObject(); } bool CFXJSE_Engine::RunScript(CXFA_Script::Type eScriptType, @@ -144,7 +147,8 @@ AutoRestorer<UnownedPtr<CXFA_Object>> nodeRestorer(&m_pThisObject); m_pThisObject = pThisObject; - CFXJSE_Value* pValue = pThisObject ? GetJSValueFromMap(pThisObject) : nullptr; + CFXJSE_Value* pValue = + pThisObject ? GetOrCreateJSBindingFromMap(pThisObject) : nullptr; IJS_Runtime::ScopedEventContext ctx(m_pSubordinateRuntime.Get()); return m_JsContext->ExecuteScript(btScript.c_str(), hRetValue, pValue); } @@ -161,7 +165,8 @@ if (!ResolveObjects(refNode, propname, &resolveRs, dwFlag, nullptr)) return false; if (resolveRs.dwFlags == XFA_ResolveNode_RSType_Nodes) { - pValue->Assign(GetJSValueFromMap(resolveRs.objects.front().Get())); + pValue->Assign( + GetOrCreateJSBindingFromMap(resolveRs.objects.front().Get())); return true; } if (resolveRs.dwFlags == XFA_ResolveNode_RSType_Attribute && @@ -228,7 +233,7 @@ CXFA_Object* pObj = lpScriptContext->GetDocument()->GetXFAObject(uHashCode); if (pObj) { - pValue->Assign(lpScriptContext->GetJSValueFromMap(pObj)); + pValue->Assign(lpScriptContext->GetOrCreateJSBindingFromMap(pObj)); return; } } @@ -302,7 +307,7 @@ CXFA_Object* pObject = lpScriptContext->GetVariablesThis(pOriginalObject, false); if (wsPropName.EqualsASCII("xfa")) { - CFXJSE_Value* pValue = lpScriptContext->GetJSValueFromMap( + CFXJSE_Value* pValue = lpScriptContext->GetOrCreateJSBindingFromMap( lpScriptContext->GetDocument()->GetRoot()); pReturnValue->Assign(pValue); return; @@ -739,9 +744,7 @@ m_CacheList.push_back(std::move(pList)); } -CFXJSE_Value* CFXJSE_Engine::GetJSValueFromMap(CXFA_Object* pObject) { - if (!pObject) - return nullptr; +CFXJSE_Value* CFXJSE_Engine::GetOrCreateJSBindingFromMap(CXFA_Object* pObject) { if (pObject->IsNode()) RunVariablesScript(pObject->AsNode()); @@ -750,13 +753,22 @@ return iter->second.get(); auto jsValue = pdfium::MakeUnique<CFXJSE_Value>(GetIsolate()); - jsValue->SetObject(pObject, m_pJsClass.Get()); + jsValue->SetHostObject(pObject, m_pJsClass.Get()); CFXJSE_Value* pValue = jsValue.get(); m_mapObjectToValue.insert(std::make_pair(pObject, std::move(jsValue))); return pValue; } +void CFXJSE_Engine::RemoveJSBindingFromMap(CXFA_Object* pObject) { + auto iter = m_mapObjectToValue.find(pObject); + if (iter == m_mapObjectToValue.end()) + return; + + iter->second->ClearHostObject(); + m_mapObjectToValue.erase(iter); +} + void CFXJSE_Engine::SetNodesOfRunScript(std::vector<CXFA_Node*>* pArray) { m_pScriptNodeArray = pArray; }
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h index d96eaee..addf0cc 100644 --- a/fxjs/xfa/cfxjse_engine.h +++ b/fxjs/xfa/cfxjse_engine.h
@@ -80,7 +80,10 @@ XFA_RESOLVENODE_RS* resolveNodeRS, uint32_t dwStyles, CXFA_Node* bindNode); - CFXJSE_Value* GetJSValueFromMap(CXFA_Object* pObject); + + CFXJSE_Value* GetOrCreateJSBindingFromMap(CXFA_Object* pObject); + void RemoveJSBindingFromMap(CXFA_Object* pObject); + void AddToCacheList(std::unique_ptr<CXFA_List> pList); CXFA_Object* GetThisObject() const { return m_pThisObject.Get(); }
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp index 47b52a9..6782fb6 100644 --- a/fxjs/xfa/cfxjse_formcalc_context.cpp +++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -5438,8 +5438,8 @@ WideString::FromUTF8(bsAccessorName).AsStringView(), &resolveNodeRS, dwFlags, nullptr); if (bRet && resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) { - accessorValue->Assign( - pScriptContext->GetJSValueFromMap(resolveNodeRS.objects.front().Get())); + accessorValue->Assign(pScriptContext->GetOrCreateJSBindingFromMap( + resolveNodeRS.objects.front().Get())); return true; } return false; @@ -5517,7 +5517,7 @@ for (auto& pObject : resolveNodeRS.objects) { resultValues->push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate)); resultValues->back()->Assign( - pScriptContext->GetJSValueFromMap(pObject.Get())); + pScriptContext->GetOrCreateJSBindingFromMap(pObject.Get())); } return; } @@ -5713,7 +5713,7 @@ : m_pIsolate(pScriptIsolate), m_pValue(pdfium::MakeUnique<CFXJSE_Value>(pScriptIsolate)), m_pDocument(pDoc) { - m_pValue->SetObject( + m_pValue->SetHostObject( this, CFXJSE_Class::Create(pScriptContext, &kFormCalcFM2JSDescriptor, false)); }
diff --git a/fxjs/xfa/cfxjse_value.cpp b/fxjs/xfa/cfxjse_value.cpp index 194e77d..eff4477 100644 --- a/fxjs/xfa/cfxjse_value.cpp +++ b/fxjs/xfa/cfxjse_value.cpp
@@ -82,8 +82,8 @@ return FXJSE_RetrieveObjectBinding(pValue.As<v8::Object>()); } -void CFXJSE_Value::SetObject(CFXJSE_HostObject* lpObject, - CFXJSE_Class* pClass) { +void CFXJSE_Value::SetHostObject(CFXJSE_HostObject* lpObject, + CFXJSE_Class* pClass) { CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); v8::Local<v8::FunctionTemplate> hClass = v8::Local<v8::FunctionTemplate>::New(GetIsolate(), pClass->m_hTemplate); @@ -95,6 +95,13 @@ m_hValue.Reset(GetIsolate(), hObject); } +void CFXJSE_Value::ClearHostObject() { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); + FXJSE_ClearObjectBinding(m_hValue.Get(GetIsolate()).As<v8::Object>()); + v8::Local<v8::Value> hValue = v8::Null(GetIsolate()); + m_hValue.Reset(GetIsolate(), hValue); +} + void CFXJSE_Value::SetArray( const std::vector<std::unique_ptr<CFXJSE_Value>>& values) { CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
diff --git a/fxjs/xfa/cfxjse_value.h b/fxjs/xfa/cfxjse_value.h index 5a81a80..aea43fd 100644 --- a/fxjs/xfa/cfxjse_value.h +++ b/fxjs/xfa/cfxjse_value.h
@@ -52,7 +52,9 @@ void SetString(ByteStringView szString); void SetFloat(float fFloat); - void SetObject(CFXJSE_HostObject* lpObject, CFXJSE_Class* pClass); + void SetHostObject(CFXJSE_HostObject* lpObject, CFXJSE_Class* pClass); + void ClearHostObject(); + void SetArray(const std::vector<std::unique_ptr<CFXJSE_Value>>& values); void SetDate(double dDouble);
diff --git a/fxjs/xfa/cjx_exclgroup.cpp b/fxjs/xfa/cjx_exclgroup.cpp index f24b7e6..ae20485 100644 --- a/fxjs/xfa/cjx_exclgroup.cpp +++ b/fxjs/xfa/cjx_exclgroup.cpp
@@ -107,9 +107,8 @@ return CJS_Result::Success(runtime->NewNull()); CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetJSValueFromMap(pReturnNode); - if (!value) - return CJS_Result::Success(runtime->NewNull()); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap( + pReturnNode); return CJS_Result::Success( value->DirectGetValue().Get(runtime->GetIsolate()));
diff --git a/fxjs/xfa/cjx_form.cpp b/fxjs/xfa/cjx_form.cpp index 41f7e45..32c884b 100644 --- a/fxjs/xfa/cjx_form.cpp +++ b/fxjs/xfa/cjx_form.cpp
@@ -48,9 +48,9 @@ CXFA_ArrayNodeList* pFormNodes = new CXFA_ArrayNodeList(GetDocument()); CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetJSValueFromMap(pFormNodes); - if (!value) - return CJS_Result::Success(runtime->NewNull()); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap( + pFormNodes); + return CJS_Result::Success( value->DirectGetValue().Get(runtime->GetIsolate())); }
diff --git a/fxjs/xfa/cjx_hostpseudomodel.cpp b/fxjs/xfa/cjx_hostpseudomodel.cpp index 678b052..c5d36b3 100644 --- a/fxjs/xfa/cjx_hostpseudomodel.cpp +++ b/fxjs/xfa/cjx_hostpseudomodel.cpp
@@ -474,9 +474,7 @@ return CJS_Result::Success(); CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetJSValueFromMap(pNode); - if (!value) - return CJS_Result::Success(runtime->NewNull()); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode); return CJS_Result::Success( value->DirectGetValue().Get(runtime->GetIsolate()));
diff --git a/fxjs/xfa/cjx_instancemanager.cpp b/fxjs/xfa/cjx_instancemanager.cpp index 6d6de91..f3881e4 100644 --- a/fxjs/xfa/cjx_instancemanager.cpp +++ b/fxjs/xfa/cjx_instancemanager.cpp
@@ -250,9 +250,8 @@ } CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetJSValueFromMap(pNewInstance); - if (!value) - return CJS_Result::Success(runtime->NewNull()); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap( + pNewInstance); return CJS_Result::Success( value->DirectGetValue().Get(runtime->GetIsolate())); @@ -296,9 +295,8 @@ } CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetJSValueFromMap(pNewInstance); - if (!value) - return CJS_Result::Success(runtime->NewNull()); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap( + pNewInstance); return CJS_Result::Success( value->DirectGetValue().Get(runtime->GetIsolate()));
diff --git a/fxjs/xfa/cjx_model.cpp b/fxjs/xfa/cjx_model.cpp index 66ae1ea..4fa0a2e 100644 --- a/fxjs/xfa/cjx_model.cpp +++ b/fxjs/xfa/cjx_model.cpp
@@ -67,9 +67,7 @@ } CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetJSValueFromMap(pNewNode); - if (!value) - return CJS_Result::Success(runtime->NewNull()); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNewNode); return CJS_Result::Success( value->DirectGetValue().Get(runtime->GetIsolate()));
diff --git a/fxjs/xfa/cjx_node.cpp b/fxjs/xfa/cjx_node.cpp index 59c364a..bf10c0f 100644 --- a/fxjs/xfa/cjx_node.cpp +++ b/fxjs/xfa/cjx_node.cpp
@@ -183,9 +183,8 @@ CXFA_Node* pCloneNode = GetXFANode()->Clone(runtime->ToBoolean(params[0])); CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetJSValueFromMap(pCloneNode); - if (!value) - return CJS_Result::Success(runtime->NewNull()); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap( + pCloneNode); return CJS_Result::Success( value->DirectGetValue().Get(runtime->GetIsolate())); @@ -219,9 +218,7 @@ return CJS_Result::Success(runtime->NewNull()); CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetJSValueFromMap(pNode); - if (!value) - return CJS_Result::Success(runtime->NewNull()); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode); return CJS_Result::Success( value->DirectGetValue().Get(runtime->GetIsolate())); @@ -470,7 +467,7 @@ ThrowInvalidPropertyException(); return; } - pValue->Assign(GetDocument()->GetScriptContext()->GetJSValueFromMap( + pValue->Assign(GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap( GetXFANode()->GetModelNode())); } @@ -509,8 +506,9 @@ std::vector<CXFA_Node*> properties = GetXFANode()->GetNodeList( XFA_NODEFILTER_OneOfProperty, XFA_Element::Unknown); if (!properties.empty()) { - pValue->Assign(GetDocument()->GetScriptContext()->GetJSValueFromMap( - properties.front())); + pValue->Assign( + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap( + properties.front())); } }
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp index 7a5e082..63eb003 100644 --- a/fxjs/xfa/cjx_object.cpp +++ b/fxjs/xfa/cjx_object.cpp
@@ -1507,8 +1507,8 @@ return; } - pValue->Assign( - GetDocument()->GetScriptContext()->GetJSValueFromMap(pDataNode)); + pValue->Assign(GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap( + pDataNode)); } void CJX_Object::ScriptSomMandatory(CFXJSE_Value* pValue,
diff --git a/fxjs/xfa/cjx_subform.cpp b/fxjs/xfa/cjx_subform.cpp index 17739a1..18e1508 100644 --- a/fxjs/xfa/cjx_subform.cpp +++ b/fxjs/xfa/cjx_subform.cpp
@@ -125,6 +125,6 @@ return; } - pValue->Assign( - GetDocument()->GetScriptContext()->GetJSValueFromMap(pInstanceMgr)); + pValue->Assign(GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap( + pInstanceMgr)); }
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp index c036ab9..cc13b7a 100644 --- a/fxjs/xfa/cjx_tree.cpp +++ b/fxjs/xfa/cjx_tree.cpp
@@ -58,9 +58,7 @@ if (resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) { CXFA_Object* pObject = resolveNodeRS.objects.front().Get(); CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetJSValueFromMap(pObject); - if (!value) - return CJS_Result::Success(runtime->NewNull()); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pObject); return CJS_Result::Success( value->DirectGetValue().Get(runtime->GetIsolate())); @@ -139,7 +137,7 @@ CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext(); CXFA_AttachNodeList* pNodeList = new CXFA_AttachNodeList(GetDocument(), ToNode(GetXFAObject())); - pValue->SetObject(pNodeList, pScriptContext->GetJseNormalClass()); + pValue->SetHostObject(pNodeList, pScriptContext->GetJseNormalClass()); } void CJX_Tree::parent(CFXJSE_Value* pValue, @@ -156,7 +154,8 @@ return; } - pValue->Assign(GetDocument()->GetScriptContext()->GetJSValueFromMap(pParent)); + pValue->Assign( + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pParent)); } void CJX_Tree::index(CFXJSE_Value* pValue, @@ -230,5 +229,5 @@ } } } - pValue->SetObject(pNodeList, pScriptContext->GetJseNormalClass()); + pValue->SetHostObject(pNodeList, pScriptContext->GetJseNormalClass()); }
diff --git a/fxjs/xfa/cjx_treelist.cpp b/fxjs/xfa/cjx_treelist.cpp index 04a27e7..51bbb0a 100644 --- a/fxjs/xfa/cjx_treelist.cpp +++ b/fxjs/xfa/cjx_treelist.cpp
@@ -44,9 +44,7 @@ return CJS_Result::Success(); CFXJSE_Value* value = - GetDocument()->GetScriptContext()->GetJSValueFromMap(pNode); - if (!value) - return CJS_Result::Success(runtime->NewNull()); + GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode); return CJS_Result::Success( value->DirectGetValue().Get(runtime->GetIsolate()));
diff --git a/fxjs/xfa/cjx_xfa.cpp b/fxjs/xfa/cjx_xfa.cpp index 2d943bd..08c6a80 100644 --- a/fxjs/xfa/cjx_xfa.cpp +++ b/fxjs/xfa/cjx_xfa.cpp
@@ -31,5 +31,5 @@ pValue->SetNull(); return; } - pValue->Assign(pScriptContext->GetJSValueFromMap(pThis)); + pValue->Assign(pScriptContext->GetOrCreateJSBindingFromMap(pThis)); }
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp index 9200ec2..a30cb54 100644 --- a/xfa/fxfa/parser/cxfa_document.cpp +++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -1437,8 +1437,6 @@ return m_pScriptContext.get(); } -// We have to call |InitScriptContext| before any calls to |GetScriptContext| -// or the context won't have an isolate set into it. CFXJSE_Engine* CXFA_Document::GetScriptContext() const { ASSERT(m_pScriptContext); return m_pScriptContext.get();
diff --git a/xfa/fxfa/parser/cxfa_document.h b/xfa/fxfa/parser/cxfa_document.h index 4a57a177..f8fec25 100644 --- a/xfa/fxfa/parser/cxfa_document.h +++ b/xfa/fxfa/parser/cxfa_document.h
@@ -59,7 +59,13 @@ explicit CXFA_Document(CXFA_FFNotify* notify); ~CXFA_Document() override; + bool HasScriptContext() const { return !!m_pScriptContext; } CFXJSE_Engine* InitScriptContext(CJS_Runtime* fxjs_runtime); + + // Only safe to call in situations where the context is known to exist, + // and always returns non-NULL in those situations. In other words, we have + // to call InitScriptContext() first to avoid a situation where the context + // won't have an isolate set into it. CFXJSE_Engine* GetScriptContext() const; CXFA_FFNotify* GetNotify() const { return notify_.Get(); }
diff --git a/xfa/fxfa/parser/cxfa_nodeowner.cpp b/xfa/fxfa/parser/cxfa_nodeowner.cpp index 13c969c..6ee9fd8 100644 --- a/xfa/fxfa/parser/cxfa_nodeowner.cpp +++ b/xfa/fxfa/parser/cxfa_nodeowner.cpp
@@ -13,7 +13,9 @@ CXFA_NodeOwner::CXFA_NodeOwner() = default; -CXFA_NodeOwner::~CXFA_NodeOwner() = default; +CXFA_NodeOwner::~CXFA_NodeOwner() { + is_being_destroyed_ = true; +} CXFA_Node* CXFA_NodeOwner::AddOwnedNode(std::unique_ptr<CXFA_Node> node) { if (!node)
diff --git a/xfa/fxfa/parser/cxfa_nodeowner.h b/xfa/fxfa/parser/cxfa_nodeowner.h index 2aaabe4..e7247cd 100644 --- a/xfa/fxfa/parser/cxfa_nodeowner.h +++ b/xfa/fxfa/parser/cxfa_nodeowner.h
@@ -18,10 +18,12 @@ CXFA_Node* AddOwnedNode(std::unique_ptr<CXFA_Node> node); void FreeOwnedNode(CXFA_Node* node); + bool IsBeingDestroyed() const { return is_being_destroyed_; } protected: CXFA_NodeOwner(); + bool is_being_destroyed_ = false; std::set<std::unique_ptr<CXFA_Node>> nodes_; };
diff --git a/xfa/fxfa/parser/cxfa_object.cpp b/xfa/fxfa/parser/cxfa_object.cpp index a541991..6d730bf 100644 --- a/xfa/fxfa/parser/cxfa_object.cpp +++ b/xfa/fxfa/parser/cxfa_object.cpp
@@ -30,7 +30,10 @@ m_elementNameHash(FX_HashCode_GetAsIfW(m_elementName, false)), m_pJSObject(std::move(jsObject)) {} -CXFA_Object::~CXFA_Object() = default; +CXFA_Object::~CXFA_Object() { + if (!GetDocument()->IsBeingDestroyed() && GetDocument()->HasScriptContext()) + GetDocument()->GetScriptContext()->RemoveJSBindingFromMap(this); +} CXFA_Object* CXFA_Object::AsCXFAObject() { return this;