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

78 lines
2.9 KiB
Python

#!/usr/bin/env python
"""
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
Identifier quoting per DBMS dialect, CSV value escaping, and dump value
replacement markers.
"""
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.common import safeSQLIdentificatorNaming, unsafeSQLIdentificatorNaming, safeCSValue
from lib.core.enums import DBMS
class TestIdentifierQuoting(unittest.TestCase):
# special-char identifier -> the per-dialect quoting wrapper
WRAP = {
DBMS.MYSQL: "`weird name`",
DBMS.MSSQL: "[weird name]",
DBMS.PGSQL: '"weird name"',
DBMS.ORACLE: '"WEIRD NAME"', # Oracle upper-cases quoted identifiers
}
def test_special_identifier_quoting(self):
for dbms, wrapped in self.WRAP.items():
set_dbms(dbms)
self.assertEqual(safeSQLIdentificatorNaming("weird name"), wrapped, msg=str(dbms))
def test_simple_identifier_roundtrip(self):
# plain identifier needs no quoting; round-trips identically on case-preserving dialects
for dbms in (DBMS.MYSQL, DBMS.MSSQL, DBMS.PGSQL):
set_dbms(dbms)
for ident in ("users", "password", "tbl1"):
self.assertEqual(safeSQLIdentificatorNaming(ident), ident, msg="%s %r" % (dbms, ident))
self.assertEqual(unsafeSQLIdentificatorNaming(safeSQLIdentificatorNaming(ident)), ident)
def test_oracle_uppercases_on_unsafe(self):
# documented dialect quirk: Oracle unsafe-naming upper-cases identifiers
set_dbms(DBMS.ORACLE)
self.assertEqual(safeSQLIdentificatorNaming("users"), "users")
self.assertEqual(unsafeSQLIdentificatorNaming(safeSQLIdentificatorNaming("users")), "USERS")
def test_unsafe_strips_quotes(self):
for dbms in (DBMS.MYSQL, DBMS.MSSQL, DBMS.PGSQL):
set_dbms(dbms)
self.assertEqual(unsafeSQLIdentificatorNaming(safeSQLIdentificatorNaming("weird name")), "weird name")
class TestSafeCSValue(unittest.TestCase):
CASES = [
("foobar", "foobar"), # plain -> unchanged
("foo,bar", '"foo,bar"'), # contains delimiter -> quoted
('he"y', '"he""y"'), # contains quote -> doubled + wrapped
("a\nb", '"a\nb"'), # contains newline -> quoted
]
def test_table(self):
for inp, expected in self.CASES:
self.assertEqual(safeCSValue(inp), expected, msg="safeCSValue(%r)" % inp)
def test_idempotent_on_already_quoted(self):
once = safeCSValue("a,b")
self.assertEqual(safeCSValue(once), once) # already starts+ends with quote -> unchanged
# (DUMP_REPLACEMENTS markers are covered in test_dicts.py - not duplicated here)
if __name__ == "__main__":
unittest.main(verbosity=2)