diff --git a/lib/controller/checks.py b/lib/controller/checks.py
index d86ece261..696a6c146 100644
--- a/lib/controller/checks.py
+++ b/lib/controller/checks.py
@@ -41,8 +41,8 @@ from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.data import paths
-from lib.core.datatype import advancedDict
-from lib.core.datatype import injectionDict
+from lib.core.datatype import AttribDict
+from lib.core.datatype import InjectionDict
from lib.core.enums import HTTPHEADER
from lib.core.enums import HTTPMETHOD
from lib.core.enums import NULLCONNECTION
@@ -68,7 +68,7 @@ from lib.techniques.union.use import configUnion
def checkSqlInjection(place, parameter, value):
# Store here the details about boundaries and payload used to
# successfully inject
- injection = injectionDict()
+ injection = InjectionDict()
# Localized thread data needed for some methods
threadData = getCurrentThreadData()
@@ -452,7 +452,7 @@ def checkSqlInjection(place, parameter, value):
if vector is None and "vector" in test and test.vector is not None:
vector = "%s%s" % (test.vector, comment)
- injection.data[stype] = advancedDict()
+ injection.data[stype] = AttribDict()
injection.data[stype].title = title
injection.data[stype].payload = agent.removePayloadDelimiters(reqPayload)
injection.data[stype].where = where
diff --git a/lib/core/agent.py b/lib/core/agent.py
index c77efb313..e9f92eb5c 100644
--- a/lib/core/agent.py
+++ b/lib/core/agent.py
@@ -21,7 +21,7 @@ from lib.core.convert import urlencode
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import queries
-from lib.core.datatype import advancedDict
+from lib.core.datatype import AttribDict
from lib.core.enums import DBMS
from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE
diff --git a/lib/core/common.py b/lib/core/common.py
index 6b67afb18..d4f12183f 100644
--- a/lib/core/common.py
+++ b/lib/core/common.py
@@ -1925,9 +1925,7 @@ def pushValue(value):
Push value to the stack (thread dependent)
"""
- # TODO: quick fix
- #getCurrentThreadData().valueStack.append(copy.deepcopy(value))
- getCurrentThreadData().valueStack.append(value)
+ getCurrentThreadData().valueStack.append(copy.deepcopy(value))
def popValue():
"""
diff --git a/lib/core/data.py b/lib/core/data.py
index 53b5635bb..cf9523711 100644
--- a/lib/core/data.py
+++ b/lib/core/data.py
@@ -7,21 +7,21 @@ Copyright (c) 2006-2011 sqlmap developers (http://www.sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
-from lib.core.datatype import advancedDict
+from lib.core.datatype import AttribDict
from lib.core.settings import LOGGER
# sqlmap paths
-paths = advancedDict()
+paths = AttribDict()
# object to store original command line options
-cmdLineOptions = advancedDict()
+cmdLineOptions = AttribDict()
# object to share within function and classes command
# line options and settings
-conf = advancedDict()
+conf = AttribDict()
# object to share within function and classes results
-kb = advancedDict()
+kb = AttribDict()
# object with each database management system specific queries
queries = {}
diff --git a/lib/core/datatype.py b/lib/core/datatype.py
index 33402a394..37c681b2f 100644
--- a/lib/core/datatype.py
+++ b/lib/core/datatype.py
@@ -7,9 +7,12 @@ Copyright (c) 2006-2011 sqlmap developers (http://www.sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
+import copy
+import types
+
from lib.core.exception import sqlmapDataException
-class advancedDict(dict):
+class AttribDict(dict):
"""
This class defines the sqlmap object, inheriting from Python data
type dictionary.
@@ -46,7 +49,7 @@ class advancedDict(dict):
"""
# This test allows attributes to be set in the __init__ method
- if not self.__dict__.has_key('_advancedDict__initialised'):
+ if not self.__dict__.has_key('_AttribDict__initialised'):
return dict.__setattr__(self, item, value)
# Any normal attributes are handled normally
@@ -62,9 +65,20 @@ class advancedDict(dict):
def __setstate__(self, dict):
self.__dict__ = dict
-class injectionDict(advancedDict):
+ def __deepcopy__(self, memo):
+ retVal = self.__class__()
+ memo[id(self)] = retVal
+ for attr in dir(self):
+ if not attr.startswith('_'):
+ value = getattr(self, attr)
+ if not isinstance(value, (types.BuiltinFunctionType, types.BuiltinFunctionType, types.FunctionType, types.MethodType)):
+ setattr(retVal, attr, copy.deepcopy(value, memo))
+
+ return retVal
+
+class InjectionDict(AttribDict):
def __init__(self):
- advancedDict.__init__(self)
+ AttribDict.__init__(self)
self.place = None
self.parameter = None
@@ -75,11 +89,11 @@ class injectionDict(advancedDict):
# data is a dict with various stype, each which is a dict with
# all the information specific for that stype
- self.data = advancedDict()
+ self.data = AttribDict()
# conf is a dict which stores current snapshot of important
# options used during detection
- self.conf = advancedDict()
+ self.conf = AttribDict()
self.dbms = None
self.dbms_version = None
diff --git a/lib/core/defaults.py b/lib/core/defaults.py
index 4e4617578..fd64ee4da 100644
--- a/lib/core/defaults.py
+++ b/lib/core/defaults.py
@@ -7,7 +7,7 @@ Copyright (c) 2006-2011 sqlmap developers (http://www.sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
-from lib.core.datatype import advancedDict
+from lib.core.datatype import AttribDict
_defaults = {
"timeSec": 5,
@@ -25,4 +25,4 @@ _defaults = {
"tech": "BEUST"
}
-defaults = advancedDict(_defaults)
+defaults = AttribDict(_defaults)
diff --git a/lib/core/option.py b/lib/core/option.py
index 745335f7a..96c4f5d68 100644
--- a/lib/core/option.py
+++ b/lib/core/option.py
@@ -55,8 +55,8 @@ from lib.core.data import kb
from lib.core.data import logger
from lib.core.data import paths
from lib.core.data import queries
-from lib.core.datatype import advancedDict
-from lib.core.datatype import injectionDict
+from lib.core.datatype import AttribDict
+from lib.core.datatype import InjectionDict
from lib.core.defaults import defaults
from lib.core.enums import DBMS
from lib.core.enums import HTTPHEADER
@@ -963,7 +963,7 @@ def __setPrefixSuffix():
if conf.prefix is not None and conf.suffix is not None:
# Create a custom boundary object for user's supplied prefix
# and suffix
- boundary = advancedDict()
+ boundary = AttribDict()
boundary.level = 1
boundary.clause = [ 0 ]
@@ -1381,18 +1381,18 @@ def __setKnowledgeBaseAttributes(flushAll=True):
kb.alwaysRefresh = None
kb.arch = None
kb.authHeader = None
- kb.bannerFp = advancedDict()
+ kb.bannerFp = AttribDict()
- kb.brute = advancedDict({'tables':[], 'columns':[]})
+ kb.brute = AttribDict({'tables':[], 'columns':[]})
kb.bruteMode = False
- kb.cache = advancedDict()
+ kb.cache = AttribDict()
kb.cache.content = {}
kb.cache.regex = {}
kb.cache.stdev = {}
kb.commonOutputs = None
- kb.data = advancedDict()
+ kb.data = AttribDict()
kb.dataOutputFlag = False
# Active back-end DBMS fingerprint
@@ -1415,10 +1415,10 @@ def __setKnowledgeBaseAttributes(flushAll=True):
kb.hintValue = None
kb.htmlFp = []
kb.ignoreTimeout = False
- kb.injection = injectionDict()
+ kb.injection = InjectionDict()
kb.injections = []
- kb.locks = advancedDict()
+ kb.locks = AttribDict()
kb.locks.cacheLock = threading.Lock()
kb.locks.logLock = threading.Lock()
kb.locks.ioLock = threading.Lock()
@@ -1459,7 +1459,7 @@ def __setKnowledgeBaseAttributes(flushAll=True):
kb.uChar = "NULL"
kb.xpCmdshellAvailable = False
- kb.misc = advancedDict()
+ kb.misc = AttribDict()
kb.misc.delimiter = randomStr(length=6, lowercase=True)
kb.misc.start = ":%s:" % randomStr(length=3, lowercase=True)
kb.misc.stop = ":%s:" % randomStr(length=3, lowercase=True)
@@ -1795,7 +1795,7 @@ def __resolveCrossReferences():
lib.core.threads.readInput = readInput
lib.core.common.getPageTemplate = getPageTemplate
-def init(inputOptions=advancedDict(), overrideOptions=False):
+def init(inputOptions=AttribDict(), overrideOptions=False):
"""
Set attributes into both configuration and knowledge base singletons
based upon command line and configuration file options.
diff --git a/lib/core/session.py b/lib/core/session.py
index 335d86a9e..3d6f00ebf 100644
--- a/lib/core/session.py
+++ b/lib/core/session.py
@@ -20,7 +20,7 @@ from lib.core.convert import base64unpickle
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
-from lib.core.datatype import injectionDict
+from lib.core.datatype import InjectionDict
from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.enums import PAYLOAD
diff --git a/lib/core/threads.py b/lib/core/threads.py
index 1d45bc373..a00ad4a20 100644
--- a/lib/core/threads.py
+++ b/lib/core/threads.py
@@ -15,7 +15,7 @@ from thread import error as threadError
from lib.core.data import kb
from lib.core.data import logger
-from lib.core.datatype import advancedDict
+from lib.core.datatype import AttribDict
from lib.core.enums import PAYLOAD
from lib.core.exception import sqlmapConnectionException
from lib.core.exception import sqlmapThreadException
@@ -23,7 +23,7 @@ from lib.core.exception import sqlmapValueException
from lib.core.settings import MAX_NUMBER_OF_THREADS
from lib.core.settings import PYVERSION
-shared = advancedDict()
+shared = AttribDict()
class _ThreadData(threading.local):
"""
diff --git a/lib/core/unescaper.py b/lib/core/unescaper.py
index ba5227f94..a9ad6b3f1 100644
--- a/lib/core/unescaper.py
+++ b/lib/core/unescaper.py
@@ -8,10 +8,10 @@ See the file 'doc/COPYING' for copying permission
"""
from lib.core.common import Backend
-from lib.core.datatype import advancedDict
+from lib.core.datatype import AttribDict
from lib.core.settings import EXCLUDE_UNESCAPE
-class Unescaper(advancedDict):
+class Unescaper(AttribDict):
def unescape(self, expression, quote=True, dbms=None):
if expression is None:
return expression
diff --git a/lib/parse/payloads.py b/lib/parse/payloads.py
index c54e74361..b26244139 100644
--- a/lib/parse/payloads.py
+++ b/lib/parse/payloads.py
@@ -11,7 +11,7 @@ from xml.etree import ElementTree as et
from lib.core.data import conf
from lib.core.data import paths
-from lib.core.datatype import advancedDict
+from lib.core.datatype import AttribDict
def cleanupVals(text, tag):
if tag in ("clause", "where"):
@@ -42,7 +42,7 @@ def cleanupVals(text, tag):
def parseXmlNode(node):
for element in node.getiterator('boundary'):
- boundary = advancedDict()
+ boundary = AttribDict()
for child in element.getchildren():
if child.text:
@@ -54,7 +54,7 @@ def parseXmlNode(node):
conf.boundaries.append(boundary)
for element in node.getiterator('test'):
- test = advancedDict()
+ test = AttribDict()
for child in element.getchildren():
if child.text and child.text.strip():
@@ -65,7 +65,7 @@ def parseXmlNode(node):
test[child.tag] = None
continue
else:
- test[child.tag] = advancedDict()
+ test[child.tag] = AttribDict()
for gchild in child.getchildren():
if gchild.tag in test[child.tag]:
diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py
index 9c19bc424..3b21bcb47 100644
--- a/plugins/generic/enumeration.py
+++ b/plugins/generic/enumeration.py
@@ -881,19 +881,11 @@ class Enumeration:
query = safeStringFormat(query, conf.db)
value = inject.getValue(query, blind=False)
- value = filter(lambda x: x, value)
+ value = arrayizeValue(filter(lambda x: x, value))
if not isNoneValue(value):
- if Backend.isDbms(DBMS.SQLITE):
- if isinstance(value, basestring):
- value = [[ DBMS.SQLITE, value ]]
- elif isinstance(value, (list, tuple, set)):
- newValue = []
-
- for v in value:
- newValue.append([ DBMS.SQLITE, v])
-
- value = newValue
+ if len(value) > 0 and not isinstance(value[0], (list, tuple)):
+ value = zip([conf.db for i in xrange(len(value))], value)
for db, table in value:
db = safeSQLIdentificatorNaming(db)
diff --git a/xml/queries.xml b/xml/queries.xml
index eaeb00438..3af8e9dff 100644
--- a/xml/queries.xml
+++ b/xml/queries.xml
@@ -48,7 +48,7 @@
-
+
@@ -366,6 +366,7 @@
+
@@ -465,7 +466,7 @@
-
+