Minor patches
Some checks failed
/ build (macos-latest, 3.8) (push) Has been cancelled
/ build (ubuntu-latest, pypy-2.7) (push) Has been cancelled
/ build (windows-latest, 3.14) (push) Has been cancelled

This commit is contained in:
Miroslav Štampar 2026-06-15 20:53:14 +02:00
parent ea1f089220
commit 4e2438dc1e
6 changed files with 57 additions and 12 deletions

View file

@ -167,7 +167,7 @@ d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py
b36b085ff1b5797e375c1e2ca3b12c7ab4204f48acd1a1efb075cff8302d9750 lib/core/agent.py
ca3e5ce56cb1cae0a8e815425ab6810068004bffe8861d1037c7c87c0ae02477 lib/core/bigarray.py
1452ffc42657bea207583173de9829dddf4afd9b159c785284e43878de492afb lib/core/common.py
7fc5a845a78e6fb7b1a2fdef2fe529510ac5f2c9fac78de588844b4a8c1504e1 lib/core/common.py
8f1272487e1adfcc8c755a2f56f0c6d21eac5e685a73a9a159482f9dc9142bc5 lib/core/compat.py
742bce10b97034966021ec60c7ac294db4af4fe7893613d63172a02c29f009f8 lib/core/convert.py
c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.py
@ -181,14 +181,14 @@ c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py
914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py
3ec59b5eb336d9808d28496f1cbbad716b4a0e276b5399023142826e460e3fd2 lib/core/optiondict.py
3ff871fe8391952c3ec3bb528ba592a13926c80ca0b68fd322a317f69a651ef7 lib/core/option.py
b61676f0aa44798aaf9be72ff37550e2b78ed6ad3c71fbcad54f8c8bf7b34096 lib/core/option.py
ccc4a717e887652b1fcce073d9409d9c59a3b28548c703a9e453d15845f90cd7 lib/core/patch.py
49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py
03db48f02c3d07a047ddb8fe33a757b6238867352d8ddda2a83e4fec09a98d04 lib/core/readlineng.py
48797d6c34dd9bb8a53f7f3794c85f4288d82a9a1d6be7fcf317d388cb20d4b3 lib/core/replication.py
0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py
888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py
ef64975437d734f34f15026d9fec87eb147999912c187985a2c83c9bb3ffb08e lib/core/settings.py
1a73ece519f93c569f9b0b9b5837213bb20aa8d1fc6be54db240c5b5d9308162 lib/core/settings.py
cd5a66deee8963ba8e7e9af3dd36eb5e8127d4d68698811c29e789655f507f82 lib/core/shell.py
bcb5d8090d5e3e0ef2a586ba09ba80eef0c6d51feb0f611ed25299fbb254f725 lib/core/subprocessng.py
70ea3768f1b3062b22d20644df41c86238157ec80dd43da40545c620714273c6 lib/core/target.py
@ -230,7 +230,7 @@ f522436fbd14bdab090a1d305fcac0361800cb8e36c8cbcb47933298376a71e0 lib/takeover/r
0787f78e6bd9bb21d4267c95c4c99806711bb57c5518485c2e25f10fcf9c41fc lib/takeover/udf.py
23d73af417604dab460b74cdc230896153f018a6c00d144019491053640a172f lib/takeover/web.py
8cc1e226d4150fe8aa1a056e5d32d858ed6444d3d4e2af7fb4bc08f0bbe9d527 lib/takeover/xp_cmdshell.py
09c3759b59bc111712f75b0b1762d195c0da0e0741dd76379546c429e8ed4457 lib/techniques/blind/inference.py
42368a281d4d6f1571da95f2fb67afc43696ecdb6cad9720a178461f861b4fcd lib/techniques/blind/inference.py
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/blind/__init__.py
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/dns/__init__.py
3df9839fb92a81d46b6194d7adacb43f391efb78b071783c132e8d596ecbfaf1 lib/techniques/dns/test.py
@ -589,7 +589,7 @@ caa06fed7323b2bb6d0f2443ce343de94f75bf8ad012c055d5e07741d908ebad tests/test_mis
cde0bea1263ae857561f91ed2bd515e972b716743f017d31b1718a8546c72759 tests/test_pagecontent.py
4bac34af2abddce003756d6776e89b2fda220bb7603ef3761f4f37ee29f9c369 tests/test_payload_marking.py
6bfc8201724078bd9d6d559916ef73c9ff97e19b0f2948f37e588a49b027795f tests/test_payloads_structure.py
5dc46919f971f89a3073118ec00bf420cc9cecf0b072b2f896df2f860e87adec tests/test_property.py
a6d013104601c0414628aff3d8b5b69bee3e6733781d8f8da880457d8b44bd3a tests/test_property.py
5c95e7863190e440234f231864fb1219c35207132762858cc95181c57086bafc tests/test_replication.py
67a5241aeebc20eb1c20cfc490422a59af5179040824e5731bd785db2e6bf750 tests/test_report.py
cec98d72992c0799229a780fa7f0d7f3fb01ec2d708187ce0e4a05c8612f291b tests/test_safe2bin.py

View file

@ -4507,13 +4507,15 @@ def safeCSValue(value):
'"foo, bar"'
>>> safeCSValue('foobar')
'foobar'
>>> safeCSValue('foo\\rbar')
'"foo\\rbar"'
"""
retVal = value
if retVal and isinstance(retVal, six.string_types):
if not (retVal[0] == retVal[-1] == '"'):
if any(_ in retVal for _ in (conf.get("csvDel", defaults.csvDel), '"', '\n')):
if any(_ in retVal for _ in (conf.get("csvDel", defaults.csvDel), '"', '\n', '\r')):
retVal = '"%s"' % retVal.replace('"', '""')
return retVal
@ -5299,9 +5301,38 @@ def splitFields(fields, delimiter=','):
>>> splitFields('foo, bar, max(foo, bar)')
['foo', 'bar', 'max(foo,bar)']
>>> splitFields("a, 'b, c', d")
['a', "'b, c'", 'd']
"""
fields = fields.replace("%s " % delimiter, delimiter)
# collapse "<delimiter> " -> "<delimiter>" but only OUTSIDE quoted string literals, so a
# space inside e.g. 'b, c' survives (the quote handling mirrors zeroDepthSearch)
normalized = []
quote = None
index = 0
while index < len(fields):
char = fields[index]
if quote:
normalized.append(char)
if char == quote:
if index + 1 < len(fields) and fields[index + 1] == quote: # escaped quote (e.g. '')
normalized.append(fields[index + 1])
index += 2
continue
else:
quote = None
elif char in ('"', "'"):
quote = char
normalized.append(char)
elif char == delimiter and index + 1 < len(fields) and fields[index + 1] == ' ':
normalized.append(char) # keep the delimiter, drop the single trailing space
index += 2
continue
else:
normalized.append(char)
index += 1
fields = "".join(normalized)
commas = [-1, len(fields)]
commas.extend(zeroDepthSearch(fields, ','))
commas = sorted(commas)

View file

@ -2074,6 +2074,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.cache.comparison = LRUDict(capacity=256)
kb.cache.encoding = LRUDict(capacity=256)
kb.cache.alphaBoundaries = None
kb.cache.charsetAsciiTbl = None
kb.cache.hashRegex = None
kb.cache.intBoundaries = None
kb.cache.parsedDbms = {}

View file

@ -20,7 +20,7 @@ from lib.core.enums import OS
from thirdparty import six
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.10.6.115"
VERSION = "1.10.6.116"
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)

View file

@ -80,7 +80,10 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
return 0, None
if charsetType is None and conf.charset:
asciiTbl = sorted(set(ord(_) for _ in conf.charset))
# conf.charset is fixed for the whole run; compute the table once, not per bisection() call
if kb.cache.charsetAsciiTbl is None:
kb.cache.charsetAsciiTbl = sorted(set(ord(_) for _ in conf.charset))
asciiTbl = kb.cache.charsetAsciiTbl
else:
asciiTbl = getCharset(charsetType)

View file

@ -220,9 +220,19 @@ class TestRandomHelpers(unittest.TestCase):
class TestSplitterInvariants(unittest.TestCase):
def test_reconstruction(self):
# pure partition identity: rejoining the 0-depth split must reproduce the (space-normalized) input
for_all(self, gen_text, lambda s: u",".join(splitFields(s)) == s.replace(", ", ","), label="split-reconstruct-text")
for_all(self, gen_sql_fields, lambda s: u",".join(splitFields(s)) == s.replace(", ", ","), label="split-reconstruct-sql")
# Faithful partition: rejoining the 0-depth split reconstructs the input modulo the only
# transform splitFields applies - dropping a single space after an unquoted delimiter. So
# nothing other than spaces may be lost/added/reordered. (Space-insensitive so it survives
# the quote-aware normalization: spaces inside 'literals' are kept, comma-trailing ones are
# not; either way no non-space content changes.)
for_all(self, gen_text, lambda s: u",".join(splitFields(s)).replace(u" ", u"") == s.replace(u" ", u""), label="split-reconstruct-text")
for_all(self, gen_sql_fields, lambda s: u",".join(splitFields(s)).replace(u" ", u"") == s.replace(u" ", u""), label="split-reconstruct-sql")
def test_quoted_literal_spaces_preserved(self):
# the I3 contract: a ", " inside a quoted literal must NOT be collapsed (the whole literal
# survives intact as a single field)
for_all(self, lambda r: u"%s, '%s, %s', %s" % (r.choice([u"a", u"id"]), r.choice([u"x", u"p q"]), r.choice([u"y", u"z"]), r.choice([u"b", u"c"])),
lambda s: u"'%s'" % s.split(u"'")[1] in splitFields(s), label="split-quote-preserve")
def test_never_cuts_inside_parens(self):
# on well-formed input no field may carry unbalanced parens (i.e. a split never lands inside a group)