From f719c95bee280bad33507b926297623bd10936c6 Mon Sep 17 00:00:00 2001
From: Nguyen Anh Quynh <aquynh@gmail.com>
Date: Sun, 22 May 2016 19:03:54 +0800
Subject: [PATCH] remove assert() from AsmToken::getStringContents()

---
 bindings/nodejs/consts/keystone.js            | 34 +++++-----
 bindings/python/keystone/keystone_const.py    | 34 +++++-----
 .../lib/keystone/keystone_const.rb            | 34 +++++-----
 include/keystone/keystone.h                   |  2 +
 llvm/include/llvm/MC/MCParser/MCAsmLexer.h    | 12 +++-
 llvm/lib/MC/MCParser/AsmParser.cpp            | 67 +++++++++++++++----
 llvm/lib/MC/MCParser/COFFAsmParser.cpp        |  9 ++-
 llvm/lib/MC/MCParser/ELFAsmParser.cpp         |  8 ++-
 .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 10 ++-
 9 files changed, 140 insertions(+), 70 deletions(-)

diff --git a/bindings/nodejs/consts/keystone.js b/bindings/nodejs/consts/keystone.js
index 403275a..5034d6e 100644
--- a/bindings/nodejs/consts/keystone.js
+++ b/bindings/nodejs/consts/keystone.js
@@ -50,22 +50,24 @@ module.exports.ERR_ASM_DIRECTIVE_COMMA = 133
 module.exports.ERR_ASM_DIRECTIVE_RELOC_NAME = 134
 module.exports.ERR_ASM_DIRECTIVE_RELOC_TOKEN = 135
 module.exports.ERR_ASM_DIRECTIVE_FPOINT = 136
-module.exports.ERR_ASM_VARIANT_INVALID = 137
-module.exports.ERR_ASM_EXPR_BRACKET = 138
-module.exports.ERR_ASM_SYMBOL_MODIFIER = 139
-module.exports.ERR_ASM_SYMBOL_REDEFINED = 140
-module.exports.ERR_ASM_SYMBOL_MISSING = 141
-module.exports.ERR_ASM_RPAREN = 142
-module.exports.ERR_ASM_STAT_TOKEN = 143
-module.exports.ERR_ASM_UNSUPPORTED = 144
-module.exports.ERR_ASM_MACRO_TOKEN = 145
-module.exports.ERR_ASM_MACRO_PAREN = 146
-module.exports.ERR_ASM_MACRO_EQU = 147
-module.exports.ERR_ASM_MACRO_ARGS = 148
-module.exports.ERR_ASM_MACRO_LEVELS_EXCEED = 149
-module.exports.ERR_ASM_ESC_BACKSLASH = 150
-module.exports.ERR_ASM_ESC_OCTAL = 151
-module.exports.ERR_ASM_ESC_SEQUENCE = 152
+module.exports.ERR_ASM_DIRECTIVE_MACRO = 137
+module.exports.ERR_ASM_VARIANT_INVALID = 138
+module.exports.ERR_ASM_EXPR_BRACKET = 139
+module.exports.ERR_ASM_SYMBOL_MODIFIER = 140
+module.exports.ERR_ASM_SYMBOL_REDEFINED = 141
+module.exports.ERR_ASM_SYMBOL_MISSING = 142
+module.exports.ERR_ASM_RPAREN = 143
+module.exports.ERR_ASM_STAT_TOKEN = 144
+module.exports.ERR_ASM_UNSUPPORTED = 145
+module.exports.ERR_ASM_MACRO_TOKEN = 146
+module.exports.ERR_ASM_MACRO_PAREN = 147
+module.exports.ERR_ASM_MACRO_EQU = 148
+module.exports.ERR_ASM_MACRO_ARGS = 149
+module.exports.ERR_ASM_MACRO_LEVELS_EXCEED = 150
+module.exports.ERR_ASM_ESC_BACKSLASH = 151
+module.exports.ERR_ASM_ESC_OCTAL = 152
+module.exports.ERR_ASM_ESC_SEQUENCE = 153
+module.exports.ERR_ASM_ESC_STR = 154
 module.exports.ERR_ASM_INVALIDOPERAND = 512
 module.exports.ERR_ASM_MISSINGFEATURE = 513
 module.exports.ERR_ASM_MNEMONICFAIL = 514
diff --git a/bindings/python/keystone/keystone_const.py b/bindings/python/keystone/keystone_const.py
index cb5fc46..16283c1 100644
--- a/bindings/python/keystone/keystone_const.py
+++ b/bindings/python/keystone/keystone_const.py
@@ -50,22 +50,24 @@ KS_ERR_ASM_DIRECTIVE_COMMA = 133
 KS_ERR_ASM_DIRECTIVE_RELOC_NAME = 134
 KS_ERR_ASM_DIRECTIVE_RELOC_TOKEN = 135
 KS_ERR_ASM_DIRECTIVE_FPOINT = 136
-KS_ERR_ASM_VARIANT_INVALID = 137
-KS_ERR_ASM_EXPR_BRACKET = 138
-KS_ERR_ASM_SYMBOL_MODIFIER = 139
-KS_ERR_ASM_SYMBOL_REDEFINED = 140
-KS_ERR_ASM_SYMBOL_MISSING = 141
-KS_ERR_ASM_RPAREN = 142
-KS_ERR_ASM_STAT_TOKEN = 143
-KS_ERR_ASM_UNSUPPORTED = 144
-KS_ERR_ASM_MACRO_TOKEN = 145
-KS_ERR_ASM_MACRO_PAREN = 146
-KS_ERR_ASM_MACRO_EQU = 147
-KS_ERR_ASM_MACRO_ARGS = 148
-KS_ERR_ASM_MACRO_LEVELS_EXCEED = 149
-KS_ERR_ASM_ESC_BACKSLASH = 150
-KS_ERR_ASM_ESC_OCTAL = 151
-KS_ERR_ASM_ESC_SEQUENCE = 152
+KS_ERR_ASM_DIRECTIVE_MACRO = 137
+KS_ERR_ASM_VARIANT_INVALID = 138
+KS_ERR_ASM_EXPR_BRACKET = 139
+KS_ERR_ASM_SYMBOL_MODIFIER = 140
+KS_ERR_ASM_SYMBOL_REDEFINED = 141
+KS_ERR_ASM_SYMBOL_MISSING = 142
+KS_ERR_ASM_RPAREN = 143
+KS_ERR_ASM_STAT_TOKEN = 144
+KS_ERR_ASM_UNSUPPORTED = 145
+KS_ERR_ASM_MACRO_TOKEN = 146
+KS_ERR_ASM_MACRO_PAREN = 147
+KS_ERR_ASM_MACRO_EQU = 148
+KS_ERR_ASM_MACRO_ARGS = 149
+KS_ERR_ASM_MACRO_LEVELS_EXCEED = 150
+KS_ERR_ASM_ESC_BACKSLASH = 151
+KS_ERR_ASM_ESC_OCTAL = 152
+KS_ERR_ASM_ESC_SEQUENCE = 153
+KS_ERR_ASM_ESC_STR = 154
 KS_ERR_ASM_INVALIDOPERAND = 512
 KS_ERR_ASM_MISSINGFEATURE = 513
 KS_ERR_ASM_MNEMONICFAIL = 514
diff --git a/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb b/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb
index fc34754..67622ee 100644
--- a/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb
+++ b/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb
@@ -52,22 +52,24 @@ module Keystone
 	KS_ERR_ASM_DIRECTIVE_RELOC_NAME = 134
 	KS_ERR_ASM_DIRECTIVE_RELOC_TOKEN = 135
 	KS_ERR_ASM_DIRECTIVE_FPOINT = 136
-	KS_ERR_ASM_VARIANT_INVALID = 137
-	KS_ERR_ASM_EXPR_BRACKET = 138
-	KS_ERR_ASM_SYMBOL_MODIFIER = 139
-	KS_ERR_ASM_SYMBOL_REDEFINED = 140
-	KS_ERR_ASM_SYMBOL_MISSING = 141
-	KS_ERR_ASM_RPAREN = 142
-	KS_ERR_ASM_STAT_TOKEN = 143
-	KS_ERR_ASM_UNSUPPORTED = 144
-	KS_ERR_ASM_MACRO_TOKEN = 145
-	KS_ERR_ASM_MACRO_PAREN = 146
-	KS_ERR_ASM_MACRO_EQU = 147
-	KS_ERR_ASM_MACRO_ARGS = 148
-	KS_ERR_ASM_MACRO_LEVELS_EXCEED = 149
-	KS_ERR_ASM_ESC_BACKSLASH = 150
-	KS_ERR_ASM_ESC_OCTAL = 151
-	KS_ERR_ASM_ESC_SEQUENCE = 152
+	KS_ERR_ASM_DIRECTIVE_MACRO = 137
+	KS_ERR_ASM_VARIANT_INVALID = 138
+	KS_ERR_ASM_EXPR_BRACKET = 139
+	KS_ERR_ASM_SYMBOL_MODIFIER = 140
+	KS_ERR_ASM_SYMBOL_REDEFINED = 141
+	KS_ERR_ASM_SYMBOL_MISSING = 142
+	KS_ERR_ASM_RPAREN = 143
+	KS_ERR_ASM_STAT_TOKEN = 144
+	KS_ERR_ASM_UNSUPPORTED = 145
+	KS_ERR_ASM_MACRO_TOKEN = 146
+	KS_ERR_ASM_MACRO_PAREN = 147
+	KS_ERR_ASM_MACRO_EQU = 148
+	KS_ERR_ASM_MACRO_ARGS = 149
+	KS_ERR_ASM_MACRO_LEVELS_EXCEED = 150
+	KS_ERR_ASM_ESC_BACKSLASH = 151
+	KS_ERR_ASM_ESC_OCTAL = 152
+	KS_ERR_ASM_ESC_SEQUENCE = 153
+	KS_ERR_ASM_ESC_STR = 154
 	KS_ERR_ASM_INVALIDOPERAND = 512
 	KS_ERR_ASM_MISSINGFEATURE = 513
 	KS_ERR_ASM_MNEMONICFAIL = 514
diff --git a/include/keystone/keystone.h b/include/keystone/keystone.h
index d1cdbbe..698368b 100644
--- a/include/keystone/keystone.h
+++ b/include/keystone/keystone.h
@@ -106,6 +106,7 @@ typedef enum ks_err {
     KS_ERR_ASM_DIRECTIVE_RELOC_NAME, // expected relocation name in directive
     KS_ERR_ASM_DIRECTIVE_RELOC_TOKEN, // unexpected token in .reloc directive
     KS_ERR_ASM_DIRECTIVE_FPOINT,    // invalid floating point in directive
+    KS_ERR_ASM_DIRECTIVE_MACRO,    // invalid floating point in directive
     KS_ERR_ASM_VARIANT_INVALID, // invalid variant
     KS_ERR_ASM_EXPR_BRACKET,    // brackets expression not supported on this target
     KS_ERR_ASM_SYMBOL_MODIFIER, // unexpected symbol modifier following '@'
@@ -122,6 +123,7 @@ typedef enum ks_err {
     KS_ERR_ASM_ESC_BACKSLASH,   // unexpected backslash at end of escaped string
     KS_ERR_ASM_ESC_OCTAL,       // invalid octal escape sequence  (out of range)
     KS_ERR_ASM_ESC_SEQUENCE,         // invalid escape sequence (unrecognized character)
+    KS_ERR_ASM_ESC_STR,         // broken escape string
 
     // generic input assembly errors - architecture specific
     KS_ERR_ASM_INVALIDOPERAND = KS_ERR_ASM_ARCH,
diff --git a/llvm/include/llvm/MC/MCParser/MCAsmLexer.h b/llvm/include/llvm/MC/MCParser/MCAsmLexer.h
index 55279f4..ca2a88e 100644
--- a/llvm/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/llvm/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -77,8 +77,13 @@ public:
   SMRange getLocRange() const;
 
   /// Get the contents of a string token (without quotes).
-  StringRef getStringContents() const {
-    assert(Kind == String && "This token isn't a string!");
+  StringRef getStringContents(bool &valid) const {
+    //assert(Kind == String && "This token isn't a string!");
+    if (Kind != String) {
+        valid = false;
+        return nullptr;
+    }
+    valid = true;
     return Str.slice(1, Str.size() - 1);
   }
 
@@ -89,7 +94,8 @@ public:
   StringRef getIdentifier() const {
     if (Kind == Identifier)
       return getString();
-    return getStringContents();
+    bool valid;
+    return getStringContents(valid);
   }
 
   /// Get the string for the current token, this includes all characters (for
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 8166362..38db993 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -2044,7 +2044,8 @@ static bool isIdentifierChar(char c) {
 bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
                             ArrayRef<MCAsmMacroParameter> Parameters,
                             ArrayRef<MCAsmMacroArgument> A,
-                            bool EnableAtPseudoVariable, SMLoc L) {
+                            bool EnableAtPseudoVariable, SMLoc L)
+{
   unsigned NParameters = Parameters.size();
   bool HasVararg = NParameters ? Parameters.back().Vararg : false;
   if ((!IsDarwin || NParameters != 0) && NParameters != A.size())
@@ -2142,8 +2143,14 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
             // parsing for varargs.
             if (Token.getKind() != AsmToken::String || VarargParameter)
               OS << Token.getString();
-            else
-              OS << Token.getStringContents();
+            else {
+              bool valid;
+              OS << Token.getStringContents(valid);
+              if (!valid) {
+                  KsError = KS_ERR_ASM_DIRECTIVE_MACRO;
+                  return true;
+              }
+            }
 
           Pos += 1 + Argument.size();
         }
@@ -2536,11 +2543,21 @@ bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) {
   return parseAssignment(Name, allow_redef, true);
 }
 
-bool AsmParser::parseEscapedString(std::string &Data) {
-  assert(getLexer().is(AsmToken::String) && "Unexpected current token!");
+bool AsmParser::parseEscapedString(std::string &Data)
+{
+  if (!getLexer().is(AsmToken::String)) {
+      KsError = KS_ERR_ASM_ESC_STR;
+      return true;
+  }
 
   Data = "";
-  StringRef Str = getTok().getStringContents();
+  bool valid;
+  StringRef Str = getTok().getStringContents(valid);
+  if (!valid) {
+      KsError = KS_ERR_ASM_ESC_STR;
+      return true;
+  }
+
   for (unsigned i = 0, e = Str.size(); i != e; ++i) {
     if (Str[i] != '\\') {
       Data += Str[i];
@@ -4514,7 +4531,8 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
 
 /// parseDirectiveIfeqs
 ///   ::= .ifeqs string1, string2
-bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
+bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual)
+{
   if (Lexer.isNot(AsmToken::String)) {
     if (ExpectEqual)
       TokError("expected string parameter for '.ifeqs' directive");
@@ -4524,7 +4542,13 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
     return true;
   }
 
-  StringRef String1 = getTok().getStringContents();
+  bool valid;
+  StringRef String1 = getTok().getStringContents(valid);
+  if (!valid) {
+      KsError = KS_ERR_ASM_DIRECTIVE_STR;
+      return true;
+  }
+
   Lex();
 
   if (Lexer.isNot(AsmToken::Comma)) {
@@ -4547,7 +4571,12 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
     return true;
   }
 
-  StringRef String2 = getTok().getStringContents();
+  StringRef String2 = getTok().getStringContents(valid);
+  if (!valid) {
+      KsError = KS_ERR_ASM_ESC_BACKSLASH;
+      return true;
+  }
+
   Lex();
 
   TheCondStack.push_back(TheCondState);
@@ -4657,7 +4686,8 @@ bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
 /// parseDirectiveError
 ///   ::= .err
 ///   ::= .error [string]
-bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
+bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage)
+{
   if (!TheCondStack.empty()) {
     if (TheCondStack.back().Ignore) {
       eatToEndOfStatement();
@@ -4676,7 +4706,12 @@ bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
       return true;
     }
 
-    Message = getTok().getStringContents();
+    bool valid;
+    Message = getTok().getStringContents(valid);
+    if (!valid) {
+        KsError = KS_ERR_ASM_DIRECTIVE_STR;
+        return true;
+    }
     Lex();
   }
 
@@ -4686,7 +4721,8 @@ bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
 
 /// parseDirectiveWarning
 ///   ::= .warning [string]
-bool AsmParser::parseDirectiveWarning(SMLoc L) {
+bool AsmParser::parseDirectiveWarning(SMLoc L)
+{
   if (!TheCondStack.empty()) {
     if (TheCondStack.back().Ignore) {
       eatToEndOfStatement();
@@ -4702,7 +4738,12 @@ bool AsmParser::parseDirectiveWarning(SMLoc L) {
       return true;
     }
 
-    Message = getTok().getStringContents();
+    bool valid;
+    Message = getTok().getStringContents(valid);
+    if (!valid) {
+        KsError = KS_ERR_ASM_DIRECTIVE_STR;
+        return true;
+    }
     Lex();
   }
 
diff --git a/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/llvm/lib/MC/MCParser/COFFAsmParser.cpp
index 2116e65..6e90435 100644
--- a/llvm/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/COFFAsmParser.cpp
@@ -334,7 +334,8 @@ bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
 //   y: Not-readable section (clears 'r')
 //
 // Subsections are not supported.
-bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
+bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc)
+{
   StringRef SectionName;
 
   if (ParseSectionName(SectionName))
@@ -350,7 +351,11 @@ bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
     if (getLexer().isNot(AsmToken::String))
       return TokError("expected string in directive");
 
-    StringRef FlagsStr = getTok().getStringContents();
+    bool valid;
+    StringRef FlagsStr = getTok().getStringContents(valid);
+    if (!valid)
+        return true;
+
     Lex();
 
     if (ParseSectionFlags(FlagsStr, &Flags))
diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index 6cbcdec..97461ee 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -356,7 +356,8 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
   return ParseSectionArguments(/*IsPush=*/false, loc);
 }
 
-bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
+bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc)
+{
   StringRef SectionName;
 
   if (ParseSectionName(SectionName))
@@ -397,7 +398,10 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
         return TokError("expected string in directive");
       extraFlags = parseSunStyleSectionFlags();
     } else {
-      StringRef FlagsStr = getTok().getStringContents();
+      bool valid;
+      StringRef FlagsStr = getTok().getStringContents(valid);
+      if (!valid)
+          return true;
       Lex();
       extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
     }
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index f0cbb64..b700aaf 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -9152,7 +9152,8 @@ bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
 /// parseDirectiveEabiAttr
 ///  ::= .eabi_attribute int, int [, "str"]
 ///  ::= .eabi_attribute Tag_name, int [, "str"]
-bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
+bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L)
+{
   MCAsmParser &Parser = getParser();
   int64_t Tag;
   SMLoc TagLoc;
@@ -9247,7 +9248,12 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
       return false;
     }
 
-    StringValue = Parser.getTok().getStringContents();
+    bool valid;
+    StringValue = Parser.getTok().getStringContents(valid);
+    if (!valid) {
+        //KsError = KS_ERR_ASM_DIRECTIVE_STR;
+        return true;
+    }
     Parser.Lex();
   }
 
-- 
GitLab