mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-08-28 04:33:16 +00:00
Adding unit tests
This commit is contained in:
parent
48b915b5ee
commit
3816df1241
39 changed files with 3501 additions and 2 deletions
129
tests/test_hashdb.py
Normal file
129
tests/test_hashdb.py
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
|
||||
See the file 'LICENSE' for copying permission
|
||||
|
||||
Session storage layer (lib/utils/hashdb.py) - the on-disk SQLite cache that
|
||||
makes --flush-session / resume work.
|
||||
|
||||
Exercised against a REAL temporary SQLite file (no network, no DBMS): scalar
|
||||
write/retrieve, serialized round-trip for every container type sqlmap stores,
|
||||
overwrite semantics, missing-key -> None, and key-hash determinism.
|
||||
|
||||
This is also the end-to-end regression for the base64-pickle bytes fix: a
|
||||
serialized value containing raw `bytes` must survive a write/flush/retrieve
|
||||
cycle on both Python 2 and 3 (it silently failed on py3 before the patch.py fix).
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from _testutils import bootstrap
|
||||
bootstrap()
|
||||
|
||||
from lib.utils.hashdb import HashDB
|
||||
from lib.core.datatype import AttribDict
|
||||
from lib.core.bigarray import BigArray
|
||||
|
||||
|
||||
class _HashDBCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
fd, self.path = tempfile.mkstemp(suffix=".sqlite")
|
||||
os.close(fd)
|
||||
os.remove(self.path) # HashDB creates it lazily
|
||||
self.db = HashDB(self.path)
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
self.db.closeAll()
|
||||
except Exception:
|
||||
pass
|
||||
if os.path.exists(self.path):
|
||||
os.remove(self.path)
|
||||
|
||||
|
||||
class TestScalar(_HashDBCase):
|
||||
def test_string_roundtrip(self):
|
||||
self.db.write("greeting", "hello")
|
||||
self.db.flush()
|
||||
self.assertEqual(self.db.retrieve("greeting"), "hello")
|
||||
|
||||
def test_non_serialized_number_comes_back_as_text(self):
|
||||
# non-serialized writes are stored via getUnicode()
|
||||
self.db.write("num", 5)
|
||||
self.db.flush()
|
||||
self.assertEqual(self.db.retrieve("num"), "5")
|
||||
|
||||
def test_missing_key_is_none(self):
|
||||
self.assertIsNone(self.db.retrieve("never-written"))
|
||||
|
||||
def test_overwrite_last_wins(self):
|
||||
self.db.write("k", "v1")
|
||||
self.db.write("k", "v2")
|
||||
self.db.flush()
|
||||
self.assertEqual(self.db.retrieve("k"), "v2")
|
||||
|
||||
def test_keys_are_independent(self):
|
||||
self.db.write("a", "1")
|
||||
self.db.write("b", "2")
|
||||
self.db.flush()
|
||||
self.assertEqual(self.db.retrieve("a"), "1")
|
||||
self.assertEqual(self.db.retrieve("b"), "2")
|
||||
|
||||
|
||||
class TestSerialized(_HashDBCase):
|
||||
def test_list_dict_tuple_set(self):
|
||||
cases = {
|
||||
"list": [1, 2, 3, "x"],
|
||||
"dict": {"k": [1, {"n": "v"}]},
|
||||
"tuple": (1, "a", None),
|
||||
"set": set([1, 2, 3]),
|
||||
}
|
||||
for key, val in cases.items():
|
||||
self.db.write(key, val, True)
|
||||
self.db.flush()
|
||||
for key, val in cases.items():
|
||||
self.assertEqual(self.db.retrieve(key, True), val, msg="serialized round-trip for %s" % key)
|
||||
|
||||
def test_attribdict_roundtrip(self):
|
||||
ad = AttribDict()
|
||||
ad.x = 1
|
||||
ad.y = [1, 2]
|
||||
self.db.write("ad", ad, True)
|
||||
self.db.flush()
|
||||
got = self.db.retrieve("ad", True)
|
||||
self.assertIsInstance(got, AttribDict)
|
||||
self.assertEqual(got.x, 1)
|
||||
self.assertEqual(got.y, [1, 2])
|
||||
|
||||
def test_bigarray_roundtrip(self):
|
||||
self.db.write("ba", BigArray([1, 2, 3]), True)
|
||||
self.db.flush()
|
||||
got = self.db.retrieve("ba", True)
|
||||
self.assertIsInstance(got, BigArray)
|
||||
self.assertEqual(list(got), [1, 2, 3])
|
||||
|
||||
def test_bytes_containing_value_survives(self):
|
||||
# REGRESSION (base64-pickle bytes fix): silently failed to restore on py3 before the fix.
|
||||
value = {"raw": b"\x00\x01\xff", "items": [b"ab", "s", 1]}
|
||||
self.db.write("bytesval", value, True)
|
||||
self.db.flush()
|
||||
self.assertEqual(self.db.retrieve("bytesval", True), value)
|
||||
|
||||
|
||||
class TestKeyHashing(_HashDBCase):
|
||||
def test_distinct_keys_distinct_hashes(self):
|
||||
# a broken hashKey that keys only on (say) length or the last char would collide; require
|
||||
# 200 distinct keys to map to 200 distinct hashes. (Determinism is implied: the retrieve
|
||||
# round-trips in TestScalar already depend on hashKey being stable.)
|
||||
keys = ["key_%d_%s" % (i, "abcdefgh"[i % 8]) for i in range(200)]
|
||||
hashes = set(HashDB.hashKey(k) for k in keys)
|
||||
self.assertEqual(len(hashes), len(keys), msg="hashKey produced collisions across distinct keys")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
Loading…
Add table
Add a link
Reference in a new issue