diff --git a/bindings/nodejs/consts/keystone.js b/bindings/nodejs/consts/keystone.js
index 403275a6dc9480f20cad07248b339c0e3348c3fa..5034d6e64725df8a7baaf4d2b93ed43b7d5068ba 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 cb5fc4621e8556c2a0aad46d4c35b3f78cba3115..16283c1aef9af8ac197cefcf4e8cd2355eb3bfe4 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 fc34754b973b03234638678b309bf2e751f05c4a..67622ee5a99ea278259e912145a2713ff3faf011 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 d1cdbbe82d125dcfeb787907aec33513e5e73f36..698368b2c1ab75cefade718f1aeda0b6485e4ab0 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 55279f49529af91046f671d337227f69908e3a8f..ca2a88e20a767f683bf28292c15decdfa6154adf 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 8166362157719ef3c988f32b978bbc4031da8f46..38db993bcaa48d0e6008d17ff29eb5c27ed541c5 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 2116e6532fbc3c75633ed9bad084ef5b296ba4cf..6e90435ee937953fd585330d8c1ddcbd0b56613e 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 6cbcdec5e275f569d5bad408285c0cdc8a865ff7..97461eed4b70bc414d94806f438b680af28cb9a3 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 f0cbb64f9c7477bfa2352c72377542d25e0fc7e3..b700aaf9933ba6aa125cac671849df40aa1bbb6e 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();
   }