diff options
author | Ryan Harrison <rharrison@chromium.org> | 2017-07-27 14:24:02 -0400 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-07-27 18:38:09 +0000 |
commit | 7314af7d04d3fd4f29fff1f0da648944183bd0d0 (patch) | |
tree | 4048c996e6c1db9d1eb31d22cb91c46ede2e8e70 | |
parent | 495d89ff20806b6acdf564f3865b1fb974ccf44a (diff) | |
download | pdfium-7314af7d04d3fd4f29fff1f0da648944183bd0d0.tar.xz |
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 <rharrison@chromium.org>
Reviewed-by: (OOO Jul 28 - Aug 8) dsinclair <dsinclair@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
-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_ |