From 6234b62c6fa11f46856d2754711014753339342c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Sun, 19 Jul 2026 18:54:15 +0200 Subject: [PATCH] Minor patch --- lib/core/common.py | 7 ++++++- lib/core/settings.py | 2 +- tests/test_common.py | 10 ++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) 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))