Move CFXJSE_Engine pointer directly into CFXJSE_ResolveProcessor itself.
Currently, this is being passed anew in each call via the
CFXJSE_ResolveProcessor::NodeData.
These are 1:1, and never change, so no need to pass it in via
NodeData on each call. In turn, make one anonymous function
into a method so it can access the engine member.
Next, get CFXJSE_Engine out of the business of creating resolve
processors, so callers can, in theory, pass in a fake one or
something.
Change-Id: I35feab1a69cee89ed9268375c2caef3fa0d9774a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/94295
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index 7a4e436..c33c658 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -119,8 +119,10 @@
return pJSObject ? pJSObject->GetXFAObject() : nullptr;
}
-CFXJSE_Engine::CFXJSE_Engine(CXFA_Document* pDocument,
- CJS_Runtime* fxjs_runtime)
+CFXJSE_Engine::CFXJSE_Engine(
+ CXFA_Document* pDocument,
+ CJS_Runtime* fxjs_runtime,
+ std::unique_ptr<CFXJSE_ResolveProcessor> pProcessor)
: CFX_V8(fxjs_runtime->GetIsolate()),
m_pSubordinateRuntime(fxjs_runtime),
m_pDocument(pDocument),
@@ -128,7 +130,8 @@
&kGlobalClassDescriptor,
pDocument->GetRoot()->JSObject(),
nullptr)),
- m_ResolveProcessor(std::make_unique<CFXJSE_ResolveProcessor>()) {
+ m_ResolveProcessor(std::move(pProcessor)) {
+ m_ResolveProcessor->SetEngine(this);
RemoveBuiltInObjs(m_JsContext.get());
m_JsContext->EnableCompatibleMode();
@@ -702,7 +705,7 @@
pNodeHelper->m_pCreateParent = nullptr;
pNodeHelper->m_iCurAllStart = -1;
- CFXJSE_ResolveProcessor::NodeData rndFind(this);
+ CFXJSE_ResolveProcessor::NodeData rndFind;
int32_t nStart = 0;
int32_t nLevel = 0;
@@ -755,7 +758,7 @@
if (((dwStyles & XFA_ResolveFlag::kBind) ||
(dwStyles & XFA_ResolveFlag::kCreateNode)) &&
nNodes > 1) {
- CFXJSE_ResolveProcessor::NodeData rndBind(nullptr);
+ CFXJSE_ResolveProcessor::NodeData rndBind;
m_ResolveProcessor->GetFilter(wsExpression, nStart, rndBind);
i = m_ResolveProcessor->IndexForDataBind(rndBind.m_wsCondition, nNodes);
bDataBind = true;
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h
index ce8108e..8fbc599 100644
--- a/fxjs/xfa/cfxjse_engine.h
+++ b/fxjs/xfa/cfxjse_engine.h
@@ -106,7 +106,9 @@
ByteStringView szPropName,
bool bQueryIn);
- CFXJSE_Engine(CXFA_Document* pDocument, CJS_Runtime* fxjs_runtime);
+ CFXJSE_Engine(CXFA_Document* pDocument,
+ CJS_Runtime* fxjs_runtime,
+ std::unique_ptr<CFXJSE_ResolveProcessor> pProcessor);
~CFXJSE_Engine() override;
void SetEventParam(CXFA_EventParam* param) { m_eventParam = param; }
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.cpp b/fxjs/xfa/cfxjse_resolveprocessor.cpp
index 7f0017e..a945b97 100644
--- a/fxjs/xfa/cfxjse_resolveprocessor.cpp
+++ b/fxjs/xfa/cfxjse_resolveprocessor.cpp
@@ -25,40 +25,16 @@
#include "xfa/fxfa/parser/cxfa_occur.h"
#include "xfa/fxfa/parser/xfa_utils.h"
-namespace {
-
-void DoPredicateFilter(v8::Isolate* pIsolate,
- WideString wsCondition,
- size_t iFoundCount,
- CFXJSE_ResolveProcessor::NodeData* pRnd) {
- DCHECK_EQ(iFoundCount, pRnd->m_Result.objects.size());
- WideString wsExpression;
- CXFA_Script::Type eLangType = CXFA_Script::Type::Unknown;
- if (wsCondition.First(2).EqualsASCII(".[") && wsCondition.Back() == L']')
- eLangType = CXFA_Script::Type::Formcalc;
- else if (wsCondition.First(2).EqualsASCII(".(") && wsCondition.Back() == L')')
- eLangType = CXFA_Script::Type::Javascript;
- else
- return;
-
- wsExpression = wsCondition.Substr(2, wsCondition.GetLength() - 3);
- for (size_t i = iFoundCount; i > 0; --i) {
- auto pRetValue = std::make_unique<CFXJSE_Value>();
- bool bRet = pRnd->m_pSC->RunScript(eLangType, wsExpression.AsStringView(),
- pRetValue.get(),
- pRnd->m_Result.objects[i - 1].Get());
- if (!bRet || !pRetValue->ToBoolean(pIsolate))
- pRnd->m_Result.objects.erase(pRnd->m_Result.objects.begin() + i - 1);
- }
-}
-
-} // namespace
-
CFXJSE_ResolveProcessor::CFXJSE_ResolveProcessor()
: m_pNodeHelper(std::make_unique<CFXJSE_NodeHelper>()) {}
CFXJSE_ResolveProcessor::~CFXJSE_ResolveProcessor() = default;
+void CFXJSE_ResolveProcessor::SetEngine(CFXJSE_Engine* pEngine) {
+ DCHECK(!m_pEngine);
+ m_pEngine = pEngine;
+}
+
bool CFXJSE_ResolveProcessor::Resolve(v8::Isolate* pIsolate, NodeData& rnd) {
if (!rnd.m_CurObject)
return false;
@@ -92,12 +68,12 @@
}
}
if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) {
- rnd.m_Result.objects.emplace_back(rnd.m_pSC->GetThisObject());
+ rnd.m_Result.objects.emplace_back(m_pEngine->GetThisObject());
return true;
}
if (rnd.m_CurObject->GetElementType() == XFA_Element::Xfa) {
CXFA_Object* pObjNode =
- rnd.m_pSC->GetDocument()->GetXFAObject(rnd.m_uHashName);
+ m_pEngine->GetDocument()->GetXFAObject(rnd.m_uHashName);
if (pObjNode) {
rnd.m_Result.objects.emplace_back(pObjNode);
} else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
@@ -113,7 +89,7 @@
return !rnd.m_Result.objects.empty();
}
if (!ResolveNormal(pIsolate, rnd) && rnd.m_uHashName == XFA_HASHCODE_Xfa)
- rnd.m_Result.objects.emplace_back(rnd.m_pSC->GetDocument()->GetRoot());
+ rnd.m_Result.objects.emplace_back(m_pEngine->GetDocument()->GetRoot());
return !rnd.m_Result.objects.empty();
}
@@ -163,12 +139,13 @@
if (rnd.m_nLevel > 0)
return false;
+ CXFA_Document* pDocument = m_pEngine->GetDocument();
XFA_HashCode dwNameHash = static_cast<XFA_HashCode>(
FX_HashCode_GetW(wsName.AsStringView().Last(nNameLen - 1)));
if (dwNameHash == XFA_HASHCODE_Xfa) {
- rnd.m_Result.objects.emplace_back(rnd.m_pSC->GetDocument()->GetRoot());
+ rnd.m_Result.objects.emplace_back(pDocument->GetRoot());
} else {
- CXFA_Object* pObjNode = rnd.m_pSC->GetDocument()->GetXFAObject(dwNameHash);
+ CXFA_Object* pObjNode = pDocument->GetXFAObject(dwNameHash);
if (pObjNode)
rnd.m_Result.objects.emplace_back(pObjNode);
}
@@ -183,11 +160,11 @@
return false;
CXFA_Node* datasets =
- ToNode(rnd.m_pSC->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
+ ToNode(m_pEngine->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
if (!datasets)
return false;
- NodeData rndFind(rnd.m_pSC.Get());
+ NodeData rndFind;
rndFind.m_CurObject = datasets;
rndFind.m_wsName = rnd.m_wsName.Last(rnd.m_wsName.GetLength() - 1);
rndFind.m_uHashName = static_cast<XFA_HashCode>(
@@ -211,7 +188,7 @@
if (ResolveForAttributeRs(curNode, &rnd.m_Result, wsName.AsStringView()))
return true;
- NodeData rndFind(rnd.m_pSC.Get());
+ NodeData rndFind;
rndFind.m_nLevel = rnd.m_nLevel + 1;
rndFind.m_dwStyles = rnd.m_dwStyles;
rndFind.m_dwStyles |= XFA_ResolveFlag::kTagName;
@@ -263,7 +240,7 @@
XFA_HashCode uNameHash = rnd.m_uHashName;
WideString& wsCondition = rnd.m_wsCondition;
- NodeData rndFind(rnd.m_pSC.Get());
+ NodeData rndFind;
rndFind.m_wsName = rnd.m_wsName;
rndFind.m_wsCondition = rnd.m_wsCondition;
rndFind.m_nLevel = rnd.m_nLevel + 1;
@@ -504,9 +481,9 @@
if (dwStyles & XFA_ResolveFlag::kALL)
dwSubStyles |= XFA_ResolveFlag::kALL;
+ m_pEngine->AddObjectToUpArray(parentNode);
rndFind.m_dwStyles = dwSubStyles;
rndFind.m_CurObject = parentNode;
- rnd.m_pSC->AddObjectToUpArray(parentNode);
ResolveNormal(pIsolate, rndFind);
rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
rndFind.m_Result.objects.begin(),
@@ -667,7 +644,7 @@
WideString wsCondition,
NodeData* pRnd) {
size_t iCurIndex = 0;
- CXFA_Node* pNode = pRnd->m_pSC->LastObjectFromUpArray();
+ CXFA_Node* pNode = m_pEngine->LastObjectFromUpArray();
if (pNode) {
const bool bIsProperty = pNode->IsProperty();
const bool bIsClassIndex =
@@ -736,6 +713,30 @@
return iCount - 1;
}
-CFXJSE_ResolveProcessor::NodeData::NodeData(CFXJSE_Engine* pSC) : m_pSC(pSC) {}
+void CFXJSE_ResolveProcessor::DoPredicateFilter(v8::Isolate* pIsolate,
+ WideString wsCondition,
+ size_t iFoundCount,
+ NodeData* pRnd) {
+ DCHECK_EQ(iFoundCount, pRnd->m_Result.objects.size());
+ CXFA_Script::Type eLangType = CXFA_Script::Type::Unknown;
+ if (wsCondition.First(2).EqualsASCII(".[") && wsCondition.Back() == L']')
+ eLangType = CXFA_Script::Type::Formcalc;
+ else if (wsCondition.First(2).EqualsASCII(".(") && wsCondition.Back() == L')')
+ eLangType = CXFA_Script::Type::Javascript;
+ else
+ return;
+
+ WideString wsExpression = wsCondition.Substr(2, wsCondition.GetLength() - 3);
+ for (size_t i = iFoundCount; i > 0; --i) {
+ auto pRetValue = std::make_unique<CFXJSE_Value>();
+ bool bRet = m_pEngine->RunScript(eLangType, wsExpression.AsStringView(),
+ pRetValue.get(),
+ pRnd->m_Result.objects[i - 1].Get());
+ if (!bRet || !pRetValue->ToBoolean(pIsolate))
+ pRnd->m_Result.objects.erase(pRnd->m_Result.objects.begin() + i - 1);
+ }
+}
+
+CFXJSE_ResolveProcessor::NodeData::NodeData() = default;
CFXJSE_ResolveProcessor::NodeData::~NodeData() = default;
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.h b/fxjs/xfa/cfxjse_resolveprocessor.h
index c0ee9de..d8b076b 100644
--- a/fxjs/xfa/cfxjse_resolveprocessor.h
+++ b/fxjs/xfa/cfxjse_resolveprocessor.h
@@ -24,10 +24,9 @@
CPPGC_STACK_ALLOCATED(); // Allows Raw/Unowned pointers.
public:
- explicit NodeData(CFXJSE_Engine* pSC);
+ NodeData();
~NodeData();
- UnownedPtr<CFXJSE_Engine> const m_pSC;
UnownedPtr<CXFA_Object> m_CurObject; // Ok, stack-only.
WideString m_wsName;
WideString m_wsCondition;
@@ -40,6 +39,7 @@
CFXJSE_ResolveProcessor();
~CFXJSE_ResolveProcessor();
+ void SetEngine(CFXJSE_Engine* pEngine);
bool Resolve(v8::Isolate* pIsolate, NodeData& rnd);
int32_t GetFilter(WideStringView wsExpression, int32_t nStart, NodeData& rnd);
int32_t IndexForDataBind(const WideString& wsNextCondition, int32_t iCount);
@@ -66,8 +66,13 @@
void FilterCondition(v8::Isolate* pIsolate,
WideString wsCondition,
NodeData* pRnd);
+ void DoPredicateFilter(v8::Isolate* pIsolate,
+ WideString wsCondition,
+ size_t iFoundCount,
+ NodeData* pRnd);
int32_t m_iCurStart = 0;
+ UnownedPtr<CFXJSE_Engine> m_pEngine;
std::unique_ptr<CFXJSE_NodeHelper> const m_pNodeHelper;
};
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index 5f8fe20..f4485fe 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -15,6 +15,7 @@
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "fxjs/gc/container_trace.h"
#include "fxjs/xfa/cfxjse_engine.h"
+#include "fxjs/xfa/cfxjse_resolveprocessor.h"
#include "fxjs/xfa/cjx_object.h"
#include "third_party/base/check.h"
#include "third_party/base/check_op.h"
@@ -1455,7 +1456,8 @@
CFXJSE_Engine* CXFA_Document::InitScriptContext(CJS_Runtime* fxjs_runtime) {
DCHECK(!m_pScriptContext);
- m_pScriptContext = std::make_unique<CFXJSE_Engine>(this, fxjs_runtime);
+ m_pScriptContext = std::make_unique<CFXJSE_Engine>(
+ this, fxjs_runtime, std::make_unique<CFXJSE_ResolveProcessor>());
return m_pScriptContext.get();
}