diff options
Diffstat (limited to 'xfa/fxfa/parser/cxfa_node.cpp')
-rw-r--r-- | xfa/fxfa/parser/cxfa_node.cpp | 103 |
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}; +} |