diff --git a/lib/core/common.py b/lib/core/common.py
index 982241b4b..63251cc26 100644
--- a/lib/core/common.py
+++ b/lib/core/common.py
@@ -2955,7 +2955,12 @@ def extractErrorMessage(page):
if match:
candidate = htmlUnescape(match.group("result")).replace("
", "\n").strip()
- if candidate and (1.0 * len(re.findall(r"[^A-Za-z,. ]", candidate)) / len(candidate) > MIN_ERROR_PARSING_NON_WRITING_RATIO):
+ # Note: only the generic '(fatal|error|warning|exception): ...' regexes can capture
+ # arbitrary prose, so guard those with the non-writing-char ratio; the specific
+ # DBMS-signature regexes (e.g. MSSQL 'Unclosed quotation mark ...') are definitive and
+ # must not be discarded just because the message happens to read like plain text
+ generic = "(fatal|error|warning|exception)" in regex
+ if candidate and (not generic or 1.0 * len(re.findall(r"[^A-Za-z,. ]", candidate)) / len(candidate) > MIN_ERROR_PARSING_NON_WRITING_RATIO):
retVal = candidate
break
diff --git a/lib/core/settings.py b/lib/core/settings.py
index d13237bcc..d17576fa2 100644
--- a/lib/core/settings.py
+++ b/lib/core/settings.py
@@ -20,7 +20,7 @@ from lib.core.enums import OS
from thirdparty import six
# sqlmap version (...)
-VERSION = "1.10.7.141"
+VERSION = "1.10.7.142"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
diff --git a/tests/test_common.py b/tests/test_common.py
index d26d1090c..be4ad2d61 100644
--- a/tests/test_common.py
+++ b/tests/test_common.py
@@ -1623,6 +1623,16 @@ class TestCommonRegexAndPage(unittest.TestCase):
def test_extract_error_message_none_for_plain(self):
self.assertIsNone(extractErrorMessage("Warning: This is only a dummy foobar test"))
+ def test_extract_error_message_prose_like_dbms_signature(self):
+ # a specific DBMS signature must be extracted even when it reads like plain text (few
+ # non-writing chars) - the non-writing-char ratio guards only the generic keyword regexes
+ page = "Microsoft OLE DB Provider for SQL Server error '80040e14' Unclosed quotation mark after the character string ''."
+ self.assertEqual(extractErrorMessage(page), "Unclosed quotation mark after the character string ''.")
+
+ def test_extract_error_message_generic_prose_still_rejected(self):
+ # the generic '(fatal|error|warning): ...' path must still drop natural-language prose
+ self.assertIsNone(extractErrorMessage("Error: everything is working fine and nothing is wrong here"))
+
def test_extract_error_message_non_string(self):
self.assertIsNone(extractErrorMessage(None))