[formcalc] Handle bad elseif conditionals

This Cl adds checking for the conditionals of if and elseif expressions.
If the conditional fails to parse we should return nullptr. This already
happens by accident in the if() case, but with elseif() conditions we'll
fail the ASSERT in the CXFA_FMIfExpression constructor and crash.

This CL explicitly checks for the expressions and early exists if they
failed to parse.

Bug: chromium:819509
Change-Id: I9a90182c7709c8c4c0d3ae17d6be67cb668c0c6a
Reviewed-on: https://pdfium-review.googlesource.com/28131
Commit-Queue: dsinclair <dsinclair@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/xfa/fxfa/fm2js/cxfa_fmparser.cpp b/xfa/fxfa/fm2js/cxfa_fmparser.cpp
index f000066..20e0fa6 100644
--- a/xfa/fxfa/fm2js/cxfa_fmparser.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmparser.cpp
@@ -911,6 +911,8 @@
     return nullptr;
 
   std::unique_ptr<CXFA_FMSimpleExpression> pCondition = ParseParenExpression();
+  if (!pCondition)
+    return nullptr;
   if (!CheckThenNext(TOKthen))
     return nullptr;
 
@@ -923,6 +925,8 @@
       return nullptr;
 
     auto elseIfCondition = ParseParenExpression();
+    if (!elseIfCondition)
+      return nullptr;
     if (!CheckThenNext(TOKthen))
       return nullptr;
 
@@ -969,6 +973,7 @@
       std::move(pCondition),
       pdfium::MakeUnique<CXFA_FMBlockExpression>(std::move(exprs)));
 }
+
 // For := 'for' Assignment 'upto' Accessor ('step' SimpleExpression)?
 //            'do' ExpressionList 'endfor' |
 //         'for' Assignment 'downto' Accessor ('step' SimpleExpression)?
diff --git a/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp b/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp
index 52de964..5ee27b1 100644
--- a/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp
@@ -218,3 +218,23 @@
   ASSERT_TRUE(ast == nullptr);
   EXPECT_TRUE(parser->HasError());
 }
+
+TEST(CXFA_FMParserTest, ParseBadIfExpression) {
+  const wchar_t input[] = {L"if ( then"};
+
+  auto parser = pdfium::MakeUnique<CXFA_FMParser>(input);
+  std::unique_ptr<CXFA_FMAST> ast = parser->Parse();
+  ASSERT_TRUE(ast == nullptr);
+  EXPECT_TRUE(parser->HasError());
+}
+
+TEST(CXFA_FMParserTest, ParseBadElseIfExpression) {
+  const wchar_t input[] = {
+      L"if ($ ne -1) then\n"
+      L"elseif( then"};
+
+  auto parser = pdfium::MakeUnique<CXFA_FMParser>(input);
+  std::unique_ptr<CXFA_FMAST> ast = parser->Parse();
+  ASSERT_TRUE(ast == nullptr);
+  EXPECT_TRUE(parser->HasError());
+}