diff options
-rw-r--r-- | BUILD.gn | 2 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp | 2 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmexpression.cpp | 100 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp | 5 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp | 95 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmsimpleexpression_unittest.cpp | 7 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.cpp | 21 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h | 22 |
8 files changed, 245 insertions, 9 deletions
@@ -1717,6 +1717,8 @@ if (pdf_enable_xfa) { "xfa/fxfa/fm2js/cxfa_fmparser.h", "xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp", "xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h", + "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.cpp", + "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h", "xfa/fxfa/fxfa.h", "xfa/fxfa/fxfa_basic.h", "xfa/fxfa/parser/cscript_datawindow.cpp", diff --git a/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp b/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp index 00df0163f7..8c2aeefbbd 100644 --- a/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp +++ b/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp @@ -22,6 +22,7 @@ #include "third_party/base/stl_util.h" #include "xfa/fxfa/cxfa_ffnotify.h" #include "xfa/fxfa/fm2js/cxfa_fmparser.h" +#include "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h" #include "xfa/fxfa/parser/cxfa_document.h" #include "xfa/fxfa/parser/cxfa_localevalue.h" #include "xfa/fxfa/parser/cxfa_node.h" @@ -6081,6 +6082,7 @@ bool CXFA_FM2JSContext::Translate(const WideStringView& wsFormcalc, if (!func || parser.HasError()) return false; + CXFA_FMToJavaScriptDepth::Reset(); if (!func->ToJavaScript(*wsJavascript)) return false; diff --git a/xfa/fxfa/fm2js/cxfa_fmexpression.cpp b/xfa/fxfa/fm2js/cxfa_fmexpression.cpp index a1bbb50271..e8ab35ea67 100644 --- a/xfa/fxfa/fm2js/cxfa_fmexpression.cpp +++ b/xfa/fxfa/fm2js/cxfa_fmexpression.cpp @@ -9,6 +9,7 @@ #include <utility> #include "core/fxcrt/cfx_widetextbuf.h" +#include "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h" namespace { @@ -30,11 +31,13 @@ CXFA_FMExpression::CXFA_FMExpression(uint32_t line, XFA_FM_EXPTYPE type) : m_type(type), m_line(line) {} bool CXFA_FMExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - return true; + CXFA_FMToJavaScriptDepth depthManager; + return depthManager.IsWithinMaxDepth(); } bool CXFA_FMExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { - return true; + CXFA_FMToJavaScriptDepth depthManager; + return depthManager.IsWithinMaxDepth(); } CXFA_FMFunctionDefinition::CXFA_FMFunctionDefinition( @@ -52,6 +55,10 @@ CXFA_FMFunctionDefinition::CXFA_FMFunctionDefinition( CXFA_FMFunctionDefinition::~CXFA_FMFunctionDefinition() {} bool CXFA_FMFunctionDefinition::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + if (m_isGlobal && m_pExpressions.empty()) { javascript << L"// comments only"; return true; @@ -111,7 +118,8 @@ bool CXFA_FMFunctionDefinition::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMFunctionDefinition::ToImpliedReturnJS(CFX_WideTextBuf&) { - return true; + CXFA_FMToJavaScriptDepth depthManager; + return depthManager.IsWithinMaxDepth(); } CXFA_FMVarExpression::CXFA_FMVarExpression( @@ -125,6 +133,10 @@ CXFA_FMVarExpression::CXFA_FMVarExpression( CXFA_FMVarExpression::~CXFA_FMVarExpression() {} bool CXFA_FMVarExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"var "; WideString tempName(m_wsName); if (m_wsName[0] == L'!') { @@ -149,6 +161,10 @@ bool CXFA_FMVarExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMVarExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"var "; WideString tempName(m_wsName); if (m_wsName[0] == L'!') { @@ -185,6 +201,10 @@ CXFA_FMExpExpression::CXFA_FMExpExpression( CXFA_FMExpExpression::~CXFA_FMExpExpression() {} bool CXFA_FMExpExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + bool ret = m_pExpression->ToJavaScript(javascript); if (m_pExpression->GetOperatorToken() != TOKassign) javascript << L";\n"; @@ -192,6 +212,10 @@ bool CXFA_FMExpExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMExpExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + if (m_pExpression->GetOperatorToken() == TOKassign) return m_pExpression->ToImpliedReturnJS(javascript); @@ -227,6 +251,10 @@ CXFA_FMBlockExpression::CXFA_FMBlockExpression( CXFA_FMBlockExpression::~CXFA_FMBlockExpression() {} bool CXFA_FMBlockExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"{\n"; for (const auto& expr : m_ExpressionList) { if (!expr->ToJavaScript(javascript) || CFXA_IsTooBig(javascript)) @@ -237,6 +265,10 @@ bool CXFA_FMBlockExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMBlockExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"{\n"; for (const auto& expr : m_ExpressionList) { bool ret; @@ -259,10 +291,18 @@ CXFA_FMDoExpression::CXFA_FMDoExpression( CXFA_FMDoExpression::~CXFA_FMDoExpression() {} bool CXFA_FMDoExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + return m_pList->ToJavaScript(javascript); } bool CXFA_FMDoExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + return m_pList->ToImpliedReturnJS(javascript); } @@ -279,6 +319,10 @@ CXFA_FMIfExpression::CXFA_FMIfExpression( CXFA_FMIfExpression::~CXFA_FMIfExpression() {} bool CXFA_FMIfExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"if ("; if (m_pExpression) { javascript << XFA_FM_EXPTypeToString(GETFMVALUE); @@ -315,6 +359,10 @@ bool CXFA_FMIfExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMIfExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << RUNTIMEFUNCTIONRETURNVALUE; javascript << L" = 0;\n"; javascript << L"if ("; @@ -354,11 +402,13 @@ bool CXFA_FMIfExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { CXFA_FMLoopExpression::~CXFA_FMLoopExpression() {} bool CXFA_FMLoopExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - return true; + CXFA_FMToJavaScriptDepth depthManager; + return depthManager.IsWithinMaxDepth(); } bool CXFA_FMLoopExpression::ToImpliedReturnJS(CFX_WideTextBuf&) { - return true; + CXFA_FMToJavaScriptDepth depthManager; + return depthManager.IsWithinMaxDepth(); } CXFA_FMWhileExpression::CXFA_FMWhileExpression( @@ -372,6 +422,10 @@ CXFA_FMWhileExpression::CXFA_FMWhileExpression( CXFA_FMWhileExpression::~CXFA_FMWhileExpression() {} bool CXFA_FMWhileExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"while ("; if (!m_pCondition->ToJavaScript(javascript)) return false; @@ -385,6 +439,10 @@ bool CXFA_FMWhileExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMWhileExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << RUNTIMEFUNCTIONRETURNVALUE; javascript << L" = 0;\n"; javascript << L"while ("; @@ -405,6 +463,10 @@ CXFA_FMBreakExpression::CXFA_FMBreakExpression(uint32_t line) CXFA_FMBreakExpression::~CXFA_FMBreakExpression() {} bool CXFA_FMBreakExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << RUNTIMEFUNCTIONRETURNVALUE; javascript << L" = 0;\n"; javascript << L"break;\n"; @@ -412,6 +474,10 @@ bool CXFA_FMBreakExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMBreakExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << RUNTIMEFUNCTIONRETURNVALUE; javascript << L" = 0;\n"; javascript << L"break;\n"; @@ -424,6 +490,10 @@ CXFA_FMContinueExpression::CXFA_FMContinueExpression(uint32_t line) CXFA_FMContinueExpression::~CXFA_FMContinueExpression() {} bool CXFA_FMContinueExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << RUNTIMEFUNCTIONRETURNVALUE; javascript << L" = 0;\n"; javascript << L"continue;\n"; @@ -431,6 +501,10 @@ bool CXFA_FMContinueExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMContinueExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << RUNTIMEFUNCTIONRETURNVALUE; javascript << L" = 0;\n"; javascript << L"continue;\n"; @@ -456,6 +530,10 @@ CXFA_FMForExpression::CXFA_FMForExpression( CXFA_FMForExpression::~CXFA_FMForExpression() {} bool CXFA_FMForExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"{\nvar "; WideString tempVariant; if (m_wsVariant[0] == L'!') { @@ -509,6 +587,10 @@ bool CXFA_FMForExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMForExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << RUNTIMEFUNCTIONRETURNVALUE; javascript << L" = 0;\n"; javascript << L"{\nvar "; @@ -577,6 +659,10 @@ CXFA_FMForeachExpression::CXFA_FMForeachExpression( CXFA_FMForeachExpression::~CXFA_FMForeachExpression() {} bool CXFA_FMForeachExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"{\n"; javascript << L"var "; if (m_wsIdentifier[0] == L'!') { @@ -632,6 +718,10 @@ bool CXFA_FMForeachExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMForeachExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << RUNTIMEFUNCTIONRETURNVALUE; javascript << L" = 0;\n"; javascript << L"{\n"; diff --git a/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp b/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp index 192f935309..8582649fec 100644 --- a/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp +++ b/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp @@ -10,6 +10,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/test_support.h" #include "third_party/base/ptr_util.h" +#include "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h" TEST(CXFA_FMParserTest, Empty) { auto parser = pdfium::MakeUnique<CXFA_FMParser>(L""); @@ -17,6 +18,7 @@ TEST(CXFA_FMParserTest, Empty) { ASSERT(ast != nullptr); EXPECT_FALSE(parser->HasError()); + CXFA_FMToJavaScriptDepth::Reset(); CFX_WideTextBuf buf; EXPECT_TRUE(ast->ToJavaScript(buf)); // TODO(dsinclair): This is a little weird ..... @@ -31,6 +33,7 @@ TEST(CXFA_FMParserTest, CommentOnlyIsError) { EXPECT_FALSE(parser->HasError()); // EXPECT_TRUE(parser->HasError()); + CXFA_FMToJavaScriptDepth::Reset(); CFX_WideTextBuf buf; EXPECT_TRUE(ast->ToJavaScript(buf)); EXPECT_EQ(L"// comments only", buf.AsStringView()); @@ -49,6 +52,7 @@ TEST(CXFA_FMParserTest, CommentThenValue) { ASSERT(ast != nullptr); EXPECT_FALSE(parser->HasError()); + CXFA_FMToJavaScriptDepth::Reset(); CFX_WideTextBuf buf; EXPECT_TRUE(ast->ToJavaScript(buf)); EXPECT_EQ(ret, buf.AsStringView()); @@ -104,6 +108,7 @@ TEST(CXFA_FMParserTest, Parse) { ASSERT(ast != nullptr); EXPECT_FALSE(parser->HasError()); + CXFA_FMToJavaScriptDepth::Reset(); CFX_WideTextBuf buf; EXPECT_TRUE(ast->ToJavaScript(buf)); EXPECT_EQ(ret, buf.AsStringView()); diff --git a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp index 3cfe0f52d5..86b7c91ec5 100644 --- a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp +++ b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp @@ -7,11 +7,14 @@ #include "xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h" #include <algorithm> +#include <iostream> #include <utility> +#include "core/fxcrt/autorestorer.h" #include "core/fxcrt/cfx_widetextbuf.h" #include "core/fxcrt/fx_extension.h" #include "third_party/base/logging.h" +#include "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h" namespace { @@ -90,11 +93,13 @@ CXFA_FMSimpleExpression::CXFA_FMSimpleExpression(uint32_t line, XFA_FM_TOKEN op) : m_line(line), m_op(op) {} bool CXFA_FMSimpleExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - return true; + CXFA_FMToJavaScriptDepth depthManager; + return depthManager.IsWithinMaxDepth(); } bool CXFA_FMSimpleExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { - return true; + CXFA_FMToJavaScriptDepth depthManager; + return depthManager.IsWithinMaxDepth(); } XFA_FM_TOKEN CXFA_FMSimpleExpression::GetOperatorToken() const { @@ -105,6 +110,10 @@ CXFA_FMNullExpression::CXFA_FMNullExpression(uint32_t line) : CXFA_FMSimpleExpression(line, TOKnull) {} bool CXFA_FMNullExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"null"; return true; } @@ -116,6 +125,10 @@ CXFA_FMNumberExpression::CXFA_FMNumberExpression(uint32_t line, CXFA_FMNumberExpression::~CXFA_FMNumberExpression() {} bool CXFA_FMNumberExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << m_wsNumber; return true; } @@ -127,6 +140,10 @@ CXFA_FMStringExpression::CXFA_FMStringExpression(uint32_t line, CXFA_FMStringExpression::~CXFA_FMStringExpression() {} bool CXFA_FMStringExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + WideString tempStr(m_wsString); if (tempStr.GetLength() <= 2) { javascript << tempStr; @@ -163,6 +180,10 @@ CXFA_FMIdentifierExpression::CXFA_FMIdentifierExpression( CXFA_FMIdentifierExpression::~CXFA_FMIdentifierExpression() {} bool CXFA_FMIdentifierExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + WideString tempStr(m_wsIdentifier); if (tempStr == L"$") { tempStr = L"this"; @@ -197,7 +218,8 @@ CXFA_FMUnaryExpression::CXFA_FMUnaryExpression( CXFA_FMUnaryExpression::~CXFA_FMUnaryExpression() {} bool CXFA_FMUnaryExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - return true; + CXFA_FMToJavaScriptDepth depthManager; + return depthManager.IsWithinMaxDepth(); } CXFA_FMBinExpression::CXFA_FMBinExpression( @@ -212,7 +234,8 @@ CXFA_FMBinExpression::CXFA_FMBinExpression( CXFA_FMBinExpression::~CXFA_FMBinExpression() {} bool CXFA_FMBinExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - return true; + CXFA_FMToJavaScriptDepth depthManager; + return depthManager.IsWithinMaxDepth(); } CXFA_FMAssignExpression::CXFA_FMAssignExpression( @@ -223,6 +246,10 @@ CXFA_FMAssignExpression::CXFA_FMAssignExpression( : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} bool CXFA_FMAssignExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"if ("; javascript << gs_lpStrExpFuncName[ISFMOBJECT]; javascript << L"("; @@ -259,6 +286,10 @@ bool CXFA_FMAssignExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } bool CXFA_FMAssignExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"if ("; javascript << gs_lpStrExpFuncName[ISFMOBJECT]; javascript << L"("; @@ -306,6 +337,10 @@ CXFA_FMLogicalOrExpression::CXFA_FMLogicalOrExpression( : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} bool CXFA_FMLogicalOrExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << gs_lpStrExpFuncName[LOGICALOR]; javascript << L"("; if (!m_pExp1->ToJavaScript(javascript)) @@ -325,6 +360,10 @@ CXFA_FMLogicalAndExpression::CXFA_FMLogicalAndExpression( : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} bool CXFA_FMLogicalAndExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << gs_lpStrExpFuncName[LOGICALAND]; javascript << L"("; if (!m_pExp1->ToJavaScript(javascript)) @@ -344,6 +383,10 @@ CXFA_FMEqualityExpression::CXFA_FMEqualityExpression( : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} bool CXFA_FMEqualityExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + switch (m_op) { case TOKeq: case TOKkseq: @@ -375,6 +418,10 @@ CXFA_FMRelationalExpression::CXFA_FMRelationalExpression( : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} bool CXFA_FMRelationalExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + switch (m_op) { case TOKlt: case TOKkslt: @@ -414,6 +461,10 @@ CXFA_FMAdditiveExpression::CXFA_FMAdditiveExpression( : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} bool CXFA_FMAdditiveExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + switch (m_op) { case TOKplus: javascript << gs_lpStrExpFuncName[PLUS]; @@ -444,6 +495,10 @@ CXFA_FMMultiplicativeExpression::CXFA_FMMultiplicativeExpression( bool CXFA_FMMultiplicativeExpression::ToJavaScript( CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + switch (m_op) { case TOKmul: javascript << gs_lpStrExpFuncName[MULTIPLE]; @@ -471,6 +526,10 @@ CXFA_FMPosExpression::CXFA_FMPosExpression( : CXFA_FMUnaryExpression(line, TOKplus, std::move(pExp)) {} bool CXFA_FMPosExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << gs_lpStrExpFuncName[POSITIVE]; javascript << L"("; if (!m_pExp->ToJavaScript(javascript)) @@ -485,6 +544,10 @@ CXFA_FMNegExpression::CXFA_FMNegExpression( : CXFA_FMUnaryExpression(line, TOKminus, std::move(pExp)) {} bool CXFA_FMNegExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << gs_lpStrExpFuncName[NEGATIVE]; javascript << L"("; if (!m_pExp->ToJavaScript(javascript)) @@ -499,6 +562,10 @@ CXFA_FMNotExpression::CXFA_FMNotExpression( : CXFA_FMUnaryExpression(line, TOKksnot, std::move(pExp)) {} bool CXFA_FMNotExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << gs_lpStrExpFuncName[NOT]; javascript << L"("; if (!m_pExp->ToJavaScript(javascript)) @@ -553,6 +620,10 @@ uint32_t CXFA_FMCallExpression::IsMethodWithObjParam( } bool CXFA_FMCallExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + CFX_WideTextBuf funcName; if (!m_pExp->ToJavaScript(funcName)) return false; @@ -666,6 +737,10 @@ CXFA_FMDotAccessorExpression::CXFA_FMDotAccessorExpression( CXFA_FMDotAccessorExpression::~CXFA_FMDotAccessorExpression() {} bool CXFA_FMDotAccessorExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << gs_lpStrExpFuncName[DOT]; javascript << L"("; CFX_WideTextBuf tempExp1; @@ -713,6 +788,10 @@ CXFA_FMIndexExpression::CXFA_FMIndexExpression( m_bIsStarIndex(bIsStarIndex) {} bool CXFA_FMIndexExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + switch (m_accessorIndex) { case ACCESSOR_NO_INDEX: javascript << L"0"; @@ -757,6 +836,10 @@ CXFA_FMDotDotAccessorExpression::~CXFA_FMDotDotAccessorExpression() {} bool CXFA_FMDotDotAccessorExpression::ToJavaScript( CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << gs_lpStrExpFuncName[DOTDOT]; javascript << L"("; CFX_WideTextBuf tempExp1; @@ -790,6 +873,10 @@ CXFA_FMMethodCallExpression::CXFA_FMMethodCallExpression( std::move(pCallExp)) {} bool CXFA_FMMethodCallExpression::ToJavaScript(CFX_WideTextBuf& javascript) { + CXFA_FMToJavaScriptDepth depthManager; + if (!depthManager.IsWithinMaxDepth()) + return false; + javascript << L"(\nfunction ()\n{\n"; javascript << L"var method_return_value = null;\n"; javascript << L"var accessor_object = "; diff --git a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression_unittest.cpp b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression_unittest.cpp index 5f4d83c327..96ccb71ca9 100644 --- a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression_unittest.cpp +++ b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression_unittest.cpp @@ -13,6 +13,7 @@ #include "testing/test_support.h" #include "third_party/base/ptr_util.h" #include "xfa/fxfa/fm2js/cxfa_fmlexer.h" +#include "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h" TEST(FMCallExpressionTest, more_than_32_arguments) { // Use sign as it has 3 object parameters at positions 0, 5, and 6. @@ -22,6 +23,7 @@ TEST(FMCallExpressionTest, more_than_32_arguments) { for (size_t i = 0; i < 50; i++) args.push_back(pdfium::MakeUnique<CXFA_FMSimpleExpression>(0, TOKnan)); + CXFA_FMToJavaScriptDepth::Reset(); CXFA_FMCallExpression callExp(0, std::move(exp), std::move(args), true); CFX_WideTextBuf js; callExp.ToJavaScript(js); @@ -45,24 +47,28 @@ TEST(FMCallExpressionTest, more_than_32_arguments) { } TEST(FMStringExpressionTest, Empty) { + CXFA_FMToJavaScriptDepth::Reset(); CFX_WideTextBuf accumulator; CXFA_FMStringExpression(1, WideStringView()).ToJavaScript(accumulator); EXPECT_EQ(L"", accumulator.AsStringView()); } TEST(FMStringExpressionTest, Short) { + CXFA_FMToJavaScriptDepth::Reset(); CFX_WideTextBuf accumulator; CXFA_FMStringExpression(1, L"a").ToJavaScript(accumulator); EXPECT_EQ(L"a", accumulator.AsStringView()); } TEST(FMStringExpressionTest, Medium) { + CXFA_FMToJavaScriptDepth::Reset(); CFX_WideTextBuf accumulator; CXFA_FMStringExpression(1, L".abcd.").ToJavaScript(accumulator); EXPECT_EQ(L"\"abcd\"", accumulator.AsStringView()); } TEST(FMStringExpressionTest, Long) { + CXFA_FMToJavaScriptDepth::Reset(); CFX_WideTextBuf accumulator; std::vector<WideStringView::UnsignedType> vec(140000, L'A'); CXFA_FMStringExpression(1, WideStringView(vec)).ToJavaScript(accumulator); @@ -70,6 +76,7 @@ TEST(FMStringExpressionTest, Long) { } TEST(FMStringExpressionTest, Quoted) { + CXFA_FMToJavaScriptDepth::Reset(); CFX_WideTextBuf accumulator; CXFA_FMStringExpression(1, L".Simon says \"\"run\"\".") .ToJavaScript(accumulator); diff --git a/xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.cpp b/xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.cpp new file mode 100644 index 0000000000..6312ba6b3d --- /dev/null +++ b/xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.cpp @@ -0,0 +1,21 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h" + +namespace { + +// Arbitarily picked by looking at how deep a translation got before hitting +// the getting fuzzer memory limits. Should be larger then |kMaxParseDepth| in +// cxfa_fmparser.cpp. +const unsigned int kMaxDepth = 5000; + +} // namespace + +unsigned long CXFA_FMToJavaScriptDepth::depth_ = 0; +unsigned long CXFA_FMToJavaScriptDepth::max_depth_ = kMaxDepth; + +void CXFA_FMToJavaScriptDepth::Reset() { + depth_ = 0; +} diff --git a/xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h b/xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h new file mode 100644 index 0000000000..14f87a68f5 --- /dev/null +++ b/xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h @@ -0,0 +1,22 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef XFA_FXFA_FM2JS_CXFA_FMTOJAVASCRIPTDEPTH_H_ +#define XFA_FXFA_FM2JS_CXFA_FMTOJAVASCRIPTDEPTH_H_ + +class CXFA_FMToJavaScriptDepth { + public: + CXFA_FMToJavaScriptDepth() { depth_++; } + ~CXFA_FMToJavaScriptDepth() { depth_--; } + + bool IsWithinMaxDepth() const { return depth_ <= max_depth_; } + + static void Reset(); + + private: + static unsigned long depth_; + static unsigned long max_depth_; +}; + +#endif // XFA_FXFA_FM2JS_CXFA_FMTOJAVASCRIPTDEPTH_H_ |