sqlmap/tests/test_misc.py
2026-06-15 09:50:47 +02:00

125 lines
4.5 KiB
Python

#!/usr/bin/env python
"""
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
Assorted pure helpers: stats, set ops, value predicates, value/counter stacks,
enum helpers, DBMS alias/version checks, column prioritization.
"""
import os
import sys
import unittest
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _testutils import bootstrap, set_dbms
bootstrap()
from lib.core import common as C
from lib.core.settings import NULL
from lib.core.enums import DBMS
class TestStats(unittest.TestCase):
def test_average(self):
self.assertEqual(C.average([1, 2, 3, 4]), 2.5)
self.assertEqual(C.average([5]), 5)
def test_stdev(self):
self.assertAlmostEqual(C.stdev([1, 2, 3, 4]), 1.2909944, places=5)
self.assertIsNone(C.stdev([5])) # undefined for single sample
class TestSetOps(unittest.TestCase):
def test_intersect(self):
self.assertEqual(C.intersect([1, 2, 3], [2, 3, 4]), [2, 3])
self.assertEqual(C.intersect([1], [2]), [])
def test_filterPairValues(self):
self.assertEqual(C.filterPairValues([[1, 2], [3], [4, 5], []]), [[1, 2], [4, 5]])
class TestValuePredicates(unittest.TestCase):
def test_isNoneValue(self):
for v in (None, [], "", {}):
self.assertTrue(C.isNoneValue(v), msg="isNoneValue(%r)" % (v,))
def test_isNullValue(self):
self.assertTrue(C.isNullValue(NULL))
# discriminating negatives: an always-True impl must fail these
self.assertFalse(C.isNullValue(None))
self.assertFalse(C.isNullValue(""))
self.assertFalse(C.isNullValue("x"))
def test_isNumPosStrValue(self):
for v, exp in [("5", True), ("0", False), ("-1", False), ("a", False), ("12", True)]:
self.assertEqual(bool(C.isNumPosStrValue(v)), exp, msg="isNumPosStrValue(%r)" % v)
def test_firstNotNone(self):
self.assertEqual(C.firstNotNone(None, None, 5, 6), 5)
self.assertIsNone(C.firstNotNone(None, None))
class TestValueStackAndCounters(unittest.TestCase):
def test_push_pop(self):
C.pushValue(7)
C.pushValue("x")
self.assertEqual(C.popValue(), "x")
self.assertEqual(C.popValue(), 7)
def test_counters(self):
C.resetCounter("UNITTEST")
C.incrementCounter("UNITTEST")
C.incrementCounter("UNITTEST")
self.assertEqual(C.getCounter("UNITTEST"), 2)
class TestEnumAndDbmsHelpers(unittest.TestCase):
def test_aliasToDbmsEnum(self):
self.assertEqual(C.aliasToDbmsEnum("mysql"), DBMS.MYSQL)
self.assertEqual(C.aliasToDbmsEnum("postgres"), DBMS.PGSQL)
def test_getPublicTypeMembers(self):
members = list(C.getPublicTypeMembers(DBMS, onlyValues=True))
# goal is correct EXTRACTION, not a magic count: real members present, no private/dunder leak
self.assertIn(DBMS.MYSQL, members)
self.assertIn(DBMS.MSSQL, members)
self.assertIn(DBMS.ORACLE, members)
self.assertFalse(any(str(m).startswith("_") for m in members), msg="leaked private member: %r" % members)
def test_isDBMSVersionAtLeast(self):
set_dbms(DBMS.MYSQL)
C.Backend.setVersion("5.7")
self.assertTrue(C.isDBMSVersionAtLeast("5.0"))
self.assertFalse(C.isDBMSVersionAtLeast("8.0"))
class TestColumnPriority(unittest.TestCase):
def test_prioritySortColumns(self):
# assert the FULL ordering, not just the first element (id-like floats to front,
# rest keep their relative order)
self.assertEqual(C.prioritySortColumns(["data", "id", "name"]), ["id", "data", "name"])
def test_prioritySortColumns_empty(self):
self.assertEqual(C.prioritySortColumns([]), [])
class TestArrayHelpers(unittest.TestCase):
def test_unArrayizeValue(self):
self.assertEqual(C.unArrayizeValue([5]), 5) # single-element list -> the element
self.assertEqual(C.unArrayizeValue([1, 2]), 1) # multi -> first
self.assertEqual(C.unArrayizeValue(7), 7) # scalar -> unchanged
self.assertIsNone(C.unArrayizeValue([])) # empty -> None
def test_arrayizeValue(self):
self.assertEqual(C.arrayizeValue(5), [5]) # scalar -> wrapped
self.assertEqual(C.arrayizeValue([5]), [5]) # list -> unchanged
def test_roundtrip_scalar(self):
for v in (0, 1, "x", "value"):
self.assertEqual(C.unArrayizeValue(C.arrayizeValue(v)), v)
if __name__ == "__main__":
unittest.main(verbosity=2)