diff options
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp | 2 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmlexer.cpp | 136 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmlexer.h | 12 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp | 44 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmparse.cpp | 1147 | ||||
-rw-r--r-- | xfa/fxfa/fm2js/cxfa_fmparse.h | 8 |
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_ |