summaryrefslogtreecommitdiff
path: root/xfa/fxfa
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fxfa')
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmlexer.cpp10
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmlexer.h1
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp24
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmparser.cpp19
4 files changed, 44 insertions, 10 deletions
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer.cpp b/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
index 72fe0f2a01..32e29575c5 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
@@ -133,13 +133,13 @@ CXFA_FMLexer::CXFA_FMLexer(const WideStringView& wsFormCalc)
m_end(m_cursor + wsFormCalc.GetLength()),
m_lexer_error(false) {}
-CXFA_FMLexer::~CXFA_FMLexer() {}
+CXFA_FMLexer::~CXFA_FMLexer() = default;
CXFA_FMToken CXFA_FMLexer::NextToken() {
if (m_lexer_error)
return CXFA_FMToken();
- while (m_cursor < m_end && *m_cursor) {
+ while (!IsComplete() && *m_cursor) {
if (!IsFormCalcCharacter(*m_cursor)) {
RaiseError();
return CXFA_FMToken();
@@ -323,7 +323,7 @@ CXFA_FMToken CXFA_FMLexer::AdvanceForString() {
const wchar_t* start = m_cursor;
++m_cursor;
- while (m_cursor < m_end && *m_cursor) {
+ while (!IsComplete() && *m_cursor) {
if (!IsFormCalcCharacter(*m_cursor))
break;
@@ -357,7 +357,7 @@ CXFA_FMToken CXFA_FMLexer::AdvanceForString() {
CXFA_FMToken CXFA_FMLexer::AdvanceForIdentifier() {
const wchar_t* start = m_cursor;
++m_cursor;
- while (m_cursor < m_end && *m_cursor) {
+ while (!IsComplete() && *m_cursor) {
if (!IsFormCalcCharacter(*m_cursor)) {
RaiseError();
return CXFA_FMToken();
@@ -377,7 +377,7 @@ CXFA_FMToken CXFA_FMLexer::AdvanceForIdentifier() {
void CXFA_FMLexer::AdvanceForComment() {
m_cursor++;
- while (m_cursor < m_end && *m_cursor) {
+ while (!IsComplete() && *m_cursor) {
if (!IsFormCalcCharacter(*m_cursor)) {
RaiseError();
return;
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer.h b/xfa/fxfa/fm2js/cxfa_fmlexer.h
index 3864abb0eb..58b193e0ec 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer.h
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer.h
@@ -109,6 +109,7 @@ class CXFA_FMLexer {
~CXFA_FMLexer();
CXFA_FMToken NextToken();
+ bool IsComplete() const { return m_cursor >= m_end; }
private:
CXFA_FMToken AdvanceForNumber();
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp b/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
index 248b9fead6..cefc1cb992 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
@@ -15,12 +15,14 @@ TEST(CXFA_FMLexerTest, NullString) {
CXFA_FMLexer lexer(null_string);
CXFA_FMToken token = lexer.NextToken();
EXPECT_EQ(TOKeof, token.m_type);
+ EXPECT_TRUE(lexer.IsComplete());
}
TEST(CXFA_FMLexerTest, EmptyString) {
CXFA_FMLexer lexer(L"");
CXFA_FMToken token = lexer.NextToken();
EXPECT_EQ(TOKeof, token.m_type);
+ EXPECT_TRUE(lexer.IsComplete());
}
TEST(CXFA_FMLexerTest, Numbers) {
@@ -67,6 +69,7 @@ TEST(CXFA_FMLexerTest, Numbers) {
// prior to the exponent.
// EXPECT_EQ(L"100000000000000000", token.m_string);
EXPECT_EQ(L"99999999999999999", token.m_string);
+ EXPECT_TRUE(lexer->IsComplete());
}
// The quotes are stripped in CXFA_FMStringExpression::ToJavaScript.
@@ -99,6 +102,7 @@ TEST(CXFA_FMLexerTest, Strings) {
EXPECT_EQ(
L"\"\\u0047\\u006f\\u0066\\u0069\\u0073\\u0068\\u0021\\u000d\\u000a\"",
token.m_string);
+ EXPECT_TRUE(lexer->IsComplete());
}
// Note, 'this' is a keyword but is not matched by the lexer.
@@ -170,6 +174,7 @@ TEST(CXFA_FMLexerTest, OperatorsAndKeywords) {
auto lexer = pdfium::MakeUnique<CXFA_FMLexer>(op[i].op);
CXFA_FMToken token = lexer->NextToken();
EXPECT_EQ(op[i].token, token.m_type);
+ EXPECT_TRUE(lexer->IsComplete());
}
}
@@ -213,6 +218,7 @@ TEST(CXFA_FMLexerTest, Comments) {
token = lexer->NextToken();
EXPECT_EQ(TOKeof, token.m_type);
+ EXPECT_TRUE(lexer->IsComplete());
}
TEST(CXFA_FMLexerTest, ValidIdentifiers) {
@@ -223,6 +229,7 @@ TEST(CXFA_FMLexerTest, ValidIdentifiers) {
CXFA_FMToken token = lexer->NextToken();
EXPECT_EQ(TOKidentifier, token.m_type);
EXPECT_EQ(ident, token.m_string);
+ EXPECT_TRUE(lexer->IsComplete());
}
}
@@ -248,6 +255,7 @@ TEST(CXFA_FMLexerTest, InvalidIdentifiers) {
EXPECT_NE(TOKreserver, token.m_type);
token = lexer->NextToken();
EXPECT_EQ(TOKreserver, token.m_type);
+ EXPECT_FALSE(lexer->IsComplete());
}
TEST(CXFA_FMLexerTest, Whitespace) {
@@ -266,4 +274,20 @@ TEST(CXFA_FMLexerTest, Whitespace) {
token = lexer->NextToken();
EXPECT_EQ(TOKeof, token.m_type);
+ EXPECT_TRUE(lexer->IsComplete());
+}
+
+TEST(CXFA_FMLexerTest, NullData) {
+ auto lexer = pdfium::MakeUnique<CXFA_FMLexer>(
+ WideStringView(L"\x2d\x32\x00\x2d\x32", 5));
+ CXFA_FMToken token = lexer->NextToken();
+ EXPECT_EQ(TOKminus, token.m_type);
+
+ token = lexer->NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ EXPECT_EQ(L"2", token.m_string);
+
+ token = lexer->NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ EXPECT_FALSE(lexer->IsComplete());
}
diff --git a/xfa/fxfa/fm2js/cxfa_fmparser.cpp b/xfa/fxfa/fm2js/cxfa_fmparser.cpp
index fb4a7f4cf9..be0a31b519 100644
--- a/xfa/fxfa/fm2js/cxfa_fmparser.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmparser.cpp
@@ -21,18 +21,26 @@ constexpr unsigned int kMaxPostExpressions = 256;
} // namespace
CXFA_FMParser::CXFA_FMParser(const WideStringView& wsFormcalc)
- : m_error(false), m_parse_depth(0), m_max_parse_depth(kMaxParseDepth) {
- m_lexer = pdfium::MakeUnique<CXFA_FMLexer>(wsFormcalc);
- m_token = m_lexer->NextToken();
-}
+ : m_lexer(pdfium::MakeUnique<CXFA_FMLexer>(wsFormcalc)),
+ m_error(false),
+ m_parse_depth(0),
+ m_max_parse_depth(kMaxParseDepth) {}
-CXFA_FMParser::~CXFA_FMParser() {}
+CXFA_FMParser::~CXFA_FMParser() = default;
std::unique_ptr<CXFA_FMAST> CXFA_FMParser::Parse() {
+ m_token = m_lexer->NextToken();
+ if (HasError())
+ return nullptr;
+
auto expressions = ParseExpressionList();
if (HasError())
return nullptr;
+ // We failed to parse all of the input so something has gone wrong.
+ if (!m_lexer->IsComplete())
+ return nullptr;
+
return pdfium::MakeUnique<CXFA_FMAST>(std::move(expressions));
}
@@ -66,6 +74,7 @@ CXFA_FMParser::ParseExpressionList() {
AutoRestorer<unsigned long> restorer(&m_parse_depth);
if (HasError() || !IncrementParseDepthAndCheck())
return std::vector<std::unique_ptr<CXFA_FMExpression>>();
+
std::vector<std::unique_ptr<CXFA_FMExpression>> expressions;
while (!HasError()) {
if (m_token.m_type == TOKeof || m_token.m_type == TOKendfunc ||