summaryrefslogtreecommitdiff
path: root/xfa/fxfa/fm2js
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fxfa/fm2js')
-rw-r--r--xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp2
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmlexer.cpp136
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmlexer.h12
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp44
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmparse.cpp1147
-rw-r--r--xfa/fxfa/fm2js/cxfa_fmparse.h8
6 files changed, 766 insertions, 583 deletions
diff --git a/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp b/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp
index bea1f32d23..81942e274e 100644
--- a/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp
@@ -6065,7 +6065,7 @@ bool CXFA_FM2JSContext::Translate(const CFX_WideStringC& wsFormcalc,
CXFA_FMParse parser(wsFormcalc);
std::unique_ptr<CXFA_FMFunctionDefinition> func = parser.Parse();
- if (parser.HasError())
+ if (!func || parser.HasError())
return false;
if (!func->ToJavaScript(*wsJavascript))
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer.cpp b/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
index 5ae8a6f40b..d217587e66 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
@@ -156,12 +156,15 @@ CXFA_FMLexer::CXFA_FMLexer(const CFX_WideStringC& wsFormCalc)
CXFA_FMLexer::~CXFA_FMLexer() {}
-CXFA_FMToken* CXFA_FMLexer::NextToken() {
+std::unique_ptr<CXFA_FMToken> CXFA_FMLexer::NextToken() {
+ if (m_lexer_error)
+ return nullptr;
+
m_token = pdfium::MakeUnique<CXFA_FMToken>(m_current_line);
while (m_cursor <= m_end && *m_cursor) {
if (!IsFormCalcCharacter(*m_cursor)) {
- m_lexer_error = true;
- return m_token.get();
+ RaiseError();
+ return nullptr;
}
switch (*m_cursor) {
@@ -180,7 +183,7 @@ CXFA_FMToken* CXFA_FMLexer::NextToken() {
case '"': {
m_token->m_type = TOKstring;
AdvanceForString();
- return m_token.get();
+ return std::move(m_token);
}
case '0':
case '1':
@@ -194,119 +197,119 @@ CXFA_FMToken* CXFA_FMLexer::NextToken() {
case '9': {
m_token->m_type = TOKnumber;
AdvanceForNumber();
- return m_token.get();
+ return std::move(m_token);
}
case '=':
++m_cursor;
if (m_cursor > m_end) {
m_token->m_type = TOKassign;
- return m_token.get();
+ return std::move(m_token);
}
- if (IsFormCalcCharacter(*m_cursor)) {
- if (*m_cursor == '=') {
- m_token->m_type = TOKeq;
- ++m_cursor;
- } else {
- m_token->m_type = TOKassign;
- }
+ if (!IsFormCalcCharacter(*m_cursor)) {
+ RaiseError();
+ return nullptr;
+ }
+ if (*m_cursor == '=') {
+ m_token->m_type = TOKeq;
+ ++m_cursor;
} else {
- m_lexer_error = true;
+ m_token->m_type = TOKassign;
}
- return m_token.get();
+ return std::move(m_token);
case '<':
++m_cursor;
if (m_cursor > m_end) {
m_token->m_type = TOKlt;
- return m_token.get();
+ return std::move(m_token);
}
- if (IsFormCalcCharacter(*m_cursor)) {
- if (*m_cursor == '=') {
- m_token->m_type = TOKle;
- ++m_cursor;
- } else if (*m_cursor == '>') {
- m_token->m_type = TOKne;
- ++m_cursor;
- } else {
- m_token->m_type = TOKlt;
- }
+ if (!IsFormCalcCharacter(*m_cursor)) {
+ RaiseError();
+ return nullptr;
+ }
+ if (*m_cursor == '=') {
+ m_token->m_type = TOKle;
+ ++m_cursor;
+ } else if (*m_cursor == '>') {
+ m_token->m_type = TOKne;
+ ++m_cursor;
} else {
- m_lexer_error = true;
+ m_token->m_type = TOKlt;
}
- return m_token.get();
+ return std::move(m_token);
case '>':
++m_cursor;
if (m_cursor > m_end) {
m_token->m_type = TOKgt;
- return m_token.get();
+ return std::move(m_token);
}
- if (IsFormCalcCharacter(*m_cursor)) {
- if (*m_cursor == '=') {
- m_token->m_type = TOKge;
- ++m_cursor;
- } else {
- m_token->m_type = TOKgt;
- }
+ if (!IsFormCalcCharacter(*m_cursor)) {
+ RaiseError();
+ return nullptr;
+ }
+ if (*m_cursor == '=') {
+ m_token->m_type = TOKge;
+ ++m_cursor;
} else {
- m_lexer_error = true;
+ m_token->m_type = TOKgt;
}
- return m_token.get();
+ return std::move(m_token);
case ',':
m_token->m_type = TOKcomma;
++m_cursor;
- return m_token.get();
+ return std::move(m_token);
case '(':
m_token->m_type = TOKlparen;
++m_cursor;
- return m_token.get();
+ return std::move(m_token);
case ')':
m_token->m_type = TOKrparen;
++m_cursor;
- return m_token.get();
+ return std::move(m_token);
case '[':
m_token->m_type = TOKlbracket;
++m_cursor;
- return m_token.get();
+ return std::move(m_token);
case ']':
m_token->m_type = TOKrbracket;
++m_cursor;
- return m_token.get();
+ return std::move(m_token);
case '&':
++m_cursor;
m_token->m_type = TOKand;
- return m_token.get();
+ return std::move(m_token);
case '|':
++m_cursor;
m_token->m_type = TOKor;
- return m_token.get();
+ return std::move(m_token);
case '+':
++m_cursor;
m_token->m_type = TOKplus;
- return m_token.get();
+ return std::move(m_token);
case '-':
++m_cursor;
m_token->m_type = TOKminus;
- return m_token.get();
+ return std::move(m_token);
case '*':
++m_cursor;
m_token->m_type = TOKmul;
- return m_token.get();
+ return std::move(m_token);
case '/': {
++m_cursor;
if (m_cursor > m_end) {
m_token->m_type = TOKdiv;
- return m_token.get();
+ return std::move(m_token);
}
if (!IsFormCalcCharacter(*m_cursor)) {
- m_lexer_error = true;
- return m_token.get();
+ RaiseError();
+ return nullptr;
}
if (*m_cursor != '/') {
m_token->m_type = TOKdiv;
- return m_token.get();
+ return std::move(m_token);
}
AdvanceForComment();
break;
@@ -315,12 +318,12 @@ CXFA_FMToken* CXFA_FMLexer::NextToken() {
++m_cursor;
if (m_cursor > m_end) {
m_token->m_type = TOKdot;
- return m_token.get();
+ return std::move(m_token);
}
if (!IsFormCalcCharacter(*m_cursor)) {
- m_lexer_error = true;
- return m_token.get();
+ RaiseError();
+ return nullptr;
}
if (*m_cursor == '.') {
@@ -339,7 +342,7 @@ CXFA_FMToken* CXFA_FMLexer::NextToken() {
} else {
m_token->m_type = TOKdot;
}
- return m_token.get();
+ return std::move(m_token);
case 0x09:
case 0x0B:
case 0x0C:
@@ -348,11 +351,11 @@ CXFA_FMToken* CXFA_FMLexer::NextToken() {
break;
default: {
if (!IsInitialIdentifierCharacter(*m_cursor)) {
- m_lexer_error = true;
- return m_token.get();
+ RaiseError();
+ return nullptr;
}
AdvanceForIdentifier();
- return m_token.get();
+ return std::move(m_token);
}
}
}
@@ -360,7 +363,7 @@ CXFA_FMToken* CXFA_FMLexer::NextToken() {
// If there isn't currently a token type then mark it EOF.
if (m_token->m_type == TOKreserver)
m_token->m_type = TOKeof;
- return m_token.get();
+ return std::move(m_token);
}
void CXFA_FMLexer::AdvanceForNumber() {
@@ -369,7 +372,7 @@ void CXFA_FMLexer::AdvanceForNumber() {
if (m_cursor)
wcstod(const_cast<wchar_t*>(m_cursor), &end);
if (end && FXSYS_iswalpha(*end)) {
- m_lexer_error = true;
+ RaiseError();
return;
}
@@ -406,8 +409,7 @@ void CXFA_FMLexer::AdvanceForString() {
}
// Didn't find the end of the string.
- m_token->m_string = CFX_WideStringC(start, (m_cursor - start));
- m_lexer_error = true;
+ RaiseError();
}
void CXFA_FMLexer::AdvanceForIdentifier() {
@@ -415,8 +417,7 @@ void CXFA_FMLexer::AdvanceForIdentifier() {
++m_cursor;
while (m_cursor <= m_end && *m_cursor) {
if (!IsFormCalcCharacter(*m_cursor)) {
- m_token->m_string = CFX_WideStringC(start, (m_cursor - start));
- m_lexer_error = true;
+ RaiseError();
return;
}
@@ -432,6 +433,11 @@ void CXFA_FMLexer::AdvanceForIdentifier() {
void CXFA_FMLexer::AdvanceForComment() {
m_cursor++;
while (m_cursor <= m_end && *m_cursor) {
+ if (!IsFormCalcCharacter(*m_cursor)) {
+ RaiseError();
+ return;
+ }
+
if (*m_cursor == L'\r') {
++m_cursor;
return;
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer.h b/xfa/fxfa/fm2js/cxfa_fmlexer.h
index 858dc5d988..39031760d9 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer.h
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer.h
@@ -107,14 +107,9 @@ class CXFA_FMLexer {
explicit CXFA_FMLexer(const CFX_WideStringC& wsFormcalc);
~CXFA_FMLexer();
- CXFA_FMToken* NextToken();
- bool HasError() const { return m_lexer_error; }
+ std::unique_ptr<CXFA_FMToken> NextToken();
void SetCurrentLine(uint32_t line) { m_current_line = line; }
- void SetToken(std::unique_ptr<CXFA_FMToken> token) {
- m_token = std::move(token);
- }
-
const wchar_t* GetPos() { return m_cursor; }
void SetPos(const wchar_t* pos) { m_cursor = pos; }
@@ -124,6 +119,11 @@ class CXFA_FMLexer {
void AdvanceForIdentifier();
void AdvanceForComment();
+ void RaiseError() {
+ m_token.reset();
+ m_lexer_error = true;
+ }
+
const wchar_t* m_cursor;
const wchar_t* const m_end;
uint32_t m_current_line;
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp b/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
index 92b8fa93b3..a6ab871b18 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
@@ -12,13 +12,13 @@
TEST(CXFA_FMLexerTest, EmptyString) {
CXFA_FMLexer lexer(L"");
- CXFA_FMToken* token = lexer.NextToken();
+ std::unique_ptr<CXFA_FMToken> token = lexer.NextToken();
EXPECT_EQ(TOKeof, token->m_type);
}
TEST(CXFA_FMLexerTest, Numbers) {
auto lexer = pdfium::MakeUnique<CXFA_FMLexer>(L"-12");
- CXFA_FMToken* token = lexer->NextToken();
+ std::unique_ptr<CXFA_FMToken> token = lexer->NextToken();
// TODO(dsinclair): Should this return -12 instead of two tokens?
EXPECT_EQ(TOKminus, token->m_type);
token = lexer->NextToken();
@@ -66,7 +66,7 @@ TEST(CXFA_FMLexerTest, Numbers) {
TEST(CXFA_FMLexerTest, Strings) {
auto lexer =
pdfium::MakeUnique<CXFA_FMLexer>(L"\"The cat jumped over the fence.\"");
- CXFA_FMToken* token = lexer->NextToken();
+ std::unique_ptr<CXFA_FMToken> token = lexer->NextToken();
EXPECT_EQ(TOKstring, token->m_type);
EXPECT_EQ(L"\"The cat jumped over the fence.\"", token->m_string);
@@ -161,14 +161,14 @@ TEST(CXFA_FMLexerTest, OperatorsAndKeywords) {
for (size_t i = 0; i < FX_ArraySize(op); ++i) {
auto lexer = pdfium::MakeUnique<CXFA_FMLexer>(op[i].op);
- CXFA_FMToken* token = lexer->NextToken();
+ std::unique_ptr<CXFA_FMToken> token = lexer->NextToken();
EXPECT_EQ(op[i].token, token->m_type);
}
}
TEST(CXFA_FMLexerTest, Comments) {
auto lexer = pdfium::MakeUnique<CXFA_FMLexer>(L"// Empty.");
- CXFA_FMToken* token = lexer->NextToken();
+ std::unique_ptr<CXFA_FMToken> token = lexer->NextToken();
EXPECT_EQ(TOKeof, token->m_type);
lexer = pdfium::MakeUnique<CXFA_FMLexer>(L"//");
@@ -213,7 +213,7 @@ TEST(CXFA_FMLexerTest, ValidIdentifiers) {
L"a", L"an_identifier", L"_ident", L"$ident", L"!ident", L"GetAddr"};
for (const auto* ident : identifiers) {
auto lexer = pdfium::MakeUnique<CXFA_FMLexer>(ident);
- CXFA_FMToken* token = lexer->NextToken();
+ std::unique_ptr<CXFA_FMToken> token = lexer->NextToken();
EXPECT_EQ(TOKidentifier, token->m_type);
EXPECT_EQ(ident, token->m_string);
}
@@ -221,40 +221,24 @@ TEST(CXFA_FMLexerTest, ValidIdentifiers) {
TEST(CXFA_FMLexerTest, InvalidIdentifiers) {
auto lexer = pdfium::MakeUnique<CXFA_FMLexer>(L"#a");
- lexer->NextToken();
- // TODO(rharrison): Add an expects for the return being nullptr here.
- // See https://crbug.com/pdfium/814
- EXPECT_TRUE(lexer->HasError());
+ EXPECT_EQ(nullptr, lexer->NextToken());
lexer = pdfium::MakeUnique<CXFA_FMLexer>(L"1a");
- lexer->NextToken();
- // TODO(rharrison): Add an expects for the return being nullptr here.
- // See https://crbug.com/pdfium/814
- EXPECT_TRUE(lexer->HasError());
+ EXPECT_EQ(nullptr, lexer->NextToken());
lexer = pdfium::MakeUnique<CXFA_FMLexer>(L"an@identifier");
- lexer->NextToken();
- EXPECT_FALSE(lexer->HasError());
- lexer->NextToken();
- // TODO(rharrison): Add an expects for the return being nullptr here.
- // See https://crbug.com/pdfium/814
- EXPECT_TRUE(lexer->HasError());
- // TODO(rharrison): Add a test for if an another call to NextToken occurs,
- // the error state will be retained, instead of continuing the parse.
- // See https://crbug.com/pdfium/814
+ EXPECT_NE(nullptr, lexer->NextToken());
+ EXPECT_EQ(nullptr, lexer->NextToken());
+ EXPECT_EQ(nullptr, lexer->NextToken());
lexer = pdfium::MakeUnique<CXFA_FMLexer>(L"_ident@");
- lexer->NextToken();
- EXPECT_FALSE(lexer->HasError());
- lexer->NextToken();
- // TODO(rharrison): Add an expects for the return being nullptr here.
- // See https://crbug.com/pdfium/814
- EXPECT_TRUE(lexer->HasError());
+ EXPECT_NE(nullptr, lexer->NextToken());
+ EXPECT_EQ(nullptr, lexer->NextToken());
}
TEST(CXFA_FMLexerTest, Whitespace) {
auto lexer = pdfium::MakeUnique<CXFA_FMLexer>(L" \t\xc\x9\xb");
- CXFA_FMToken* token = lexer->NextToken();
+ std::unique_ptr<CXFA_FMToken> token = lexer->NextToken();
EXPECT_EQ(TOKeof, token->m_type);
lexer = pdfium::MakeUnique<CXFA_FMLexer>(L"123 \t\xc\x9\xb 456");
diff --git a/xfa/fxfa/fm2js/cxfa_fmparse.cpp b/xfa/fxfa/fm2js/cxfa_fmparse.cpp
index 723a735936..8e163a40d0 100644
--- a/xfa/fxfa/fm2js/cxfa_fmparse.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmparse.cpp
@@ -18,18 +18,14 @@ const int kMaxAssignmentChainLength = 12;
} // namespace
-CXFA_FMParse::CXFA_FMParse(const CFX_WideStringC& wsFormcalc)
- : m_pToken(nullptr), m_ParserError(false) {
+CXFA_FMParse::CXFA_FMParse(const CFX_WideStringC& wsFormcalc) : m_error(false) {
m_lexer = pdfium::MakeUnique<CXFA_FMLexer>(wsFormcalc);
+ m_token = m_lexer->NextToken();
}
CXFA_FMParse::~CXFA_FMParse() {}
std::unique_ptr<CXFA_FMFunctionDefinition> CXFA_FMParse::Parse() {
- NextToken();
- if (HasError())
- return nullptr;
-
auto expressions = ParseTopExpression();
if (HasError())
return nullptr;
@@ -39,93 +35,122 @@ std::unique_ptr<CXFA_FMFunctionDefinition> CXFA_FMParse::Parse() {
1, true, L"", std::move(arguments), std::move(expressions));
}
-void CXFA_FMParse::NextToken() {
- m_pToken = m_lexer->NextToken();
- while (m_pToken->m_type == TOKreserver) {
- if (HasError())
- break;
- m_pToken = m_lexer->NextToken();
- }
+bool CXFA_FMParse::NextToken() {
+ if (HasError())
+ return false;
+ m_token = m_lexer->NextToken();
+ while (!HasError() && m_token->m_type == TOKreserver)
+ m_token = m_lexer->NextToken();
+ return !HasError();
}
-void CXFA_FMParse::Check(XFA_FM_TOKEN op) {
- if (m_pToken->m_type != op)
- m_ParserError = true;
- NextToken();
+bool CXFA_FMParse::CheckThenNext(XFA_FM_TOKEN op) {
+ if (HasError())
+ return false;
+
+ if (m_token->m_type != op) {
+ m_error = true;
+ return false;
+ }
+ return NextToken();
}
std::vector<std::unique_ptr<CXFA_FMExpression>>
CXFA_FMParse::ParseTopExpression() {
std::unique_ptr<CXFA_FMExpression> expr;
std::vector<std::unique_ptr<CXFA_FMExpression>> expressions;
- while (1) {
- if (m_pToken->m_type == TOKeof || m_pToken->m_type == TOKendfunc ||
- m_pToken->m_type == TOKendif || m_pToken->m_type == TOKelseif ||
- m_pToken->m_type == TOKelse || m_pToken->m_type == TOKreserver) {
+ if (HasError())
+ return expressions;
+
+ while (!HasError()) {
+ if (m_token->m_type == TOKeof || m_token->m_type == TOKendfunc ||
+ m_token->m_type == TOKendif || m_token->m_type == TOKelseif ||
+ m_token->m_type == TOKelse || m_token->m_type == TOKreserver) {
return expressions;
}
- expr = m_pToken->m_type == TOKfunc ? ParseFunction() : ParseExpression();
- if (!expr)
+ expr = m_token->m_type == TOKfunc ? ParseFunction() : ParseExpression();
+ if (!expr) {
+ m_error = true;
+ expressions.clear();
break;
+ }
expressions.push_back(std::move(expr));
}
+ if (HasError())
+ expressions.clear();
return expressions;
}
std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseFunction() {
+ if (HasError())
+ return nullptr;
+
CFX_WideStringC ident;
std::vector<CFX_WideStringC> arguments;
std::vector<std::unique_ptr<CXFA_FMExpression>> expressions;
- uint32_t line = m_pToken->m_line_num;
- NextToken();
- if (m_pToken->m_type != TOKidentifier) {
- m_ParserError = true;
+ uint32_t line = m_token->m_line_num;
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKidentifier) {
+ m_error = true;
+ return nullptr;
} else {
- ident = m_pToken->m_string;
- NextToken();
+ ident = m_token->m_string;
+ if (!NextToken())
+ return nullptr;
}
- Check(TOKlparen);
- if (m_pToken->m_type == TOKrparen) {
- NextToken();
+ if (!CheckThenNext(TOKlparen))
+ return nullptr;
+ if (m_token->m_type == TOKrparen) {
+ if (!NextToken())
+ return nullptr;
} else {
while (1) {
- if (m_pToken->m_type == TOKidentifier) {
- arguments.push_back(m_pToken->m_string);
- NextToken();
- if (m_pToken->m_type == TOKcomma) {
- NextToken();
- continue;
- }
- if (m_pToken->m_type == TOKrparen)
- NextToken();
- else
- Check(TOKrparen);
+ if (m_token->m_type != TOKidentifier) {
+ m_error = true;
+ return nullptr;
+ }
+ arguments.push_back(m_token->m_string);
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type == TOKcomma) {
+ if (!NextToken())
+ return nullptr;
+ continue;
+ }
+ if (m_token->m_type == TOKrparen) {
+ if (!NextToken())
+ return nullptr;
} else {
- m_ParserError = true;
- NextToken();
+ if (!CheckThenNext(TOKrparen))
+ return nullptr;
}
break;
}
}
- Check(TOKdo);
- if (m_pToken->m_type == TOKendfunc) {
- NextToken();
+ if (!CheckThenNext(TOKdo))
+ return nullptr;
+ if (m_token->m_type == TOKendfunc) {
+ if (!NextToken())
+ return nullptr;
} else {
expressions = ParseTopExpression();
- Check(TOKendfunc);
+ if (!expressions.size() || !CheckThenNext(TOKendfunc))
+ return nullptr;
}
- if (HasError())
- return nullptr;
return pdfium::MakeUnique<CXFA_FMFunctionDefinition>(
line, false, ident, std::move(arguments), std::move(expressions));
}
std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseExpression() {
+ if (HasError())
+ return nullptr;
+
std::unique_ptr<CXFA_FMExpression> expr;
- uint32_t line = m_pToken->m_line_num;
- switch (m_pToken->m_type) {
+ uint32_t line = m_token->m_line_num;
+ switch (m_token->m_type) {
case TOKvar:
expr = ParseVarExpression();
break;
@@ -156,86 +181,111 @@ std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseExpression() {
break;
case TOKbreak:
expr = pdfium::MakeUnique<CXFA_FMBreakExpression>(line);
- NextToken();
+ if (!NextToken())
+ return nullptr;
break;
case TOKcontinue:
expr = pdfium::MakeUnique<CXFA_FMContinueExpression>(line);
- NextToken();
+ if (!NextToken())
+ return nullptr;
break;
default:
- m_ParserError = true;
- NextToken();
- break;
+ m_error = true;
+ return nullptr;
}
return expr;
}
std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseVarExpression() {
+ if (HasError())
+ return nullptr;
+
CFX_WideStringC ident;
- uint32_t line = m_pToken->m_line_num;
- NextToken();
- if (m_pToken->m_type != TOKidentifier) {
- m_ParserError = true;
- } else {
- ident = m_pToken->m_string;
- NextToken();
+ uint32_t line = m_token->m_line_num;
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKidentifier) {
+ m_error = true;
+ return nullptr;
}
+
+ ident = m_token->m_string;
+ if (!NextToken())
+ return nullptr;
+
std::unique_ptr<CXFA_FMExpression> expr;
- if (m_pToken->m_type == TOKassign) {
- NextToken();
+ if (m_token->m_type == TOKassign) {
+ if (!NextToken())
+ return nullptr;
+
expr = ParseExpExpression();
+ if (!expr)
+ return nullptr;
}
- if (HasError())
- return nullptr;
return pdfium::MakeUnique<CXFA_FMVarExpression>(line, ident, std::move(expr));
}
std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParseSimpleExpression() {
- uint32_t line = m_pToken->m_line_num;
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
std::unique_ptr<CXFA_FMSimpleExpression> pExp1 = ParseLogicalOrExpression();
+ if (!pExp1)
+ return nullptr;
int level = 1;
- while (m_pToken->m_type == TOKassign) {
- NextToken();
+ while (m_token->m_type == TOKassign) {
+ if (!NextToken())
+ return nullptr;
std::unique_ptr<CXFA_FMSimpleExpression> pExp2 = ParseLogicalOrExpression();
- if (level++ == kMaxAssignmentChainLength)
- m_ParserError = true;
- if (!HasError()) {
- pExp1 = pdfium::MakeUnique<CXFA_FMAssignExpression>(
- line, TOKassign, std::move(pExp1), std::move(pExp2));
- } else {
- pExp1.reset();
+ if (!pExp2)
+ return nullptr;
+ if (level++ == kMaxAssignmentChainLength) {
+ m_error = true;
+ return nullptr;
}
+ pExp1 = pdfium::MakeUnique<CXFA_FMAssignExpression>(
+ line, TOKassign, std::move(pExp1), std::move(pExp2));
}
return pExp1;
}
std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseExpExpression() {
- uint32_t line = m_pToken->m_line_num;
- std::unique_ptr<CXFA_FMSimpleExpression> pExp1 = ParseSimpleExpression();
if (HasError())
return nullptr;
+ uint32_t line = m_token->m_line_num;
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp1 = ParseSimpleExpression();
+ if (!pExp1)
+ return nullptr;
return pdfium::MakeUnique<CXFA_FMExpExpression>(line, std::move(pExp1));
}
std::unique_ptr<CXFA_FMSimpleExpression>
CXFA_FMParse::ParseLogicalOrExpression() {
- uint32_t line = m_pToken->m_line_num;
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseLogicalAndExpression();
+ if (!e1)
+ return nullptr;
+
for (;;) {
- switch (m_pToken->m_type) {
+ switch (m_token->m_type) {
case TOKor:
case TOKksor: {
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
std::unique_ptr<CXFA_FMSimpleExpression> e2(
ParseLogicalAndExpression());
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMLogicalOrExpression>(
- line, TOKor, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMLogicalOrExpression>(
+ line, TOKor, std::move(e1), std::move(e2));
continue;
}
default:
@@ -248,20 +298,27 @@ CXFA_FMParse::ParseLogicalOrExpression() {
std::unique_ptr<CXFA_FMSimpleExpression>
CXFA_FMParse::ParseLogicalAndExpression() {
- uint32_t line = m_pToken->m_line_num;
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseEqualityExpression();
+ if (!e1)
+ return nullptr;
+
for (;;) {
- switch (m_pToken->m_type) {
+ switch (m_token->m_type) {
case TOKand:
case TOKksand: {
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
std::unique_ptr<CXFA_FMSimpleExpression> e2 = ParseEqualityExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMLogicalAndExpression>(
- line, TOKand, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMLogicalAndExpression>(
+ line, TOKand, std::move(e1), std::move(e2));
continue;
}
default:
@@ -274,32 +331,39 @@ CXFA_FMParse::ParseLogicalAndExpression() {
std::unique_ptr<CXFA_FMSimpleExpression>
CXFA_FMParse::ParseEqualityExpression() {
- uint32_t line = m_pToken->m_line_num;
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseRelationalExpression();
+ if (!e1)
+ return nullptr;
for (;;) {
std::unique_ptr<CXFA_FMSimpleExpression> e2;
- switch (m_pToken->m_type) {
+ switch (m_token->m_type) {
case TOKeq:
case TOKkseq:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
e2 = ParseRelationalExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMEqualityExpression>(
- line, TOKeq, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMEqualityExpression>(
+ line, TOKeq, std::move(e1), std::move(e2));
continue;
case TOKne:
case TOKksne:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
e2 = ParseRelationalExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMEqualityExpression>(
- line, TOKne, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMEqualityExpression>(
+ line, TOKne, std::move(e1), std::move(e2));
continue;
default:
break;
@@ -311,54 +375,64 @@ CXFA_FMParse::ParseEqualityExpression() {
std::unique_ptr<CXFA_FMSimpleExpression>
CXFA_FMParse::ParseRelationalExpression() {
- uint32_t line = m_pToken->m_line_num;
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseAddtiveExpression();
+ if (!e1)
+ return nullptr;
+
for (;;) {
std::unique_ptr<CXFA_FMSimpleExpression> e2;
- switch (m_pToken->m_type) {
+ switch (m_token->m_type) {
case TOKlt:
case TOKkslt:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
e2 = ParseAddtiveExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
- line, TOKlt, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
+ line, TOKlt, std::move(e1), std::move(e2));
continue;
case TOKgt:
case TOKksgt:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
e2 = ParseAddtiveExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
- line, TOKgt, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
+ line, TOKgt, std::move(e1), std::move(e2));
continue;
case TOKle:
case TOKksle:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
e2 = ParseAddtiveExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
- line, TOKle, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
+ line, TOKle, std::move(e1), std::move(e2));
continue;
case TOKge:
case TOKksge:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
e2 = ParseAddtiveExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
- line, TOKge, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>(
+ line, TOKge, std::move(e1), std::move(e2));
continue;
default:
break;
@@ -370,30 +444,38 @@ CXFA_FMParse::ParseRelationalExpression() {
std::unique_ptr<CXFA_FMSimpleExpression>
CXFA_FMParse::ParseAddtiveExpression() {
- uint32_t line = m_pToken->m_line_num;
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseMultiplicativeExpression();
+ if (!e1)
+ return nullptr;
+
for (;;) {
std::unique_ptr<CXFA_FMSimpleExpression> e2;
- switch (m_pToken->m_type) {
+ switch (m_token->m_type) {
case TOKplus:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
e2 = ParseMultiplicativeExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMAdditiveExpression>(
- line, TOKplus, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMAdditiveExpression>(
+ line, TOKplus, std::move(e1), std::move(e2));
continue;
case TOKminus:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
e2 = ParseMultiplicativeExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMAdditiveExpression>(
- line, TOKminus, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMAdditiveExpression>(
+ line, TOKminus, std::move(e1), std::move(e2));
continue;
default:
break;
@@ -405,30 +487,38 @@ CXFA_FMParse::ParseAddtiveExpression() {
std::unique_ptr<CXFA_FMSimpleExpression>
CXFA_FMParse::ParseMultiplicativeExpression() {
- uint32_t line = m_pToken->m_line_num;
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseUnaryExpression();
+ if (!e1)
+ return nullptr;
+
for (;;) {
std::unique_ptr<CXFA_FMSimpleExpression> e2;
- switch (m_pToken->m_type) {
+ switch (m_token->m_type) {
case TOKmul:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
e2 = ParseUnaryExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMMultiplicativeExpression>(
- line, TOKmul, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMMultiplicativeExpression>(
+ line, TOKmul, std::move(e1), std::move(e2));
continue;
case TOKdiv:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
e2 = ParseUnaryExpression();
- if (!HasError()) {
- e1 = pdfium::MakeUnique<CXFA_FMMultiplicativeExpression>(
- line, TOKdiv, std::move(e1), std::move(e2));
- } else {
- e1.reset();
- }
+ if (!e2)
+ return nullptr;
+
+ e1 = pdfium::MakeUnique<CXFA_FMMultiplicativeExpression>(
+ line, TOKdiv, std::move(e1), std::move(e2));
continue;
default:
break;
@@ -439,35 +529,46 @@ CXFA_FMParse::ParseMultiplicativeExpression() {
}
std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParseUnaryExpression() {
+ if (HasError())
+ return nullptr;
+
std::unique_ptr<CXFA_FMSimpleExpression> expr;
- uint32_t line = m_pToken->m_line_num;
- switch (m_pToken->m_type) {
+ uint32_t line = m_token->m_line_num;
+ switch (m_token->m_type) {
case TOKplus:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
expr = ParseUnaryExpression();
- if (!HasError())
- expr = pdfium::MakeUnique<CXFA_FMPosExpression>(line, std::move(expr));
- else
- expr.reset();
+ if (!expr)
+ return nullptr;
+
+ expr = pdfium::MakeUnique<CXFA_FMPosExpression>(line, std::move(expr));
break;
case TOKminus:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
expr = ParseUnaryExpression();
- if (!HasError())
- expr = pdfium::MakeUnique<CXFA_FMNegExpression>(line, std::move(expr));
- else
- expr.reset();
+ if (!expr)
+ return nullptr;
+
+ expr = pdfium::MakeUnique<CXFA_FMNegExpression>(line, std::move(expr));
break;
case TOKksnot:
- NextToken();
+ if (!NextToken())
+ return nullptr;
+
expr = ParseUnaryExpression();
- if (!HasError())
- expr = pdfium::MakeUnique<CXFA_FMNotExpression>(line, std::move(expr));
- else
- expr.reset();
+ if (!expr)
+ return nullptr;
+
+ expr = pdfium::MakeUnique<CXFA_FMNotExpression>(line, std::move(expr));
break;
default:
expr = ParsePrimaryExpression();
+ if (!expr)
+ return nullptr;
break;
}
return expr;
@@ -475,29 +576,39 @@ std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParseUnaryExpression() {
std::unique_ptr<CXFA_FMSimpleExpression>
CXFA_FMParse::ParsePrimaryExpression() {
+ if (HasError())
+ return nullptr;
+
std::unique_ptr<CXFA_FMSimpleExpression> expr;
- uint32_t line = m_pToken->m_line_num;
- switch (m_pToken->m_type) {
+ uint32_t line = m_token->m_line_num;
+ switch (m_token->m_type) {
case TOKnumber:
expr =
- pdfium::MakeUnique<CXFA_FMNumberExpression>(line, m_pToken->m_string);
- NextToken();
+ pdfium::MakeUnique<CXFA_FMNumberExpression>(line, m_token->m_string);
+ if (!NextToken())
+ return nullptr;
break;
case TOKstring:
expr =
- pdfium::MakeUnique<CXFA_FMStringExpression>(line, m_pToken->m_string);
- NextToken();
+ pdfium::MakeUnique<CXFA_FMStringExpression>(line, m_token->m_string);
+ if (!NextToken())
+ return nullptr;
break;
case TOKidentifier: {
- CFX_WideStringC wsIdentifier(m_pToken->m_string);
- NextToken();
- if (m_pToken->m_type == TOKlbracket) {
+ CFX_WideStringC wsIdentifier(m_token->m_string);
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type == TOKlbracket) {
std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
- if (s) {
- expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
- line, nullptr, TOKdot, wsIdentifier, std::move(s));
- }
- NextToken();
+ if (!s)
+ return nullptr;
+
+ expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
+ line, nullptr, TOKdot, wsIdentifier, std::move(s));
+ if (!expr)
+ return nullptr;
+ if (!NextToken())
+ return nullptr;
} else {
expr =
pdfium::MakeUnique<CXFA_FMIdentifierExpression>(line, wsIdentifier);
@@ -505,125 +616,139 @@ CXFA_FMParse::ParsePrimaryExpression() {
break;
}
case TOKif:
- expr = pdfium::MakeUnique<CXFA_FMIdentifierExpression>(
- line, m_pToken->m_string);
- NextToken();
+ expr = pdfium::MakeUnique<CXFA_FMIdentifierExpression>(line,
+ m_token->m_string);
+ if (!expr || !NextToken())
+ return nullptr;
break;
case TOKnull:
expr = pdfium::MakeUnique<CXFA_FMNullExpression>(line);
- NextToken();
+ if (!expr || !NextToken())
+ return nullptr;
break;
case TOKlparen:
expr = ParseParenExpression();
+ if (!expr)
+ return nullptr;
break;
default:
- m_ParserError = true;
- NextToken();
- break;
+ m_error = true;
+ return nullptr;
}
expr = ParsePostExpression(std::move(expr));
- if (HasError())
- expr.reset();
+ if (!expr)
+ return nullptr;
return expr;
}
std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParsePostExpression(
std::unique_ptr<CXFA_FMSimpleExpression> expr) {
- uint32_t line = m_pToken->m_line_num;
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
while (1) {
- switch (m_pToken->m_type) {
+ switch (m_token->m_type) {
case TOKlparen: {
- NextToken();
+ if (!NextToken())
+ return nullptr;
std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> expressions;
- if (m_pToken->m_type != TOKrparen) {
- while (m_pToken->m_type != TOKrparen) {
+ if (m_token->m_type != TOKrparen) {
+ while (m_token->m_type != TOKrparen) {
if (std::unique_ptr<CXFA_FMSimpleExpression> expr =
ParseSimpleExpression())
expressions.push_back(std::move(expr));
- if (m_pToken->m_type == TOKcomma) {
- NextToken();
- } else if (m_pToken->m_type == TOKeof ||
- m_pToken->m_type == TOKreserver) {
+ if (m_token->m_type == TOKcomma) {
+ if (!NextToken())
+ return nullptr;
+ } else if (m_token->m_type == TOKeof ||
+ m_token->m_type == TOKreserver) {
break;
}
}
- if (m_pToken->m_type != TOKrparen)
- m_ParserError = true;
- }
- if (!HasError()) {
- expr = pdfium::MakeUnique<CXFA_FMCallExpression>(
- line, std::move(expr), std::move(expressions), false);
- NextToken();
- if (m_pToken->m_type != TOKlbracket)
- continue;
-
- std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
- if (s) {
- expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
- line, std::move(expr), TOKcall, L"", std::move(s));
- } else {
- expr.reset();
+ if (m_token->m_type != TOKrparen) {
+ m_error = true;
+ return nullptr;
}
- } else {
- expr.reset();
}
+ expr = pdfium::MakeUnique<CXFA_FMCallExpression>(
+ line, std::move(expr), std::move(expressions), false);
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKlbracket)
+ continue;
+
+ std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
+ if (!s)
+ return nullptr;
+
+ expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
+ line, std::move(expr), TOKcall, L"", std::move(s));
break;
}
- case TOKdot:
- NextToken();
- if (m_pToken->m_type == TOKidentifier) {
- CFX_WideStringC tempStr = m_pToken->m_string;
- uint32_t tempLine = m_pToken->m_line_num;
- NextToken();
- if (m_pToken->m_type == TOKlparen) {
- std::unique_ptr<CXFA_FMSimpleExpression> pExpCall;
- NextToken();
- std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> expressions;
- if (m_pToken->m_type != TOKrparen) {
- while (m_pToken->m_type != TOKrparen) {
- std::unique_ptr<CXFA_FMSimpleExpression> exp =
- ParseSimpleExpression();
- expressions.push_back(std::move(exp));
- if (m_pToken->m_type == TOKcomma) {
- NextToken();
- } else if (m_pToken->m_type == TOKeof ||
- m_pToken->m_type == TOKreserver) {
- break;
- }
- }
- if (m_pToken->m_type != TOKrparen)
- m_ParserError = true;
- }
- if (!HasError()) {
- std::unique_ptr<CXFA_FMSimpleExpression> pIdentifier =
- pdfium::MakeUnique<CXFA_FMIdentifierExpression>(tempLine,
- tempStr);
- pExpCall = pdfium::MakeUnique<CXFA_FMCallExpression>(
- line, std::move(pIdentifier), std::move(expressions), true);
- expr = pdfium::MakeUnique<CXFA_FMMethodCallExpression>(
- line, std::move(expr), std::move(pExpCall));
- NextToken();
- if (m_pToken->m_type != TOKlbracket)
- continue;
-
- std::unique_ptr<CXFA_FMSimpleExpression> s =
- ParseIndexExpression();
- if (s) {
- expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
- line, std::move(expr), TOKcall, L"", std::move(s));
- } else {
- expr.reset();
+ case TOKdot: {
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKidentifier) {
+ m_error = true;
+ return nullptr;
+ }
+ CFX_WideStringC tempStr = m_token->m_string;
+ uint32_t tempLine = m_token->m_line_num;
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type == TOKlparen) {
+ std::unique_ptr<CXFA_FMSimpleExpression> pExpCall;
+ if (!NextToken())
+ return nullptr;
+
+ std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> expressions;
+ if (m_token->m_type != TOKrparen) {
+ while (m_token->m_type != TOKrparen) {
+ std::unique_ptr<CXFA_FMSimpleExpression> exp =
+ ParseSimpleExpression();
+ if (!exp)
+ return nullptr;
+
+ expressions.push_back(std::move(exp));
+ if (m_token->m_type == TOKcomma) {
+ if (!NextToken())
+ return nullptr;
+ } else if (m_token->m_type == TOKeof ||
+ m_token->m_type == TOKreserver) {
+ break;
}
- } else {
- expr.reset();
}
- } else if (m_pToken->m_type == TOKlbracket) {
- std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
- if (HasError())
+ if (m_token->m_type != TOKrparen) {
+ m_error = true;
return nullptr;
+ }
+ }
+ std::unique_ptr<CXFA_FMSimpleExpression> pIdentifier =
+ pdfium::MakeUnique<CXFA_FMIdentifierExpression>(tempLine,
+ tempStr);
+ pExpCall = pdfium::MakeUnique<CXFA_FMCallExpression>(
+ line, std::move(pIdentifier), std::move(expressions), true);
+ expr = pdfium::MakeUnique<CXFA_FMMethodCallExpression>(
+ line, std::move(expr), std::move(pExpCall));
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKlbracket)
+ continue;
- expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
- tempLine, std::move(expr), TOKdot, tempStr, std::move(s));
+ std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
+ if (!s)
+ return nullptr;
+
+ expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
+ line, std::move(expr), TOKcall, L"", std::move(s));
+ } else if (m_token->m_type == TOKlbracket) {
+ std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
+ if (!s)
+ return nullptr;
+
+ expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
+ tempLine, std::move(expr), TOKdot, tempStr, std::move(s));
} else {
std::unique_ptr<CXFA_FMSimpleExpression> s =
pdfium::MakeUnique<CXFA_FMIndexExpression>(
@@ -632,20 +757,22 @@ std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParsePostExpression(
line, std::move(expr), TOKdot, tempStr, std::move(s));
continue;
}
- } else {
- m_ParserError = true;
- return expr;
}
break;
- case TOKdotdot:
- NextToken();
- if (m_pToken->m_type == TOKidentifier) {
- CFX_WideStringC tempStr = m_pToken->m_string;
- uint32_t tempLine = m_pToken->m_line_num;
- NextToken();
- if (m_pToken->m_type == TOKlbracket) {
+ case TOKdotdot: {
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKidentifier) {
+ m_error = true;
+ return nullptr;
+ }
+ CFX_WideStringC tempStr = m_token->m_string;
+ uint32_t tempLine = m_token->m_line_num;
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type == TOKlbracket) {
std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
- if (HasError())
+ if (!s)
return nullptr;
expr = pdfium::MakeUnique<CXFA_FMDotDotAccessorExpression>(
@@ -658,21 +785,20 @@ std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParsePostExpression(
line, std::move(expr), TOKdotdot, tempStr, std::move(s));
continue;
}
- } else {
- m_ParserError = true;
- return expr;
}
break;
case TOKdotscream: {
- NextToken();
- if (m_pToken->m_type != TOKidentifier) {
- m_ParserError = true;
- return expr;
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKidentifier) {
+ m_error = true;
+ return nullptr;
}
- CFX_WideStringC tempStr = m_pToken->m_string;
- uint32_t tempLine = m_pToken->m_line_num;
- NextToken();
- if (m_pToken->m_type != TOKlbracket) {
+ CFX_WideStringC tempStr = m_token->m_string;
+ uint32_t tempLine = m_token->m_line_num;
+ if (NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKlbracket) {
std::unique_ptr<CXFA_FMSimpleExpression> s =
pdfium::MakeUnique<CXFA_FMIndexExpression>(
tempLine, ACCESSOR_NO_INDEX, nullptr, false);
@@ -681,7 +807,7 @@ std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParsePostExpression(
continue;
}
std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression();
- if (HasError())
+ if (!s)
return nullptr;
expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>(
@@ -699,80 +825,98 @@ std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParsePostExpression(
default:
return expr;
}
- NextToken();
+ if (!NextToken())
+ return nullptr;
}
return expr;
}
std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParseIndexExpression() {
- std::unique_ptr<CXFA_FMSimpleExpression> pExp;
- uint32_t line = m_pToken->m_line_num;
- NextToken();
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
+ if (!NextToken())
+ return nullptr;
+
std::unique_ptr<CXFA_FMSimpleExpression> s;
XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX;
- if (m_pToken->m_type == TOKmul) {
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp;
+ if (m_token->m_type == TOKmul) {
pExp = pdfium::MakeUnique<CXFA_FMIndexExpression>(line, accessorIndex,
std::move(s), true);
- NextToken();
- if (m_pToken->m_type != TOKrbracket) {
- m_ParserError = true;
- pExp.reset();
+ if (!pExp || !NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKrbracket) {
+ m_error = true;
+ return nullptr;
}
return pExp;
}
- if (m_pToken->m_type == TOKplus) {
+ if (m_token->m_type == TOKplus) {
accessorIndex = ACCESSOR_POSITIVE_INDEX;
- NextToken();
- } else if (m_pToken->m_type == TOKminus) {
+ if (!NextToken())
+ return nullptr;
+ } else if (m_token->m_type == TOKminus) {
accessorIndex = ACCESSOR_NEGATIVE_INDEX;
- NextToken();
+ if (!NextToken())
+ return nullptr;
}
s = ParseSimpleExpression();
- if (m_pToken->m_type != TOKrbracket) {
- m_ParserError = true;
- } else {
- pExp = pdfium::MakeUnique<CXFA_FMIndexExpression>(line, accessorIndex,
- std::move(s), false);
+ if (!s)
+ return nullptr;
+ if (m_token->m_type != TOKrbracket) {
+ m_error = true;
+ return nullptr;
}
- return pExp;
+ return pdfium::MakeUnique<CXFA_FMIndexExpression>(line, accessorIndex,
+ std::move(s), false);
}
std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParse::ParseParenExpression() {
- Check(TOKlparen);
+ if (!CheckThenNext(TOKlparen))
+ return nullptr;
- if (m_pToken->m_type == TOKrparen) {
- m_ParserError = true;
- NextToken();
+ if (m_token->m_type == TOKrparen) {
+ m_error = true;
return nullptr;
}
- uint32_t line = m_pToken->m_line_num;
+ uint32_t line = m_token->m_line_num;
std::unique_ptr<CXFA_FMSimpleExpression> pExp1 = ParseLogicalOrExpression();
+ if (!pExp1)
+ return nullptr;
int level = 1;
- while (m_pToken->m_type == TOKassign) {
- NextToken();
+ while (m_token->m_type == TOKassign) {
+ if (!NextToken())
+ return nullptr;
+
std::unique_ptr<CXFA_FMSimpleExpression> pExp2 = ParseLogicalOrExpression();
- if (level++ == kMaxAssignmentChainLength)
- m_ParserError = true;
- if (!HasError()) {
- pExp1 = pdfium::MakeUnique<CXFA_FMAssignExpression>(
- line, TOKassign, std::move(pExp1), std::move(pExp2));
- } else {
- pExp1.reset();
+ if (!pExp2)
+ return nullptr;
+ if (level++ == kMaxAssignmentChainLength) {
+ m_error = true;
+ return nullptr;
}
+
+ pExp1 = pdfium::MakeUnique<CXFA_FMAssignExpression>(
+ line, TOKassign, std::move(pExp1), std::move(pExp2));
}
- Check(TOKrparen);
+ if (!CheckThenNext(TOKrparen))
+ return nullptr;
return pExp1;
}
std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseBlockExpression() {
- uint32_t line = m_pToken->m_line_num;
- std::unique_ptr<CXFA_FMExpression> expr;
- std::vector<std::unique_ptr<CXFA_FMExpression>> expressions;
+ if (HasError())
+ return nullptr;
+ uint32_t line = m_token->m_line_num;
+ std::vector<std::unique_ptr<CXFA_FMExpression>> expressions;
while (1) {
- switch (m_pToken->m_type) {
+ std::unique_ptr<CXFA_FMExpression> expr;
+ switch (m_token->m_type) {
case TOKeof:
case TOKendif:
case TOKelseif:
@@ -785,207 +929,256 @@ std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseBlockExpression() {
break;
case TOKfunc:
expr = ParseFunction();
- if (expr) {
- expressions.push_back(std::move(expr));
- }
+ if (!expr)
+ return nullptr;
+
+ expressions.push_back(std::move(expr));
continue;
default:
expr = ParseExpression();
- if (expr) {
- expressions.push_back(std::move(expr));
- }
+ if (!expr)
+ return nullptr;
+
+ expressions.push_back(std::move(expr));
continue;
}
break;
}
- std::unique_ptr<CXFA_FMBlockExpression> pExp;
- if (!HasError()) {
- pExp = pdfium::MakeUnique<CXFA_FMBlockExpression>(line,
- std::move(expressions));
- }
- return pExp;
+ return pdfium::MakeUnique<CXFA_FMBlockExpression>(line,
+ std::move(expressions));
}
std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseIfExpression() {
- uint32_t line = m_pToken->m_line_num;
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
const wchar_t* pStartPos = m_lexer->GetPos();
- NextToken();
- Check(TOKlparen);
+ if (!NextToken() || !CheckThenNext(TOKlparen))
+ return nullptr;
+
std::unique_ptr<CXFA_FMSimpleExpression> pExpression;
- while (m_pToken->m_type != TOKrparen) {
+ while (m_token->m_type != TOKrparen) {
pExpression = ParseSimpleExpression();
- if (m_pToken->m_type != TOKcomma)
+ if (!pExpression)
+ return nullptr;
+ if (m_token->m_type != TOKcomma)
break;
- NextToken();
+ if (!NextToken())
+ return nullptr;
}
- Check(TOKrparen);
- if (m_pToken->m_type != TOKthen) {
+ if (!CheckThenNext(TOKrparen))
+ return nullptr;
+ if (m_token->m_type != TOKthen) {
m_lexer->SetCurrentLine(line);
auto pNewToken = pdfium::MakeUnique<CXFA_FMToken>(line);
- m_pToken = pNewToken.get();
- m_pToken->m_type = TOKidentifier;
- m_pToken->m_string = L"if";
- m_lexer->SetToken(std::move(pNewToken));
+ m_token = std::move(pNewToken);
+ m_token->m_type = TOKidentifier;
+ m_token->m_string = L"if";
m_lexer->SetPos(pStartPos);
return ParseExpExpression();
}
- Check(TOKthen);
+ if (!CheckThenNext(TOKthen))
+ return nullptr;
+
std::unique_ptr<CXFA_FMExpression> pIfExpression = ParseBlockExpression();
+ if (!pIfExpression)
+ return nullptr;
+
std::unique_ptr<CXFA_FMExpression> pElseExpression;
- switch (m_pToken->m_type) {
+ switch (m_token->m_type) {
case TOKeof:
case TOKendif:
- Check(TOKendif);
+ if (!CheckThenNext(TOKendif))
+ return nullptr;
break;
case TOKif:
pElseExpression = ParseIfExpression();
- Check(TOKendif);
+ if (!pElseExpression || !CheckThenNext(TOKendif))
+ return nullptr;
break;
case TOKelseif:
pElseExpression = ParseIfExpression();
+ if (!pElseExpression)
+ return nullptr;
break;
case TOKelse:
- NextToken();
+ if (!NextToken())
+ return nullptr;
pElseExpression = ParseBlockExpression();
- Check(TOKendif);
+ if (!pElseExpression || !CheckThenNext(TOKendif))
+ return nullptr;
break;
default:
- m_ParserError = true;
- NextToken();
- break;
+ m_error = true;
+ return nullptr;
}
- std::unique_ptr<CXFA_FMIfExpression> pExp;
- if (!HasError()) {
- pExp = pdfium::MakeUnique<CXFA_FMIfExpression>(line, std::move(pExpression),
- std::move(pIfExpression),
- std::move(pElseExpression));
- }
- return pExp;
+ return pdfium::MakeUnique<CXFA_FMIfExpression>(line, std::move(pExpression),
+ std::move(pIfExpression),
+ std::move(pElseExpression));
}
std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseWhileExpression() {
- uint32_t line = m_pToken->m_line_num;
- NextToken();
+ if (HasError())
+ return nullptr;
+
+ uint32_t line = m_token->m_line_num;
+ if (!NextToken())
+ return nullptr;
+
std::unique_ptr<CXFA_FMSimpleExpression> pCondition = ParseParenExpression();
- Check(TOKdo);
+ if (!pCondition || !CheckThenNext(TOKdo))
+ return nullptr;
+
std::unique_ptr<CXFA_FMExpression> pExpression = ParseBlockExpression();
- Check(TOKendwhile);
- std::unique_ptr<CXFA_FMExpression> expr;
- if (!HasError()) {
- expr = pdfium::MakeUnique<CXFA_FMWhileExpression>(
- line, std::move(pCondition), std::move(pExpression));
- }
- return expr;
+ if (!pExpression || !CheckThenNext(TOKendwhile))
+ return nullptr;
+ return pdfium::MakeUnique<CXFA_FMWhileExpression>(line, std::move(pCondition),
+ std::move(pExpression));
}
std::unique_ptr<CXFA_FMSimpleExpression>
CXFA_FMParse::ParseSubassignmentInForExpression() {
- std::unique_ptr<CXFA_FMSimpleExpression> expr;
- switch (m_pToken->m_type) {
- case TOKidentifier:
- expr = ParseSimpleExpression();
- break;
- default:
- m_ParserError = true;
- NextToken();
- break;
+ if (HasError())
+ return nullptr;
+
+ if (m_token->m_type != TOKidentifier) {
+ m_error = true;
+ return nullptr;
}
+ std::unique_ptr<CXFA_FMSimpleExpression> expr = ParseSimpleExpression();
+ if (!expr)
+ return nullptr;
return expr;
}
std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseForExpression() {
+ if (HasError())
+ return nullptr;
+
CFX_WideStringC wsVariant;
- uint32_t line = m_pToken->m_line_num;
- NextToken();
- if (m_pToken->m_type != TOKidentifier)
- m_ParserError = true;
-
- wsVariant = m_pToken->m_string;
- NextToken();
- std::unique_ptr<CXFA_FMSimpleExpression> pAssignment;
- if (m_pToken->m_type == TOKassign) {
- NextToken();
- pAssignment = ParseSimpleExpression();
- } else {
- m_ParserError = true;
+ uint32_t line = m_token->m_line_num;
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKidentifier) {
+ m_error = true;
+ return nullptr;
+ }
+
+ wsVariant = m_token->m_string;
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKassign) {
+ m_error = true;
+ return nullptr;
}
+ if (!NextToken())
+ return nullptr;
+
+ std::unique_ptr<CXFA_FMSimpleExpression> pAssignment =
+ ParseSimpleExpression();
+ if (!pAssignment)
+ return nullptr;
int32_t iDirection = 0;
- if (m_pToken->m_type == TOKupto)
+ if (m_token->m_type == TOKupto) {
iDirection = 1;
- else if (m_pToken->m_type == TOKdownto)
+ } else if (m_token->m_type == TOKdownto) {
iDirection = -1;
- else
- m_ParserError = true;
+ } else {
+ m_error = true;
+ return nullptr;
+ }
+
+ if (!NextToken())
+ return nullptr;
- NextToken();
std::unique_ptr<CXFA_FMSimpleExpression> pAccessor = ParseSimpleExpression();
+ if (!pAccessor)
+ return nullptr;
+
std::unique_ptr<CXFA_FMSimpleExpression> pStep;
- if (m_pToken->m_type == TOKstep) {
- NextToken();
+ if (m_token->m_type == TOKstep) {
+ if (!NextToken())
+ return nullptr;
pStep = ParseSimpleExpression();
+ if (!pStep)
+ return nullptr;
}
- Check(TOKdo);
+ if (!CheckThenNext(TOKdo))
+ return nullptr;
+
std::unique_ptr<CXFA_FMExpression> pList = ParseBlockExpression();
- Check(TOKendfor);
+ if (!pList || !CheckThenNext(TOKendfor))
+ return nullptr;
+
std::unique_ptr<CXFA_FMExpression> expr;
- if (!HasError()) {
- expr = pdfium::MakeUnique<CXFA_FMForExpression>(
- line, wsVariant, std::move(pAssignment), std::move(pAccessor),
- iDirection, std::move(pStep), std::move(pList));
- }
- return expr;
+ if (!expr)
+ return nullptr;
+ return pdfium::MakeUnique<CXFA_FMForExpression>(
+ line, wsVariant, std::move(pAssignment), std::move(pAccessor), iDirection,
+ std::move(pStep), std::move(pList));
}
std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseForeachExpression() {
+ if (HasError())
+ return nullptr;
+
std::unique_ptr<CXFA_FMExpression> expr;
CFX_WideStringC wsIdentifier;
std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> pAccessors;
std::unique_ptr<CXFA_FMExpression> pList;
- uint32_t line = m_pToken->m_line_num;
- NextToken();
- if (m_pToken->m_type != TOKidentifier)
- m_ParserError = true;
-
- wsIdentifier = m_pToken->m_string;
- NextToken();
- Check(TOKin);
- Check(TOKlparen);
- if (m_pToken->m_type == TOKrparen) {
- m_ParserError = true;
- NextToken();
- } else {
- while (m_pToken->m_type != TOKrparen) {
- std::unique_ptr<CXFA_FMSimpleExpression> s = ParseSimpleExpression();
- if (s)
- pAccessors.push_back(std::move(s));
- if (m_pToken->m_type != TOKcomma)
- break;
- NextToken();
- }
- Check(TOKrparen);
+ uint32_t line = m_token->m_line_num;
+ if (!NextToken())
+ return nullptr;
+ if (m_token->m_type != TOKidentifier) {
+ m_error = true;
+ return nullptr;
}
- Check(TOKdo);
- pList = ParseBlockExpression();
- Check(TOKendfor);
- if (!HasError()) {
- expr = pdfium::MakeUnique<CXFA_FMForeachExpression>(
- line, wsIdentifier, std::move(pAccessors), std::move(pList));
+
+ wsIdentifier = m_token->m_string;
+ if (!NextToken() || !CheckThenNext(TOKin) || !CheckThenNext(TOKlparen))
+ return nullptr;
+ if (m_token->m_type == TOKrparen) {
+ m_error = true;
+ return nullptr;
}
- return expr;
+
+ while (m_token->m_type != TOKrparen) {
+ std::unique_ptr<CXFA_FMSimpleExpression> s = ParseSimpleExpression();
+ if (!s)
+ return nullptr;
+
+ pAccessors.push_back(std::move(s));
+ if (m_token->m_type != TOKcomma)
+ break;
+ if (!NextToken())
+ return nullptr;
+ }
+ if (!CheckThenNext(TOKrparen) || !CheckThenNext(TOKdo))
+ return nullptr;
+
+ pList = ParseBlockExpression();
+ if (!pList || !CheckThenNext(TOKendfor))
+ return nullptr;
+ return pdfium::MakeUnique<CXFA_FMForeachExpression>(
+ line, wsIdentifier, std::move(pAccessors), std::move(pList));
}
std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseDoExpression() {
- uint32_t line = m_pToken->m_line_num;
- NextToken();
- std::unique_ptr<CXFA_FMExpression> expr = ParseBlockExpression();
- Check(TOKend);
if (HasError())
return nullptr;
+ uint32_t line = m_token->m_line_num;
+ if (!NextToken())
+ return nullptr;
+
+ std::unique_ptr<CXFA_FMExpression> expr = ParseBlockExpression();
+ if (!expr || !CheckThenNext(TOKend))
+ return nullptr;
return pdfium::MakeUnique<CXFA_FMDoExpression>(line, std::move(expr));
}
bool CXFA_FMParse::HasError() const {
- return m_ParserError || m_lexer->HasError();
+ return m_error || m_token == nullptr;
}
diff --git a/xfa/fxfa/fm2js/cxfa_fmparse.h b/xfa/fxfa/fm2js/cxfa_fmparse.h
index 0f7109135d..7377cc75d7 100644
--- a/xfa/fxfa/fm2js/cxfa_fmparse.h
+++ b/xfa/fxfa/fm2js/cxfa_fmparse.h
@@ -22,8 +22,8 @@ class CXFA_FMParse {
bool HasError() const;
private:
- void NextToken();
- void Check(XFA_FM_TOKEN op);
+ bool NextToken();
+ bool CheckThenNext(XFA_FM_TOKEN op);
std::vector<std::unique_ptr<CXFA_FMExpression>> ParseTopExpression();
std::unique_ptr<CXFA_FMExpression> ParseFunction();
@@ -52,8 +52,8 @@ class CXFA_FMParse {
std::unique_ptr<CXFA_FMSimpleExpression> ParseIndexExpression();
std::unique_ptr<CXFA_FMLexer> m_lexer;
- CXFA_FMToken* m_pToken;
- bool m_ParserError;
+ std::unique_ptr<CXFA_FMToken> m_token;
+ bool m_error;
};
#endif // XFA_FXFA_FM2JS_CXFA_FMPARSE_H_