Minor patch

This commit is contained in:
Miroslav Štampar 2026-07-08 11:14:34 +02:00
parent 89ddc5a592
commit e2c55c1ddc
3 changed files with 32 additions and 5 deletions

View file

@ -20,7 +20,7 @@ from lib.core.enums import OS
from thirdparty import six from thirdparty import six
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.10.7.38" VERSION = "1.10.7.39"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} 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) VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

View file

@ -760,6 +760,17 @@ class Connect(object):
warnMsg = "problem occurred during connection closing ('%s')" % getSafeExString(ex) warnMsg = "problem occurred during connection closing ('%s')" % getSafeExString(ex)
logger.warning(warnMsg) logger.warning(warnMsg)
# Keep-alive: dispose the response explicitly. Its wrapped close() hands the socket
# back to the pool when the body was fully drained, otherwise drops it (a size-capped
# partial read must not be reused). This avoids leaning on GC to reclaim it (delayed on
# non-refcounting runtimes like PyPy). Guarded by the handler's marker so the HTTP/2
# reuse pool is left untouched.
elif conn is not None and getattr(conn, "_keepaliveManaged", False):
try:
conn.close()
except Exception:
pass
except SqlmapConnectionException as ex: except SqlmapConnectionException as ex:
if conf.proxyList and not kb.threadException: if conf.proxyList and not kb.threadException:
warnMsg = "unable to connect to the target URL ('%s')" % getSafeExString(ex) warnMsg = "unable to connect to the target URL ('%s')" % getSafeExString(ex)

View file

@ -185,7 +185,11 @@ class _KeepAliveHandler(object):
a connection is never reused. a connection is never reused.
""" """
state = {"handled": False} # 'eof' is raised only on a genuine end-of-body (observed while reading), never
# merely because close() nulled the file object; the socket is handed back to the
# pool solely on that signal, so a half-read response can never be reused (which
# would splice its leftover bytes onto the next request - response desynchronization)
state = {"handled": False, "reading": False, "eof": False}
_read = response.read _read = response.read
_close = response.close _close = response.close
@ -200,7 +204,7 @@ class _KeepAliveHandler(object):
def settle(): def settle():
# Once (and only once) the body is fully drained, decide the socket's fate # Once (and only once) the body is fully drained, decide the socket's fate
if state["handled"] or not drained(): if state["handled"] or not state["eof"]:
return return
state["handled"] = True state["handled"] = True
if keep: if keep:
@ -212,12 +216,23 @@ class _KeepAliveHandler(object):
pass pass
def read(*args, **kwargs): def read(*args, **kwargs):
data = _read(*args, **kwargs) state["reading"] = True
try:
data = _read(*args, **kwargs)
finally:
state["reading"] = False
if drained():
state["eof"] = True
settle() settle()
return data return data
def close(): def close():
# Note: on Python 2 httplib.read() calls close() itself upon EOF # Note: on Python 2 httplib.read() calls close() itself upon EOF, i.e. from inside
# our read(); such an in-read close marks a real end-of-body. An external close()
# on a not-yet-drained body means the caller abandoned it (e.g. sqlmap hitting a
# size cap), so the socket must be dropped rather than returned to the pool.
if state["reading"]:
state["eof"] = True
_close() _close()
settle() settle()
if not state["handled"]: if not state["handled"]:
@ -228,6 +243,7 @@ class _KeepAliveHandler(object):
except Exception: except Exception:
pass pass
response._keepaliveManaged = True
response.read = read response.read = read
response.close = close response.close = close