Fix some issues with CXFA_FMParse/CXFA_FMLexer infinite looping.

The parser did not expect an invalid token in some places, leading to an
infinite loop.

In the lexer, if an invalid string was found, the underlying pointer was
never advanced.

Also cleans some minor stuff along the way:
- Remove nonsensical/useless destructors
- Use unique_ptrs for owned members
- Remove unused members
- Other minor style changes

BUG=587620
R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/1701363003 .
diff --git a/xfa/src/fxfa/src/fm2js/xfa_fmparse.cpp b/xfa/src/fxfa/src/fm2js/xfa_fmparse.cpp
index 9a01267..105c514 100644
--- a/xfa/src/fxfa/src/fm2js/xfa_fmparse.cpp
+++ b/xfa/src/fxfa/src/fm2js/xfa_fmparse.cpp
@@ -5,33 +5,16 @@
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
 #include "xfa_fm2js.h"
-CXFA_FMParse::CXFA_FMParse() {
-  m_pScript = 0;
-  m_uLength = 0;
-  m_pErrorInfo = 0;
-  m_lexer = 0;
-  m_pToken = 0;
-}
-CXFA_FMParse::~CXFA_FMParse() {
-  if (m_lexer) {
-    delete m_lexer;
-  }
-  m_lexer = 0;
-  m_pErrorInfo = 0;
-  m_pScript = 0;
-  m_pToken = 0;
-}
+
+CXFA_FMParse::CXFA_FMParse() : m_pToken(nullptr), m_pErrorInfo(0) {}
+
 int32_t CXFA_FMParse::Init(const CFX_WideStringC& wsFormcalc,
                            CXFA_FMErrorInfo* pErrorInfo) {
-  m_pScript = wsFormcalc.GetPtr();
-  m_uLength = wsFormcalc.GetLength();
   m_pErrorInfo = pErrorInfo;
-  m_lexer = new CXFA_FMLexer(wsFormcalc, m_pErrorInfo);
-  if (m_lexer == 0) {
-    return -1;
-  }
+  m_lexer.reset(new CXFA_FMLexer(wsFormcalc, m_pErrorInfo));
   return 0;
 }
+
 void CXFA_FMParse::NextToken() {
   m_pToken = m_lexer->NextToken();
   while (m_pToken->m_type == TOKreserver) {
@@ -41,6 +24,7 @@
     m_pToken = m_lexer->NextToken();
   }
 }
+
 void CXFA_FMParse::Check(XFA_FM_TOKEN op) {
   if (m_pToken->m_type != op) {
     CFX_WideString ws_TempString = m_pToken->m_wstring;
@@ -49,6 +33,7 @@
   }
   NextToken();
 }
+
 void CXFA_FMParse::Error(FX_DWORD lineNum, XFA_FM_ERRMSG msg, ...) {
   m_pErrorInfo->linenum = lineNum;
   const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg);
@@ -57,25 +42,17 @@
   m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
   va_end(ap);
 }
+
 CFX_PtrArray* CXFA_FMParse::ParseTopExpression() {
   CXFA_FMExpression* e = 0;
   CFX_PtrArray* expression = new CFX_PtrArray();
   while (1) {
-    if (m_pToken->m_type == TOKeof) {
+    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) {
       return expression;
     }
-    if (m_pToken->m_type == TOKendfunc) {
-      return expression;
-    }
-    if (m_pToken->m_type == TOKendif) {
-      return expression;
-    }
-    if (m_pToken->m_type == TOKelseif) {
-      return expression;
-    }
-    if (m_pToken->m_type == TOKelse) {
-      return expression;
-    }
+
     if (m_pToken->m_type == TOKfunc) {
       e = ParseFunction();
       if (e) {
@@ -94,6 +71,7 @@
   }
   return expression;
 }
+
 CXFA_FMExpression* CXFA_FMParse::ParseFunction() {
   CXFA_FMExpression* e = 0;
   CFX_WideStringC ident;
@@ -172,6 +150,7 @@
   }
   return e;
 }
+
 CXFA_FMExpression* CXFA_FMParse::ParseExpression() {
   CXFA_FMExpression* e = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -221,6 +200,7 @@
   }
   return e;
 }
+
 CXFA_FMExpression* CXFA_FMParse::ParseVarExpression() {
   CXFA_FMExpression* e = 0;
   CFX_WideStringC ident;
@@ -246,6 +226,7 @@
   }
   return e;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseSimpleExpression() {
   FX_DWORD line = m_pToken->m_uLinenum;
   CXFA_FMSimpleExpression *pExp1 = 0, *pExp2 = 0;
@@ -262,6 +243,7 @@
   }
   return pExp1;
 }
+
 CXFA_FMExpression* CXFA_FMParse::ParseExpExpression() {
   CXFA_FMExpression* e = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -275,6 +257,7 @@
   }
   return e;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalOrExpression() {
   CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -299,6 +282,7 @@
   }
   return e1;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalAndExpression() {
   CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -323,6 +307,7 @@
   }
   return e1;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseEqualityExpression() {
   CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -358,6 +343,7 @@
   }
   return e1;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseRelationalExpression() {
   CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -415,6 +401,7 @@
   }
   return e1;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseAddtiveExpression() {
   CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -448,6 +435,7 @@
   }
   return e1;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseMultiplicativeExpression() {
   CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -481,6 +469,7 @@
   }
   return e1;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseUnaryExpression() {
   CXFA_FMSimpleExpression* e = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -518,6 +507,7 @@
   }
   return e;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParsePrimaryExpression() {
   CXFA_FMSimpleExpression* e = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -569,6 +559,7 @@
   }
   return e;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParsePostExpression(
     CXFA_FMSimpleExpression* e) {
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -586,7 +577,8 @@
             }
             if (m_pToken->m_type == TOKcomma) {
               NextToken();
-            } else if (m_pToken->m_type == TOKeof) {
+            } else if (m_pToken->m_type == TOKeof ||
+                       m_pToken->m_type == TOKreserver) {
               break;
             }
           }
@@ -641,7 +633,8 @@
                 pArray->Add(exp);
                 if (m_pToken->m_type == TOKcomma) {
                   NextToken();
-                } else if (m_pToken->m_type == TOKeof) {
+                } else if (m_pToken->m_type == TOKeof ||
+                           m_pToken->m_type == TOKreserver) {
                   break;
                 }
               }
@@ -791,6 +784,7 @@
   }
   return e;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseIndexExpression() {
   CXFA_FMSimpleExpression* pExp = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -831,6 +825,7 @@
   }
   return pExp;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseParenExpression() {
   CXFA_FMSimpleExpression *pExp1 = 0, *pExp2 = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
@@ -853,6 +848,7 @@
   }
   return pExp1;
 }
+
 CXFA_FMExpression* CXFA_FMParse::ParseBlockExpression() {
   FX_DWORD line = m_pToken->m_uLinenum;
   CXFA_FMExpression* e = 0;
@@ -867,6 +863,7 @@
       case TOKendfor:
       case TOKend:
       case TOKendfunc:
+      case TOKreserver:
         break;
       case TOKfunc:
         e = ParseFunction();
@@ -900,6 +897,7 @@
   }
   return pExp;
 }
+
 CXFA_FMExpression* CXFA_FMParse::ParseIfExpression() {
   CXFA_FMSimpleExpression* pExpression = 0;
   CXFA_FMExpression* pIfExpression = 0;
@@ -974,6 +972,7 @@
   }
   return pExp;
 }
+
 CXFA_FMExpression* CXFA_FMParse::ParseWhileExpression() {
   CXFA_FMExpression* e = 0;
   CXFA_FMSimpleExpression* pCondition = 0;
@@ -998,6 +997,7 @@
   }
   return e;
 }
+
 CXFA_FMSimpleExpression* CXFA_FMParse::ParseSubassignmentInForExpression() {
   CXFA_FMSimpleExpression* e = 0;
   switch (m_pToken->m_type) {
@@ -1013,6 +1013,7 @@
   }
   return e;
 }
+
 CXFA_FMExpression* CXFA_FMParse::ParseForExpression() {
   CXFA_FMExpression* e = 0;
   CFX_WideStringC wsVariant;
@@ -1075,6 +1076,7 @@
   }
   return e;
 }
+
 CXFA_FMExpression* CXFA_FMParse::ParseForeachExpression() {
   CXFA_FMExpression* e = 0;
   CFX_WideStringC wsIdentifier;
@@ -1136,6 +1138,7 @@
   }
   return e;
 }
+
 CXFA_FMExpression* CXFA_FMParse::ParseDoExpression() {
   CXFA_FMExpression* e = 0;
   FX_DWORD line = m_pToken->m_uLinenum;
diff --git a/xfa/src/fxfa/src/fm2js/xfa_fmparse.h b/xfa/src/fxfa/src/fm2js/xfa_fmparse.h
index 45cd3db..ed950c5 100644
--- a/xfa/src/fxfa/src/fm2js/xfa_fmparse.h
+++ b/xfa/src/fxfa/src/fm2js/xfa_fmparse.h
@@ -6,10 +6,14 @@
 
 #ifndef _XFA_FM_PARSE_H
 #define _XFA_FM_PARSE_H
+
+#include <memory>
+
+#include "xfa/src/fxfa/src/fm2js/xfa_lexer.h"
+
 class CXFA_FMParse {
  public:
   CXFA_FMParse();
-  ~CXFA_FMParse();
   int32_t Init(const CFX_WideStringC& wsFormcalc, CXFA_FMErrorInfo* pErrorInfo);
   void NextToken();
   void Check(XFA_FM_TOKEN op);
@@ -40,10 +44,9 @@
   CXFA_FMSimpleExpression* ParseIndexExpression();
 
  private:
-  const FX_WCHAR* m_pScript;
-  FX_STRSIZE m_uLength;
-  CXFA_FMLexer* m_lexer;
+  std::unique_ptr<CXFA_FMLexer> m_lexer;
   CXFA_FMToken* m_pToken;
   CXFA_FMErrorInfo* m_pErrorInfo;
 };
+
 #endif
diff --git a/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp b/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
index 8ecc85b..957c21b 100644
--- a/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
+++ b/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
@@ -5,6 +5,9 @@
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
 #include "xfa_fm2js.h"
+
+namespace {
+
 struct XFA_FMDChar {
   static const FX_WCHAR* inc(const FX_WCHAR*& p) {
     ++p;
@@ -43,6 +46,7 @@
                                const FX_WCHAR*& pEnd);
   static FX_BOOL isUnicodeAlpha(uint16_t ch);
 };
+
 inline FX_BOOL XFA_FMDChar::isAvalid(const FX_WCHAR* p, FX_BOOL flag) {
   if (*p == 0) {
     return 1;
@@ -58,6 +62,7 @@
   }
   return 0;
 }
+
 inline FX_BOOL XFA_FMDChar::string2number(const FX_WCHAR* s,
                                           FX_DOUBLE* pValue,
                                           const FX_WCHAR*& pEnd) {
@@ -66,6 +71,7 @@
   }
   return 0;
 }
+
 inline FX_BOOL XFA_FMDChar::isUnicodeAlpha(uint16_t ch) {
   if (ch == 0 || ch == 0x0A || ch == 0x0D || ch == 0x09 || ch == 0x0B ||
       ch == 0x0C || ch == 0x20 || ch == '.' || ch == ';' || ch == '"' ||
@@ -73,11 +79,11 @@
       ch == ')' || ch == ']' || ch == '[' || ch == '&' || ch == '|' ||
       ch == '+' || ch == '-' || ch == '*' || ch == '/') {
     return FALSE;
-  } else {
-    return TRUE;
   }
+  return TRUE;
 }
-static XFA_FMKeyword keyWords[] = {
+
+XFA_FMKeyword keyWords[] = {
     {TOKand, 0x00000026, L"&"},
     {TOKlparen, 0x00000028, L"("},
     {TOKrparen, 0x00000029, L")"},
@@ -138,48 +144,30 @@
     {TOKfunc, 0xcdce60ec, L"func"},
     {TOKendif, 0xe0e8fee6, L"endif"},
 };
-static const FX_WORD KEYWORD_START = TOKdo;
-static const FX_WORD KEYWORD_END = TOKendif;
+
+const FX_WORD KEYWORD_START = TOKdo;
+const FX_WORD KEYWORD_END = TOKendif;
+
+}  // namespace
+
 const FX_WCHAR* XFA_FM_KeywordToString(XFA_FM_TOKEN op) {
   return keyWords[op].m_keword;
 }
-CXFA_FMToken::CXFA_FMToken() {
-  m_type = TOKreserver;
-  m_uLinenum = 1;
-  m_pNext = 0;
-}
-CXFA_FMToken::CXFA_FMToken(FX_DWORD uLineNum) {
-  m_type = TOKreserver;
-  m_uLinenum = uLineNum;
-  m_pNext = 0;
-}
-CXFA_FMToken::~CXFA_FMToken() {}
+
+CXFA_FMToken::CXFA_FMToken() : m_type(TOKreserver), m_uLinenum(1) {}
+
+CXFA_FMToken::CXFA_FMToken(FX_DWORD uLineNum)
+    : m_type(TOKreserver), m_uLinenum(uLineNum) {}
+
 CXFA_FMLexer::CXFA_FMLexer(const CFX_WideStringC& wsFormCalc,
-                           CXFA_FMErrorInfo* pErrorInfo) {
-  m_pScript = wsFormCalc.GetPtr();
-  m_uLength = wsFormCalc.GetLength();
-  m_uCurrentLine = 1;
-  m_ptr = m_pScript;
-  m_pToken = 0;
-  m_pErrorInfo = pErrorInfo;
-}
+                           CXFA_FMErrorInfo* pErrorInfo)
+    : m_ptr(wsFormCalc.GetPtr()), m_uCurrentLine(1), m_pErrorInfo(pErrorInfo) {}
+
 CXFA_FMToken* CXFA_FMLexer::NextToken() {
-  CXFA_FMToken* t = 0;
-  if (!m_pToken) {
-    m_pToken = Scan();
-  } else {
-    if (m_pToken->m_pNext) {
-      t = m_pToken->m_pNext;
-      delete m_pToken;
-      m_pToken = t;
-    } else {
-      t = m_pToken;
-      m_pToken = Scan();
-      delete t;
-    }
-  }
-  return m_pToken;
+  m_pToken.reset(Scan());
+  return m_pToken.get();
 }
+
 CXFA_FMToken* CXFA_FMLexer::Scan() {
   uint16_t ch = 0;
   CXFA_FMToken* p = new CXFA_FMToken(m_uCurrentLine);
@@ -217,9 +205,6 @@
         const FX_WCHAR* pTemp = 0;
         p->m_type = TOKstring;
         iRet = String(p, m_ptr, pTemp);
-        if (iRet) {
-          return p;
-        }
         m_ptr = pTemp;
       }
         return p;
@@ -414,6 +399,7 @@
     }
   }
 }
+
 FX_DWORD CXFA_FMLexer::Number(CXFA_FMToken* t,
                               const FX_WCHAR* p,
                               const FX_WCHAR*& pEnd) {
@@ -427,6 +413,7 @@
   t->m_wstring = CFX_WideStringC(p, (pEnd - p));
   return 0;
 }
+
 FX_DWORD CXFA_FMLexer::String(CXFA_FMToken* t,
                               const FX_WCHAR* p,
                               const FX_WCHAR*& pEnd) {
@@ -466,6 +453,7 @@
   t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
   return 0;
 }
+
 FX_DWORD CXFA_FMLexer::Identifiers(CXFA_FMToken* t,
                                    const FX_WCHAR* p,
                                    const FX_WCHAR*& pEnd) {
@@ -500,6 +488,7 @@
   t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
   return 0;
 }
+
 void CXFA_FMLexer::Comment(const FX_WCHAR* p, const FX_WCHAR*& pEnd) {
   unsigned ch = 0;
   XFA_FMDChar::inc(p);
@@ -521,6 +510,7 @@
   }
   pEnd = p;
 }
+
 XFA_FM_TOKEN CXFA_FMLexer::IsKeyword(const CFX_WideStringC& str) {
   int32_t iLength = str.GetLength();
   uint32_t uHash = FX_HashCode_String_GetW(str.GetPtr(), iLength, TRUE);
@@ -540,22 +530,7 @@
   } while (iStart <= iEnd);
   return TOKidentifier;
 }
-CXFA_FMLexer::~CXFA_FMLexer() {
-  m_pScript = 0;
-  m_ptr = m_pScript;
-  if (m_pToken) {
-    CXFA_FMToken* t1 = m_pToken;
-    CXFA_FMToken* t2 = t1->m_pNext;
-    while (t2) {
-      delete t1;
-      t1 = t2;
-      t2 = t2->m_pNext;
-    }
-    delete m_pToken;
-    m_pToken = 0;
-  }
-  m_pErrorInfo = 0;
-}
+
 void CXFA_FMLexer::Error(XFA_FM_ERRMSG msg, ...) {
   m_pErrorInfo->linenum = m_uCurrentLine;
   const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg);
@@ -564,6 +539,7 @@
   m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
   va_end(ap);
 }
+
 FX_BOOL CXFA_FMLexer::HasError() const {
   if (m_pErrorInfo->message.IsEmpty()) {
     return FALSE;
diff --git a/xfa/src/fxfa/src/fm2js/xfa_lexer.h b/xfa/src/fxfa/src/fm2js/xfa_lexer.h
index 85b647e..14b927d 100644
--- a/xfa/src/fxfa/src/fm2js/xfa_lexer.h
+++ b/xfa/src/fxfa/src/fm2js/xfa_lexer.h
@@ -6,6 +6,9 @@
 
 #ifndef _XFA_FM_LEXER_H
 #define _XFA_FM_LEXER_H
+
+#include <memory>
+
 enum XFA_FM_TOKEN {
   TOKand,
   TOKlparen,
@@ -76,26 +79,28 @@
   TOKnumber,
   TOKreserver
 };
+
 struct XFA_FMKeyword {
   XFA_FM_TOKEN m_type;
   uint32_t m_uHash;
   const FX_WCHAR* m_keword;
 };
+
 const FX_WCHAR* XFA_FM_KeywordToString(XFA_FM_TOKEN op);
+
 class CXFA_FMToken {
  public:
   CXFA_FMToken();
-  CXFA_FMToken(FX_DWORD uLineNum);
-  ~CXFA_FMToken();
+  explicit CXFA_FMToken(FX_DWORD uLineNum);
+
   CFX_WideStringC m_wstring;
   XFA_FM_TOKEN m_type;
   FX_DWORD m_uLinenum;
-  CXFA_FMToken* m_pNext;
 };
+
 class CXFA_FMLexer {
  public:
   CXFA_FMLexer(const CFX_WideStringC& wsFormcalc, CXFA_FMErrorInfo* pErrorInfo);
-  ~CXFA_FMLexer();
   CXFA_FMToken* NextToken();
   FX_DWORD Number(CXFA_FMToken* t, const FX_WCHAR* p, const FX_WCHAR*& pEnd);
   FX_DWORD String(CXFA_FMToken* t, const FX_WCHAR* p, const FX_WCHAR*& pEnd);
@@ -106,10 +111,8 @@
   XFA_FM_TOKEN IsKeyword(const CFX_WideStringC& p);
   void SetCurrentLine(FX_DWORD line) { m_uCurrentLine = line; }
   void SetToken(CXFA_FMToken* pToken) {
-    if (m_pToken) {
-      delete m_pToken;
-    }
-    m_pToken = pToken;
+    if (m_pToken.get() != pToken)
+      m_pToken.reset(pToken);
   }
   const FX_WCHAR* SavePos() { return m_ptr; }
   void RestorePos(const FX_WCHAR* pPos) { m_ptr = pPos; }
@@ -118,11 +121,11 @@
 
  protected:
   CXFA_FMToken* Scan();
-  const FX_WCHAR* m_pScript;
+
   const FX_WCHAR* m_ptr;
-  FX_STRSIZE m_uLength;
   FX_DWORD m_uCurrentLine;
-  CXFA_FMToken* m_pToken;
+  std::unique_ptr<CXFA_FMToken> m_pToken;
   CXFA_FMErrorInfo* m_pErrorInfo;
 };
+
 #endif