summaryrefslogtreecommitdiff
path: root/xfa/fxfa/parser/cxfa_node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fxfa/parser/cxfa_node.cpp')
-rw-r--r--xfa/fxfa/parser/cxfa_node.cpp103
1 files changed, 97 insertions, 6 deletions
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 50c4c4195e..8c8f0c69f2 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -12,6 +12,7 @@
#include <utility>
#include <vector>
+#include "core/fxcrt/autorestorer.h"
#include "core/fxcrt/cfx_decimal.h"
#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_codepage.h"
@@ -56,6 +57,8 @@
namespace {
+constexpr uint8_t kMaxExecuteRecursion = 2;
+
std::vector<CXFA_Node*> NodesSortedByDocumentIdx(
const std::set<CXFA_Node*>& rgNodeSet) {
if (rgNodeSet.empty())
@@ -1690,8 +1693,7 @@ int32_t CXFA_Node::ProcessEvent(CXFA_FFDocView* docView,
case XFA_Element::Execute:
break;
case XFA_Element::Script:
- return GetWidgetAcc()->ExecuteScript(docView, event->GetScript(),
- pEventParam);
+ return ExecuteScript(docView, event->GetScript(), pEventParam);
case XFA_Element::SignData:
break;
case XFA_Element::Submit:
@@ -1715,8 +1717,7 @@ int32_t CXFA_Node::ProcessCalculate(CXFA_FFDocView* docView) {
CXFA_EventParam EventParam;
EventParam.m_eType = XFA_EVENT_Calculate;
- int32_t iRet =
- GetWidgetAcc()->ExecuteScript(docView, calc->GetScript(), &EventParam);
+ int32_t iRet = ExecuteScript(docView, calc->GetScript(), &EventParam);
if (iRet != XFA_EVENTERROR_Success)
return iRet;
@@ -1904,8 +1905,7 @@ int32_t CXFA_Node::ProcessValidate(CXFA_FFDocView* docView, int32_t iFlags) {
CXFA_EventParam eParam;
eParam.m_eType = XFA_EVENT_Validate;
eParam.m_pTarget = GetWidgetAcc();
- std::tie(iRet, bRet) =
- GetWidgetAcc()->ExecuteBoolScript(docView, script, &eParam);
+ std::tie(iRet, bRet) = ExecuteBoolScript(docView, script, &eParam);
}
XFA_VERSION version = docView->GetDoc()->GetXFADoc()->GetCurVersionMode();
@@ -1963,3 +1963,94 @@ WideString CXFA_Node::GetValidateMessage(bool bError, bool bVersionFlag) {
L"validations for %ls, click Ignore.",
wsCaptionName.c_str(), wsCaptionName.c_str());
}
+
+int32_t CXFA_Node::ExecuteScript(CXFA_FFDocView* docView,
+ CXFA_Script* script,
+ CXFA_EventParam* pEventParam) {
+ bool bRet;
+ int32_t iRet;
+ std::tie(iRet, bRet) = ExecuteBoolScript(docView, script, pEventParam);
+ return iRet;
+}
+
+std::pair<int32_t, bool> CXFA_Node::ExecuteBoolScript(
+ CXFA_FFDocView* docView,
+ CXFA_Script* script,
+ CXFA_EventParam* pEventParam) {
+ if (m_ExecuteRecursionDepth > kMaxExecuteRecursion)
+ return {XFA_EVENTERROR_Success, false};
+
+ ASSERT(pEventParam);
+ if (!script)
+ return {XFA_EVENTERROR_NotExist, false};
+ if (script->GetRunAt() == XFA_AttributeEnum::Server)
+ return {XFA_EVENTERROR_Disabled, false};
+
+ WideString wsExpression = script->GetExpression();
+ if (wsExpression.IsEmpty())
+ return {XFA_EVENTERROR_NotExist, false};
+
+ CXFA_Script::Type eScriptType = script->GetContentType();
+ if (eScriptType == CXFA_Script::Type::Unknown)
+ return {XFA_EVENTERROR_Success, false};
+
+ CXFA_FFDoc* pDoc = docView->GetDoc();
+ CFXJSE_Engine* pContext = pDoc->GetXFADoc()->GetScriptContext();
+ pContext->SetEventParam(*pEventParam);
+ pContext->SetRunAtType(script->GetRunAt());
+
+ std::vector<CXFA_Node*> refNodes;
+ if (pEventParam->m_eType == XFA_EVENT_InitCalculate ||
+ pEventParam->m_eType == XFA_EVENT_Calculate) {
+ pContext->SetNodesOfRunScript(&refNodes);
+ }
+
+ auto pTmpRetValue = pdfium::MakeUnique<CFXJSE_Value>(pContext->GetIsolate());
+ bool bRet = false;
+ {
+ AutoRestorer<uint8_t> restorer(&m_ExecuteRecursionDepth);
+ ++m_ExecuteRecursionDepth;
+ bRet = pContext->RunScript(eScriptType, wsExpression.AsStringView(),
+ pTmpRetValue.get(), this);
+ }
+
+ int32_t iRet = XFA_EVENTERROR_Error;
+ if (bRet) {
+ iRet = XFA_EVENTERROR_Success;
+ if (pEventParam->m_eType == XFA_EVENT_Calculate ||
+ pEventParam->m_eType == XFA_EVENT_InitCalculate) {
+ if (!pTmpRetValue->IsUndefined()) {
+ if (!pTmpRetValue->IsNull())
+ pEventParam->m_wsResult = pTmpRetValue->ToWideString();
+
+ iRet = XFA_EVENTERROR_Success;
+ } else {
+ iRet = XFA_EVENTERROR_Error;
+ }
+ if (pEventParam->m_eType == XFA_EVENT_InitCalculate) {
+ if ((iRet == XFA_EVENTERROR_Success) &&
+ (GetRawValue() != pEventParam->m_wsResult)) {
+ GetWidgetAcc()->SetValue(XFA_VALUEPICTURE_Raw,
+ pEventParam->m_wsResult);
+ docView->AddValidateWidget(GetWidgetAcc());
+ }
+ }
+ for (CXFA_Node* pRefNode : refNodes) {
+ if (pRefNode == this)
+ continue;
+
+ CXFA_CalcData* pGlobalData = pRefNode->JSObject()->GetCalcData();
+ if (!pGlobalData) {
+ pRefNode->JSObject()->SetCalcData(
+ pdfium::MakeUnique<CXFA_CalcData>());
+ pGlobalData = pRefNode->JSObject()->GetCalcData();
+ }
+ if (!pdfium::ContainsValue(pGlobalData->m_Globals, this))
+ pGlobalData->m_Globals.push_back(this);
+ }
+ }
+ }
+ pContext->SetNodesOfRunScript(nullptr);
+
+ return {iRet, pTmpRetValue->IsBoolean() ? pTmpRetValue->ToBoolean() : false};
+}