From 7314af7d04d3fd4f29fff1f0da648944183bd0d0 Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Thu, 27 Jul 2017 14:24:02 -0400 Subject: Rewrite FMLexer to use nullptr for errors This CL rewrites how FMLexer returns errors, instead of having a flag that gets flipped and needs to be checked, it now returns nullptr for NextToken() when an error occurs. The Lexer's behaviour has also been changed to only return nullptr once an error has occurred, instead of advancing the lexing on further calls. FMParse now checks the returned value from the lexer instead of testing the error flag on the parser object. For any operation that might cause the error state of the parser to change, i.e. consuming a token, an error check has been added. In the event this check fails the related function returns nullptr. This will cause the parse to short circuit and exit. BUG=pdfium:814 Change-Id: I669012c4732c18d13009be7cd7bf1ae682950904 Reviewed-on: https://pdfium-review.googlesource.com/8950 Commit-Queue: Ryan Harrison Reviewed-by: (OOO Jul 28 - Aug 8) dsinclair Reviewed-by: Tom Sepez --- xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp | 2 +- xfa/fxfa/fm2js/cxfa_fmlexer.cpp | 136 ++-- xfa/fxfa/fm2js/cxfa_fmlexer.h | 12 +- xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp | 44 +- xfa/fxfa/fm2js/cxfa_fmparse.cpp | 1147 +++++++++++++++++------------- 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 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_FMLexer::NextToken() { + if (m_lexer_error) + return nullptr; + m_token = pdfium::MakeUnique(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(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 NextToken(); void SetCurrentLine(uint32_t line) { m_current_line = line; } - void SetToken(std::unique_ptr 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 token = lexer.NextToken(); EXPECT_EQ(TOKeof, token->m_type); } TEST(CXFA_FMLexerTest, Numbers) { auto lexer = pdfium::MakeUnique(L"-12"); - CXFA_FMToken* token = lexer->NextToken(); + std::unique_ptr 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(L"\"The cat jumped over the fence.\""); - CXFA_FMToken* token = lexer->NextToken(); + std::unique_ptr 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(op[i].op); - CXFA_FMToken* token = lexer->NextToken(); + std::unique_ptr token = lexer->NextToken(); EXPECT_EQ(op[i].token, token->m_type); } } TEST(CXFA_FMLexerTest, Comments) { auto lexer = pdfium::MakeUnique(L"// Empty."); - CXFA_FMToken* token = lexer->NextToken(); + std::unique_ptr token = lexer->NextToken(); EXPECT_EQ(TOKeof, token->m_type); lexer = pdfium::MakeUnique(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(ident); - CXFA_FMToken* token = lexer->NextToken(); + std::unique_ptr 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(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(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(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(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(L" \t\xc\x9\xb"); - CXFA_FMToken* token = lexer->NextToken(); + std::unique_ptr token = lexer->NextToken(); EXPECT_EQ(TOKeof, token->m_type); lexer = pdfium::MakeUnique(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(wsFormcalc); + m_token = m_lexer->NextToken(); } CXFA_FMParse::~CXFA_FMParse() {} std::unique_ptr CXFA_FMParse::Parse() { - NextToken(); - if (HasError()) - return nullptr; - auto expressions = ParseTopExpression(); if (HasError()) return nullptr; @@ -39,93 +35,122 @@ std::unique_ptr 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> CXFA_FMParse::ParseTopExpression() { std::unique_ptr expr; std::vector> 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_FMParse::ParseFunction() { + if (HasError()) + return nullptr; + CFX_WideStringC ident; std::vector arguments; std::vector> 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( line, false, ident, std::move(arguments), std::move(expressions)); } std::unique_ptr CXFA_FMParse::ParseExpression() { + if (HasError()) + return nullptr; + std::unique_ptr 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_FMParse::ParseExpression() { break; case TOKbreak: expr = pdfium::MakeUnique(line); - NextToken(); + if (!NextToken()) + return nullptr; break; case TOKcontinue: expr = pdfium::MakeUnique(line); - NextToken(); + if (!NextToken()) + return nullptr; break; default: - m_ParserError = true; - NextToken(); - break; + m_error = true; + return nullptr; } return expr; } std::unique_ptr 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 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(line, ident, std::move(expr)); } std::unique_ptr 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 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 pExp2 = ParseLogicalOrExpression(); - if (level++ == kMaxAssignmentChainLength) - m_ParserError = true; - if (!HasError()) { - pExp1 = pdfium::MakeUnique( - 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( + line, TOKassign, std::move(pExp1), std::move(pExp2)); } return pExp1; } std::unique_ptr CXFA_FMParse::ParseExpExpression() { - uint32_t line = m_pToken->m_line_num; - std::unique_ptr pExp1 = ParseSimpleExpression(); if (HasError()) return nullptr; + uint32_t line = m_token->m_line_num; + std::unique_ptr pExp1 = ParseSimpleExpression(); + if (!pExp1) + return nullptr; return pdfium::MakeUnique(line, std::move(pExp1)); } std::unique_ptr 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 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 e2( ParseLogicalAndExpression()); - if (!HasError()) { - e1 = pdfium::MakeUnique( - line, TOKor, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + line, TOKor, std::move(e1), std::move(e2)); continue; } default: @@ -248,20 +298,27 @@ CXFA_FMParse::ParseLogicalOrExpression() { std::unique_ptr 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 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 e2 = ParseEqualityExpression(); - if (!HasError()) { - e1 = pdfium::MakeUnique( - line, TOKand, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + line, TOKand, std::move(e1), std::move(e2)); continue; } default: @@ -274,32 +331,39 @@ CXFA_FMParse::ParseLogicalAndExpression() { std::unique_ptr 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 e1 = ParseRelationalExpression(); + if (!e1) + return nullptr; for (;;) { std::unique_ptr 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( - line, TOKeq, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + 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( - line, TOKne, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + line, TOKne, std::move(e1), std::move(e2)); continue; default: break; @@ -311,54 +375,64 @@ CXFA_FMParse::ParseEqualityExpression() { std::unique_ptr 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 e1 = ParseAddtiveExpression(); + if (!e1) + return nullptr; + for (;;) { std::unique_ptr 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( - line, TOKlt, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + 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( - line, TOKgt, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + 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( - line, TOKle, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + 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( - line, TOKge, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + line, TOKge, std::move(e1), std::move(e2)); continue; default: break; @@ -370,30 +444,38 @@ CXFA_FMParse::ParseRelationalExpression() { std::unique_ptr 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 e1 = ParseMultiplicativeExpression(); + if (!e1) + return nullptr; + for (;;) { std::unique_ptr 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( - line, TOKplus, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + line, TOKplus, std::move(e1), std::move(e2)); continue; case TOKminus: - NextToken(); + if (!NextToken()) + return nullptr; + e2 = ParseMultiplicativeExpression(); - if (!HasError()) { - e1 = pdfium::MakeUnique( - line, TOKminus, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + line, TOKminus, std::move(e1), std::move(e2)); continue; default: break; @@ -405,30 +487,38 @@ CXFA_FMParse::ParseAddtiveExpression() { std::unique_ptr 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 e1 = ParseUnaryExpression(); + if (!e1) + return nullptr; + for (;;) { std::unique_ptr 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( - line, TOKmul, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + line, TOKmul, std::move(e1), std::move(e2)); continue; case TOKdiv: - NextToken(); + if (!NextToken()) + return nullptr; + e2 = ParseUnaryExpression(); - if (!HasError()) { - e1 = pdfium::MakeUnique( - line, TOKdiv, std::move(e1), std::move(e2)); - } else { - e1.reset(); - } + if (!e2) + return nullptr; + + e1 = pdfium::MakeUnique( + line, TOKdiv, std::move(e1), std::move(e2)); continue; default: break; @@ -439,35 +529,46 @@ CXFA_FMParse::ParseMultiplicativeExpression() { } std::unique_ptr CXFA_FMParse::ParseUnaryExpression() { + if (HasError()) + return nullptr; + std::unique_ptr 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(line, std::move(expr)); - else - expr.reset(); + if (!expr) + return nullptr; + + expr = pdfium::MakeUnique(line, std::move(expr)); break; case TOKminus: - NextToken(); + if (!NextToken()) + return nullptr; + expr = ParseUnaryExpression(); - if (!HasError()) - expr = pdfium::MakeUnique(line, std::move(expr)); - else - expr.reset(); + if (!expr) + return nullptr; + + expr = pdfium::MakeUnique(line, std::move(expr)); break; case TOKksnot: - NextToken(); + if (!NextToken()) + return nullptr; + expr = ParseUnaryExpression(); - if (!HasError()) - expr = pdfium::MakeUnique(line, std::move(expr)); - else - expr.reset(); + if (!expr) + return nullptr; + + expr = pdfium::MakeUnique(line, std::move(expr)); break; default: expr = ParsePrimaryExpression(); + if (!expr) + return nullptr; break; } return expr; @@ -475,29 +576,39 @@ std::unique_ptr CXFA_FMParse::ParseUnaryExpression() { std::unique_ptr CXFA_FMParse::ParsePrimaryExpression() { + if (HasError()) + return nullptr; + std::unique_ptr 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(line, m_pToken->m_string); - NextToken(); + pdfium::MakeUnique(line, m_token->m_string); + if (!NextToken()) + return nullptr; break; case TOKstring: expr = - pdfium::MakeUnique(line, m_pToken->m_string); - NextToken(); + pdfium::MakeUnique(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 s = ParseIndexExpression(); - if (s) { - expr = pdfium::MakeUnique( - line, nullptr, TOKdot, wsIdentifier, std::move(s)); - } - NextToken(); + if (!s) + return nullptr; + + expr = pdfium::MakeUnique( + line, nullptr, TOKdot, wsIdentifier, std::move(s)); + if (!expr) + return nullptr; + if (!NextToken()) + return nullptr; } else { expr = pdfium::MakeUnique(line, wsIdentifier); @@ -505,125 +616,139 @@ CXFA_FMParse::ParsePrimaryExpression() { break; } case TOKif: - expr = pdfium::MakeUnique( - line, m_pToken->m_string); - NextToken(); + expr = pdfium::MakeUnique(line, + m_token->m_string); + if (!expr || !NextToken()) + return nullptr; break; case TOKnull: expr = pdfium::MakeUnique(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_FMParse::ParsePostExpression( std::unique_ptr 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> 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 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( - line, std::move(expr), std::move(expressions), false); - NextToken(); - if (m_pToken->m_type != TOKlbracket) - continue; - - std::unique_ptr s = ParseIndexExpression(); - if (s) { - expr = pdfium::MakeUnique( - 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( + line, std::move(expr), std::move(expressions), false); + if (!NextToken()) + return nullptr; + if (m_token->m_type != TOKlbracket) + continue; + + std::unique_ptr s = ParseIndexExpression(); + if (!s) + return nullptr; + + expr = pdfium::MakeUnique( + 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 pExpCall; - NextToken(); - std::vector> expressions; - if (m_pToken->m_type != TOKrparen) { - while (m_pToken->m_type != TOKrparen) { - std::unique_ptr 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 pIdentifier = - pdfium::MakeUnique(tempLine, - tempStr); - pExpCall = pdfium::MakeUnique( - line, std::move(pIdentifier), std::move(expressions), true); - expr = pdfium::MakeUnique( - line, std::move(expr), std::move(pExpCall)); - NextToken(); - if (m_pToken->m_type != TOKlbracket) - continue; - - std::unique_ptr s = - ParseIndexExpression(); - if (s) { - expr = pdfium::MakeUnique( - 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 pExpCall; + if (!NextToken()) + return nullptr; + + std::vector> expressions; + if (m_token->m_type != TOKrparen) { + while (m_token->m_type != TOKrparen) { + std::unique_ptr 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 s = ParseIndexExpression(); - if (HasError()) + if (m_token->m_type != TOKrparen) { + m_error = true; return nullptr; + } + } + std::unique_ptr pIdentifier = + pdfium::MakeUnique(tempLine, + tempStr); + pExpCall = pdfium::MakeUnique( + line, std::move(pIdentifier), std::move(expressions), true); + expr = pdfium::MakeUnique( + line, std::move(expr), std::move(pExpCall)); + if (!NextToken()) + return nullptr; + if (m_token->m_type != TOKlbracket) + continue; - expr = pdfium::MakeUnique( - tempLine, std::move(expr), TOKdot, tempStr, std::move(s)); + std::unique_ptr s = ParseIndexExpression(); + if (!s) + return nullptr; + + expr = pdfium::MakeUnique( + line, std::move(expr), TOKcall, L"", std::move(s)); + } else if (m_token->m_type == TOKlbracket) { + std::unique_ptr s = ParseIndexExpression(); + if (!s) + return nullptr; + + expr = pdfium::MakeUnique( + tempLine, std::move(expr), TOKdot, tempStr, std::move(s)); } else { std::unique_ptr s = pdfium::MakeUnique( @@ -632,20 +757,22 @@ std::unique_ptr 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 s = ParseIndexExpression(); - if (HasError()) + if (!s) return nullptr; expr = pdfium::MakeUnique( @@ -658,21 +785,20 @@ std::unique_ptr 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 s = pdfium::MakeUnique( tempLine, ACCESSOR_NO_INDEX, nullptr, false); @@ -681,7 +807,7 @@ std::unique_ptr CXFA_FMParse::ParsePostExpression( continue; } std::unique_ptr s = ParseIndexExpression(); - if (HasError()) + if (!s) return nullptr; expr = pdfium::MakeUnique( @@ -699,80 +825,98 @@ std::unique_ptr CXFA_FMParse::ParsePostExpression( default: return expr; } - NextToken(); + if (!NextToken()) + return nullptr; } return expr; } std::unique_ptr CXFA_FMParse::ParseIndexExpression() { - std::unique_ptr 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 s; XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX; - if (m_pToken->m_type == TOKmul) { + std::unique_ptr pExp; + if (m_token->m_type == TOKmul) { pExp = pdfium::MakeUnique(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(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(line, accessorIndex, + std::move(s), false); } std::unique_ptr 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 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 pExp2 = ParseLogicalOrExpression(); - if (level++ == kMaxAssignmentChainLength) - m_ParserError = true; - if (!HasError()) { - pExp1 = pdfium::MakeUnique( - 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( + line, TOKassign, std::move(pExp1), std::move(pExp2)); } - Check(TOKrparen); + if (!CheckThenNext(TOKrparen)) + return nullptr; return pExp1; } std::unique_ptr CXFA_FMParse::ParseBlockExpression() { - uint32_t line = m_pToken->m_line_num; - std::unique_ptr expr; - std::vector> expressions; + if (HasError()) + return nullptr; + uint32_t line = m_token->m_line_num; + std::vector> expressions; while (1) { - switch (m_pToken->m_type) { + std::unique_ptr expr; + switch (m_token->m_type) { case TOKeof: case TOKendif: case TOKelseif: @@ -785,207 +929,256 @@ std::unique_ptr 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 pExp; - if (!HasError()) { - pExp = pdfium::MakeUnique(line, - std::move(expressions)); - } - return pExp; + return pdfium::MakeUnique(line, + std::move(expressions)); } std::unique_ptr 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 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(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 pIfExpression = ParseBlockExpression(); + if (!pIfExpression) + return nullptr; + std::unique_ptr 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 pExp; - if (!HasError()) { - pExp = pdfium::MakeUnique(line, std::move(pExpression), - std::move(pIfExpression), - std::move(pElseExpression)); - } - return pExp; + return pdfium::MakeUnique(line, std::move(pExpression), + std::move(pIfExpression), + std::move(pElseExpression)); } std::unique_ptr 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 pCondition = ParseParenExpression(); - Check(TOKdo); + if (!pCondition || !CheckThenNext(TOKdo)) + return nullptr; + std::unique_ptr pExpression = ParseBlockExpression(); - Check(TOKendwhile); - std::unique_ptr expr; - if (!HasError()) { - expr = pdfium::MakeUnique( - line, std::move(pCondition), std::move(pExpression)); - } - return expr; + if (!pExpression || !CheckThenNext(TOKendwhile)) + return nullptr; + return pdfium::MakeUnique(line, std::move(pCondition), + std::move(pExpression)); } std::unique_ptr CXFA_FMParse::ParseSubassignmentInForExpression() { - std::unique_ptr 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 expr = ParseSimpleExpression(); + if (!expr) + return nullptr; return expr; } std::unique_ptr 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 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 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 pAccessor = ParseSimpleExpression(); + if (!pAccessor) + return nullptr; + std::unique_ptr 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 pList = ParseBlockExpression(); - Check(TOKendfor); + if (!pList || !CheckThenNext(TOKendfor)) + return nullptr; + std::unique_ptr expr; - if (!HasError()) { - expr = pdfium::MakeUnique( - line, wsVariant, std::move(pAssignment), std::move(pAccessor), - iDirection, std::move(pStep), std::move(pList)); - } - return expr; + if (!expr) + return nullptr; + return pdfium::MakeUnique( + line, wsVariant, std::move(pAssignment), std::move(pAccessor), iDirection, + std::move(pStep), std::move(pList)); } std::unique_ptr CXFA_FMParse::ParseForeachExpression() { + if (HasError()) + return nullptr; + std::unique_ptr expr; CFX_WideStringC wsIdentifier; std::vector> pAccessors; std::unique_ptr 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 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( - 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 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( + line, wsIdentifier, std::move(pAccessors), std::move(pList)); } std::unique_ptr CXFA_FMParse::ParseDoExpression() { - uint32_t line = m_pToken->m_line_num; - NextToken(); - std::unique_ptr expr = ParseBlockExpression(); - Check(TOKend); if (HasError()) return nullptr; + uint32_t line = m_token->m_line_num; + if (!NextToken()) + return nullptr; + + std::unique_ptr expr = ParseBlockExpression(); + if (!expr || !CheckThenNext(TOKend)) + return nullptr; return pdfium::MakeUnique(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> ParseTopExpression(); std::unique_ptr ParseFunction(); @@ -52,8 +52,8 @@ class CXFA_FMParse { std::unique_ptr ParseIndexExpression(); std::unique_ptr m_lexer; - CXFA_FMToken* m_pToken; - bool m_ParserError; + std::unique_ptr m_token; + bool m_error; }; #endif // XFA_FXFA_FM2JS_CXFA_FMPARSE_H_ -- cgit v1.2.3