summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn2
-rw-r--r--xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp2
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmexpression.cpp100
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp5
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp95
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmsimpleexpression_unittest.cpp7
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.cpp21
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h22
8 files changed, 245 insertions, 9 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 5d0ad6dcd8..8807e8a061 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -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_