mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-07-03 06:51:08 +00:00
Minor optimization
This commit is contained in:
parent
d6b491dec4
commit
154c7e333e
4 changed files with 75 additions and 54 deletions
|
|
@ -170,13 +170,13 @@ d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller
|
|||
c51c33501cc905586a9aaac93b06f2ac6f71628d032a7dc39fd0ef05d7ee3856 lib/core/bigarray.py
|
||||
d143df718fbaacb617b6046c73cf4e47932e1a25928a4e1ecb87ea77a3b154ed lib/core/common.py
|
||||
8f1272487e1adfcc8c755a2f56f0c6d21eac5e685a73a9a159482f9dc9142bc5 lib/core/compat.py
|
||||
a683d0ad9ba543587382c4903d28db610ae20394fcf9045a68b2ab54a39381ae lib/core/convert.py
|
||||
5301ba2204404d086e9a67271cde00fc10214c63b018a95fc5aa90ff9e0b2ad9 lib/core/convert.py
|
||||
c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.py
|
||||
d9ec034a6d51ab4ddde0b6aa7ed306f9e0b1336557f77d7939ba547600f9b3ae lib/core/datatype.py
|
||||
f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decorators.py
|
||||
147823c37596bd6a56d677697781f34b8d1d1671d5a2518fbc9468d623c6d07d lib/core/defaults.py
|
||||
8e4f4b5ea37a49d445bb0df83bf04b34f61035ec33fd8acf598ebcf371cb19a7 lib/core/dicts.py
|
||||
854073f899b876ab13b36e93e174b9cfe51408f7343040197a80afd9fc9c65ee lib/core/dump.py
|
||||
10d8bb671a64cc787fc2fbf2c641560b7797fccd62c4792e55dffe5efab9f544 lib/core/dump.py
|
||||
6dd47f52082e98dc0cda6969b277b7d81c6f7c68dac4688821f873a1c65c6edf lib/core/enums.py
|
||||
5387168e5dfedd94ae22af7bb255f27d6baaca50b24179c6b98f4f325f5cc7b4 lib/core/exception.py
|
||||
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py
|
||||
|
|
@ -189,7 +189,7 @@ f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decor
|
|||
9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py
|
||||
0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py
|
||||
888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py
|
||||
4d9cc21e2b2a10fd6c06ce6c9b248fd16a4c266511cd01156bbe7643e5327a89 lib/core/settings.py
|
||||
516d6b40efa04a5a25b0aa317ea49771f6964a57581777761f82d36d1b1b78b0 lib/core/settings.py
|
||||
c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py
|
||||
a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py
|
||||
19f1e3c5e3ba703d28d510cd7a9ab8284d5fbe9df5ce7e77c86e5931571364b7 lib/core/target.py
|
||||
|
|
|
|||
|
|
@ -464,6 +464,9 @@ def stdoutEncode(value):
|
|||
|
||||
return retVal
|
||||
|
||||
# str.isascii() is available on Python 3.7+ only (sqlmap still supports 2.7)
|
||||
_HAS_ISASCII = hasattr(str, "isascii")
|
||||
|
||||
def getConsoleLength(value):
|
||||
"""
|
||||
Returns console width of unicode values
|
||||
|
|
@ -475,7 +478,15 @@ def getConsoleLength(value):
|
|||
"""
|
||||
|
||||
if isinstance(value, six.text_type):
|
||||
retVal = len(value) + sum(ord(_) >= 0x3000 for _ in value)
|
||||
# Fast path: ASCII values have no wide (>= U+3000) characters, so their
|
||||
# console width is simply their length. str.isascii() (Python 3.7+) is a
|
||||
# C-level scan, far cheaper than the per-character generator below (which
|
||||
# stays for the rare wide-character case and for Python 2). This runs
|
||||
# once per dumped cell, so it dominates large table dumps.
|
||||
if _HAS_ISASCII and value.isascii():
|
||||
retVal = len(value)
|
||||
else:
|
||||
retVal = len(value) + sum(ord(_) >= 0x3000 for _ in value)
|
||||
else:
|
||||
retVal = len(value)
|
||||
|
||||
|
|
|
|||
108
lib/core/dump.py
108
lib/core/dump.py
|
|
@ -627,11 +627,25 @@ class Dump(object):
|
|||
elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
|
||||
rtable.beginTransaction()
|
||||
|
||||
# Precompute the per-column layout once. These values are invariant across
|
||||
# every row, so resolving them per cell (dict lookup, int() conversion and
|
||||
# identifier normalization) wasted count x ncols work on large dumps.
|
||||
dumpColumns = []
|
||||
for column in columns:
|
||||
if column != "__infos__":
|
||||
info = tableValues[column]
|
||||
dumpColumns.append((unsafeSQLIdentificatorNaming(column), info["values"], int(info["length"])))
|
||||
|
||||
for i in xrange(count):
|
||||
console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
|
||||
field = 1
|
||||
values = []
|
||||
record = OrderedDict()
|
||||
|
||||
# Only the SQLITE and JSONL paths accumulate a per-row container; the
|
||||
# others left these unused, wasting an allocation on every single row
|
||||
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
|
||||
values = []
|
||||
elif conf.dumpFormat == DUMP_FORMAT.JSONL:
|
||||
record = OrderedDict()
|
||||
|
||||
if i == 0 and count > TRIM_STDOUT_DUMP_SIZE:
|
||||
self._write(" ...")
|
||||
|
|
@ -639,62 +653,58 @@ class Dump(object):
|
|||
if conf.dumpFormat == DUMP_FORMAT.HTML:
|
||||
dataToDumpFile(dumpFP, "<tr>")
|
||||
|
||||
for column in columns:
|
||||
if column != "__infos__":
|
||||
info = tableValues[column]
|
||||
for safeColumn, colValues, maxlength in dumpColumns:
|
||||
if len(colValues) <= i or colValues[i] is None:
|
||||
value = u''
|
||||
else:
|
||||
value = getUnicode(colValues[i])
|
||||
value = DUMP_REPLACEMENTS.get(value, value)
|
||||
|
||||
if len(info["values"]) <= i or info["values"][i] is None:
|
||||
value = u''
|
||||
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
|
||||
# Note: store a real NULL for the NULL sentinel (and the raw value otherwise),
|
||||
# mirroring the JSONL path below; appending the display-replaced 'NULL'/'<blank>'
|
||||
# text would corrupt the INTEGER/REAL-typed columns inferred above
|
||||
if len(colValues) <= i or colValues[i] is None or colValues[i] == " ": # NULL
|
||||
values.append(None)
|
||||
else:
|
||||
value = getUnicode(info["values"][i])
|
||||
value = DUMP_REPLACEMENTS.get(value, value)
|
||||
values.append(getUnicode(colValues[i]))
|
||||
|
||||
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
|
||||
# Note: store a real NULL for the NULL sentinel (and the raw value otherwise),
|
||||
# mirroring the JSONL path below; appending the display-replaced 'NULL'/'<blank>'
|
||||
# text would corrupt the INTEGER/REAL-typed columns inferred above
|
||||
if len(info["values"]) <= i or info["values"][i] is None or info["values"][i] == " ": # NULL
|
||||
values.append(None)
|
||||
else:
|
||||
values.append(getUnicode(info["values"][i]))
|
||||
blank = " " * (maxlength - getConsoleLength(value))
|
||||
self._write("| %s%s" % (value, blank), newline=False, console=console)
|
||||
|
||||
maxlength = int(info["length"])
|
||||
blank = " " * (maxlength - getConsoleLength(value))
|
||||
self._write("| %s%s" % (value, blank), newline=False, console=console)
|
||||
if len(value) > MIN_BINARY_DISK_DUMP_SIZE and r'\x' in value:
|
||||
try:
|
||||
mimetype = getText(magic.from_buffer(getBytes(value), mime=True))
|
||||
if any(mimetype.startswith(_) for _ in ("application", "image")):
|
||||
if not os.path.isdir(dumpDbPath):
|
||||
os.makedirs(dumpDbPath)
|
||||
|
||||
if len(value) > MIN_BINARY_DISK_DUMP_SIZE and r'\x' in value:
|
||||
try:
|
||||
mimetype = getText(magic.from_buffer(getBytes(value), mime=True))
|
||||
if any(mimetype.startswith(_) for _ in ("application", "image")):
|
||||
if not os.path.isdir(dumpDbPath):
|
||||
os.makedirs(dumpDbPath)
|
||||
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(safeColumn))
|
||||
filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (_, randomInt(8)))
|
||||
warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
|
||||
logger.warning(warnMsg)
|
||||
|
||||
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(column)))
|
||||
filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (_, randomInt(8)))
|
||||
warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
|
||||
logger.warning(warnMsg)
|
||||
with openFile(filepath, "w+b", None) as f:
|
||||
_ = safechardecode(value, True)
|
||||
f.write(_)
|
||||
|
||||
with openFile(filepath, "w+b", None) as f:
|
||||
_ = safechardecode(value, True)
|
||||
f.write(_)
|
||||
except Exception as ex:
|
||||
logger.debug(getSafeExString(ex))
|
||||
|
||||
except Exception as ex:
|
||||
logger.debug(getSafeExString(ex))
|
||||
if conf.dumpFormat == DUMP_FORMAT.CSV:
|
||||
if field == fields:
|
||||
dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
|
||||
else:
|
||||
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
|
||||
elif conf.dumpFormat == DUMP_FORMAT.HTML:
|
||||
dataToDumpFile(dumpFP, "<td>%s</td>" % getUnicode(htmlEscape(value).encode("ascii", "xmlcharrefreplace")))
|
||||
elif conf.dumpFormat == DUMP_FORMAT.JSONL:
|
||||
if len(colValues) <= i or colValues[i] is None or colValues[i] == " ": # NULL
|
||||
record[safeColumn] = None
|
||||
else:
|
||||
record[safeColumn] = getUnicode(colValues[i])
|
||||
|
||||
if conf.dumpFormat == DUMP_FORMAT.CSV:
|
||||
if field == fields:
|
||||
dataToDumpFile(dumpFP, "%s" % safeCSValue(value))
|
||||
else:
|
||||
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
|
||||
elif conf.dumpFormat == DUMP_FORMAT.HTML:
|
||||
dataToDumpFile(dumpFP, "<td>%s</td>" % getUnicode(htmlEscape(value).encode("ascii", "xmlcharrefreplace")))
|
||||
elif conf.dumpFormat == DUMP_FORMAT.JSONL:
|
||||
if len(info["values"]) <= i or info["values"][i] is None or info["values"][i] == " ": # NULL
|
||||
record[unsafeSQLIdentificatorNaming(column)] = None
|
||||
else:
|
||||
record[unsafeSQLIdentificatorNaming(column)] = getUnicode(info["values"][i])
|
||||
|
||||
field += 1
|
||||
field += 1
|
||||
|
||||
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -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.201"
|
||||
VERSION = "1.10.7.0"
|
||||
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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue