From 95bb9748c9292d282e2425d4500f15f5c48c2b34 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Tue, 9 Jan 2018 10:02:55 -0500 Subject: More Execute* methods to CXFA_Node This Cl moves the two Execute* methods from CXFA_WidgetAcc to CXFA_Node. Change-Id: I4e1d6cd2159028800b855558273ca80aad365570 Reviewed-on: https://pdfium-review.googlesource.com/22550 Reviewed-by: Ryan Harrison Commit-Queue: dsinclair --- xfa/fxfa/cxfa_ffdocview.cpp | 2 +- xfa/fxfa/cxfa_ffnotify.cpp | 9 +--- xfa/fxfa/cxfa_ffwidgethandler.cpp | 6 +-- xfa/fxfa/cxfa_widgetacc.cpp | 90 +-------------------------------- xfa/fxfa/cxfa_widgetacc.h | 8 --- xfa/fxfa/parser/cxfa_node.cpp | 103 +++++++++++++++++++++++++++++++++++--- xfa/fxfa/parser/cxfa_node.h | 9 ++++ 7 files changed, 113 insertions(+), 114 deletions(-) diff --git a/xfa/fxfa/cxfa_ffdocview.cpp b/xfa/fxfa/cxfa_ffdocview.cpp index 2165759c83..80d40d15f6 100644 --- a/xfa/fxfa/cxfa_ffdocview.cpp +++ b/xfa/fxfa/cxfa_ffdocview.cpp @@ -431,7 +431,7 @@ static int32_t XFA_ProcessEvent(CXFA_FFDocView* pDocView, if (node->IsUserInteractive()) return XFA_EVENTERROR_Disabled; - return pWidgetAcc->ExecuteScript(pDocView, calc->GetScript(), pParam); + return node->ExecuteScript(pDocView, calc->GetScript(), pParam); } default: break; diff --git a/xfa/fxfa/cxfa_ffnotify.cpp b/xfa/fxfa/cxfa_ffnotify.cpp index 5dc06f90b8..7fd3699f04 100644 --- a/xfa/fxfa/cxfa_ffnotify.cpp +++ b/xfa/fxfa/cxfa_ffnotify.cpp @@ -210,22 +210,17 @@ bool CXFA_FFNotify::FindSplitPos(CXFA_Node* pItem, pAcc->FindSplitPos(m_pDoc->GetDocView(), iBlockIndex, fCalcHeightPos); } -bool CXFA_FFNotify::RunScript(CXFA_Script* pScript, CXFA_Node* pFormItem) { +bool CXFA_FFNotify::RunScript(CXFA_Script* script, CXFA_Node* item) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) return false; - CXFA_WidgetAcc* pWidgetAcc = pFormItem->GetWidgetAcc(); - if (!pWidgetAcc) - return false; - CXFA_EventParam EventParam; EventParam.m_eType = XFA_EVENT_Unknown; int32_t iRet; bool bRet; - std::tie(iRet, bRet) = - pWidgetAcc->ExecuteBoolScript(pDocView, pScript, &EventParam); + std::tie(iRet, bRet) = item->ExecuteBoolScript(pDocView, script, &EventParam); return iRet == XFA_EVENTERROR_Success && bRet; } diff --git a/xfa/fxfa/cxfa_ffwidgethandler.cpp b/xfa/fxfa/cxfa_ffwidgethandler.cpp index c1e00fb668..b70facd3ed 100644 --- a/xfa/fxfa/cxfa_ffwidgethandler.cpp +++ b/xfa/fxfa/cxfa_ffwidgethandler.cpp @@ -229,12 +229,12 @@ int32_t CXFA_FFWidgetHandler::ProcessEvent(CXFA_WidgetAcc* pWidgetAcc, } return XFA_EVENTERROR_Disabled; case XFA_EVENT_InitCalculate: { - CXFA_Calculate* calc = pWidgetAcc->GetNode()->GetCalculate(); + CXFA_Calculate* calc = node->GetCalculate(); if (!calc) return XFA_EVENTERROR_NotExist; - if (pWidgetAcc->GetNode()->IsUserInteractive()) + if (node->IsUserInteractive()) return XFA_EVENTERROR_Disabled; - return pWidgetAcc->ExecuteScript(m_pDocView, calc->GetScript(), pParam); + return node->ExecuteScript(m_pDocView, calc->GetScript(), pParam); } default: break; diff --git a/xfa/fxfa/cxfa_widgetacc.cpp b/xfa/fxfa/cxfa_widgetacc.cpp index bbed5b3245..870dc53ff9 100644 --- a/xfa/fxfa/cxfa_widgetacc.cpp +++ b/xfa/fxfa/cxfa_widgetacc.cpp @@ -357,8 +357,7 @@ std::pair CreateUIChild(CXFA_Node* pNode) { } // namespace CXFA_WidgetAcc::CXFA_WidgetAcc(CXFA_Node* pNode) - : m_nRecursionDepth(0), - m_bIsNull(true), + : m_bIsNull(true), m_bPreNull(true), m_pUiChildNode(nullptr), m_eUIType(XFA_Element::Unknown), @@ -464,93 +463,6 @@ void CXFA_WidgetAcc::SetImageEdit(const WideString& wsContentType, } } -int32_t CXFA_WidgetAcc::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 CXFA_WidgetAcc::ExecuteBoolScript( - CXFA_FFDocView* docView, - CXFA_Script* script, - CXFA_EventParam* pEventParam) { - static const uint32_t MAX_RECURSION_DEPTH = 2; - if (m_nRecursionDepth > MAX_RECURSION_DEPTH) - 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 refNodes; - if (pEventParam->m_eType == XFA_EVENT_InitCalculate || - pEventParam->m_eType == XFA_EVENT_Calculate) { - pContext->SetNodesOfRunScript(&refNodes); - } - - auto pTmpRetValue = pdfium::MakeUnique(pContext->GetIsolate()); - ++m_nRecursionDepth; - bool bRet = pContext->RunScript(eScriptType, wsExpression.AsStringView(), - pTmpRetValue.get(), m_pNode); - --m_nRecursionDepth; - 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) && - (m_pNode->GetRawValue() != pEventParam->m_wsResult)) { - SetValue(XFA_VALUEPICTURE_Raw, pEventParam->m_wsResult); - docView->AddValidateWidget(this); - } - } - for (CXFA_Node* pRefNode : refNodes) { - if (pRefNode->GetWidgetAcc() == this) - continue; - - CXFA_CalcData* pGlobalData = pRefNode->JSObject()->GetCalcData(); - if (!pGlobalData) { - pRefNode->JSObject()->SetCalcData( - pdfium::MakeUnique()); - pGlobalData = pRefNode->JSObject()->GetCalcData(); - } - if (!pdfium::ContainsValue(pGlobalData->m_Globals, GetNode())) - pGlobalData->m_Globals.push_back(GetNode()); - } - } - } - pContext->SetNodesOfRunScript(nullptr); - - return {iRet, pTmpRetValue->IsBoolean() ? pTmpRetValue->ToBoolean() : false}; -} - CXFA_FFWidget* CXFA_WidgetAcc::GetNextWidget(CXFA_FFWidget* pWidget) { return static_cast(pWidget->GetNext()); } diff --git a/xfa/fxfa/cxfa_widgetacc.h b/xfa/fxfa/cxfa_widgetacc.h index 2a0196a88a..6031d9be26 100644 --- a/xfa/fxfa/cxfa_widgetacc.h +++ b/xfa/fxfa/cxfa_widgetacc.h @@ -62,13 +62,6 @@ class CXFA_WidgetAcc { void ResetData(); - int32_t ExecuteScript(CXFA_FFDocView* docView, - CXFA_Script* script, - CXFA_EventParam* pEventParam); - std::pair ExecuteBoolScript(CXFA_FFDocView* docView, - CXFA_Script* script, - CXFA_EventParam* pEventParam); - CXFA_FFWidget* GetNextWidget(CXFA_FFWidget* pWidget); void StartWidgetLayout(CXFA_FFDoc* doc, float& fCalcWidth, @@ -241,7 +234,6 @@ class CXFA_WidgetAcc { void GetItemLabel(const WideStringView& wsValue, WideString& wsLabel); std::unique_ptr m_pLayoutData; - uint32_t m_nRecursionDepth; bool m_bIsNull; bool m_bPreNull; CXFA_Node* m_pUiChildNode; 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 #include +#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 NodesSortedByDocumentIdx( const std::set& 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 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 refNodes; + if (pEventParam->m_eType == XFA_EVENT_InitCalculate || + pEventParam->m_eType == XFA_EVENT_Calculate) { + pContext->SetNodesOfRunScript(&refNodes); + } + + auto pTmpRetValue = pdfium::MakeUnique(pContext->GetIsolate()); + bool bRet = false; + { + AutoRestorer 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()); + 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}; +} diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h index ed948cf155..7bf0654b58 100644 --- a/xfa/fxfa/parser/cxfa_node.h +++ b/xfa/fxfa/parser/cxfa_node.h @@ -31,6 +31,7 @@ class CXFA_Font; class CXFA_Margin; class CXFA_Occur; class CXFA_Para; +class CXFA_Script; class CXFA_Validate; class CXFA_Value; class CXFA_WidgetAcc; @@ -271,6 +272,13 @@ class CXFA_Node : public CXFA_Object { int32_t ProcessCalculate(CXFA_FFDocView* docView); int32_t ProcessValidate(CXFA_FFDocView* docView, int32_t iFlags); + int32_t ExecuteScript(CXFA_FFDocView* docView, + CXFA_Script* script, + CXFA_EventParam* pEventParam); + std::pair ExecuteBoolScript(CXFA_FFDocView* docView, + CXFA_Script* script, + CXFA_EventParam* pEventParam); + protected: CXFA_Node(CXFA_Document* pDoc, XFA_PacketType ePacket, @@ -329,6 +337,7 @@ class CXFA_Node : public CXFA_Object { CXFA_Node* m_pParent; CFX_XMLNode* m_pXMLNode; const XFA_PacketType m_ePacket; + uint8_t m_ExecuteRecursionDepth = 0; uint16_t m_uNodeFlags; uint32_t m_dwNameHash; CXFA_Node* m_pAuxNode; -- cgit v1.2.3