mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-06-20 06:28:55 +00:00
78 lines
2.9 KiB
Python
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)
|