parent
79f4d4f95a
commit
6869c9f61b
@ -1,248 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
import copy
|
||||
import threading
|
||||
import types
|
||||
|
||||
from thirdparty.odict import OrderedDict
|
||||
from thirdparty.six.moves import collections_abc as _collections
|
||||
|
||||
class AttribDict(dict):
|
||||
"""
|
||||
This class defines the dictionary with added capability to access members as attributes
|
||||
|
||||
>>> foo = AttribDict()
|
||||
>>> foo.bar = 1
|
||||
>>> foo.bar
|
||||
1
|
||||
"""
|
||||
|
||||
def __init__(self, indict=None, attribute=None, keycheck=True):
|
||||
if indict is None:
|
||||
indict = {}
|
||||
|
||||
# Set any attributes here - before initialisation
|
||||
# these remain as normal attributes
|
||||
self.attribute = attribute
|
||||
self.keycheck = keycheck
|
||||
dict.__init__(self, indict)
|
||||
self.__initialised = True
|
||||
|
||||
# After initialisation, setting attributes
|
||||
# is the same as setting an item
|
||||
|
||||
def __getattr__(self, item):
|
||||
"""
|
||||
Maps values to attributes
|
||||
Only called if there *is NOT* an attribute with this name
|
||||
"""
|
||||
|
||||
try:
|
||||
return self.__getitem__(item)
|
||||
except KeyError:
|
||||
if self.keycheck:
|
||||
raise AttributeError("unable to access item '%s'" % item)
|
||||
else:
|
||||
return None
|
||||
|
||||
def __delattr__(self, item):
|
||||
"""
|
||||
Deletes attributes
|
||||
"""
|
||||
|
||||
try:
|
||||
return self.pop(item)
|
||||
except KeyError:
|
||||
if self.keycheck:
|
||||
raise AttributeError("unable to access item '%s'" % item)
|
||||
else:
|
||||
return None
|
||||
|
||||
def __setattr__(self, item, value):
|
||||
"""
|
||||
Maps attributes to values
|
||||
Only if we are initialised
|
||||
"""
|
||||
|
||||
# This test allows attributes to be set in the __init__ method
|
||||
if "_AttribDict__initialised" not in self.__dict__:
|
||||
return dict.__setattr__(self, item, value)
|
||||
|
||||
# Any normal attributes are handled normally
|
||||
elif item in self.__dict__:
|
||||
dict.__setattr__(self, item, value)
|
||||
|
||||
else:
|
||||
self.__setitem__(item, value)
|
||||
|
||||
def __getstate__(self):
|
||||
return self.__dict__
|
||||
|
||||
def __setstate__(self, dict):
|
||||
self.__dict__ = dict
|
||||
|
||||
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.FunctionType, types.MethodType)):
|
||||
setattr(retVal, attr, copy.deepcopy(value, memo))
|
||||
|
||||
for key, value in self.items():
|
||||
retVal.__setitem__(key, copy.deepcopy(value, memo))
|
||||
|
||||
return retVal
|
||||
|
||||
class InjectionDict(AttribDict):
|
||||
def __init__(self):
|
||||
AttribDict.__init__(self)
|
||||
|
||||
self.place = None
|
||||
self.parameter = None
|
||||
self.ptype = None
|
||||
self.prefix = None
|
||||
self.suffix = None
|
||||
self.clause = None
|
||||
self.notes = [] # Note: https://github.com/sqlmapproject/sqlmap/issues/1888
|
||||
|
||||
# data is a dict with various stype, each which is a dict with
|
||||
# all the information specific for that stype
|
||||
self.data = AttribDict()
|
||||
|
||||
# conf is a dict which stores current snapshot of important
|
||||
# options used during detection
|
||||
self.conf = AttribDict()
|
||||
|
||||
self.dbms = None
|
||||
self.dbms_version = None
|
||||
self.os = None
|
||||
|
||||
# Reference: https://www.kunxi.org/2014/05/lru-cache-in-python
|
||||
class LRUDict(object):
|
||||
"""
|
||||
This class defines the LRU dictionary
|
||||
|
||||
>>> foo = LRUDict(capacity=2)
|
||||
>>> foo["first"] = 1
|
||||
>>> foo["second"] = 2
|
||||
>>> foo["third"] = 3
|
||||
>>> "first" in foo
|
||||
False
|
||||
>>> "third" in foo
|
||||
True
|
||||
"""
|
||||
|
||||
def __init__(self, capacity):
|
||||
self.capacity = capacity
|
||||
self.cache = OrderedDict()
|
||||
self.__lock = threading.Lock()
|
||||
|
||||
def __len__(self):
|
||||
return len(self.cache)
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self.cache
|
||||
|
||||
def __getitem__(self, key):
|
||||
value = self.cache.pop(key)
|
||||
self.cache[key] = value
|
||||
return value
|
||||
|
||||
def get(self, key):
|
||||
return self.__getitem__(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
with self.__lock:
|
||||
try:
|
||||
self.cache.pop(key)
|
||||
except KeyError:
|
||||
if len(self.cache) >= self.capacity:
|
||||
self.cache.popitem(last=False)
|
||||
self.cache[key] = value
|
||||
|
||||
def set(self, key, value):
|
||||
self.__setitem__(key, value)
|
||||
|
||||
def keys(self):
|
||||
return self.cache.keys()
|
||||
|
||||
# Reference: https://code.activestate.com/recipes/576694/
|
||||
class OrderedSet(_collections.MutableSet):
|
||||
"""
|
||||
This class defines the set with ordered (as added) items
|
||||
|
||||
>>> foo = OrderedSet()
|
||||
>>> foo.add(1)
|
||||
>>> foo.add(2)
|
||||
>>> foo.add(3)
|
||||
>>> foo.pop()
|
||||
3
|
||||
>>> foo.pop()
|
||||
2
|
||||
>>> foo.pop()
|
||||
1
|
||||
"""
|
||||
|
||||
def __init__(self, iterable=None):
|
||||
self.end = end = []
|
||||
end += [None, end, end] # sentinel node for doubly linked list
|
||||
self.map = {} # key --> [key, prev, next]
|
||||
if iterable is not None:
|
||||
self |= iterable
|
||||
|
||||
def __len__(self):
|
||||
return len(self.map)
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self.map
|
||||
|
||||
def add(self, value):
|
||||
if value not in self.map:
|
||||
end = self.end
|
||||
curr = end[1]
|
||||
curr[2] = end[1] = self.map[value] = [value, curr, end]
|
||||
|
||||
def discard(self, value):
|
||||
if value in self.map:
|
||||
value, prev, next = self.map.pop(value)
|
||||
prev[2] = next
|
||||
next[1] = prev
|
||||
|
||||
def __iter__(self):
|
||||
end = self.end
|
||||
curr = end[2]
|
||||
while curr is not end:
|
||||
yield curr[0]
|
||||
curr = curr[2]
|
||||
|
||||
def __reversed__(self):
|
||||
end = self.end
|
||||
curr = end[1]
|
||||
while curr is not end:
|
||||
yield curr[0]
|
||||
curr = curr[1]
|
||||
|
||||
def pop(self, last=True):
|
||||
if not self:
|
||||
raise KeyError('set is empty')
|
||||
key = self.end[1][0] if last else self.end[2][0]
|
||||
self.discard(key)
|
||||
return key
|
||||
|
||||
def __repr__(self):
|
||||
if not self:
|
||||
return '%s()' % (self.__class__.__name__,)
|
||||
return '%s(%r)' % (self.__class__.__name__, list(self))
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, OrderedSet):
|
||||
return len(self) == len(other) and list(self) == list(other)
|
||||
return set(self) == set(other)
|
@ -1,100 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
import functools
|
||||
import hashlib
|
||||
import threading
|
||||
|
||||
from lib.core.datatype import LRUDict
|
||||
from lib.core.settings import MAX_CACHE_ITEMS
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.core.threads import getCurrentThreadData
|
||||
|
||||
_cache = {}
|
||||
_cache_lock = threading.Lock()
|
||||
_method_locks = {}
|
||||
|
||||
def cachedmethod(f):
|
||||
"""
|
||||
Method with a cached content
|
||||
|
||||
>>> __ = cachedmethod(lambda _: _)
|
||||
>>> __(1)
|
||||
1
|
||||
>>> __(1)
|
||||
1
|
||||
>>> __ = cachedmethod(lambda *args, **kwargs: args[0])
|
||||
>>> __(2)
|
||||
2
|
||||
>>> __ = cachedmethod(lambda *args, **kwargs: next(iter(kwargs.values())))
|
||||
>>> __(foobar=3)
|
||||
3
|
||||
|
||||
Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/
|
||||
"""
|
||||
|
||||
_cache[f] = LRUDict(capacity=MAX_CACHE_ITEMS)
|
||||
|
||||
@functools.wraps(f)
|
||||
def _f(*args, **kwargs):
|
||||
try:
|
||||
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs)).encode(UNICODE_ENCODING)).hexdigest(), 16) & 0x7fffffffffffffff
|
||||
except ValueError: # https://github.com/sqlmapproject/sqlmap/issues/4281 (NOTE: non-standard Python behavior where hexdigest returns binary value)
|
||||
result = f(*args, **kwargs)
|
||||
else:
|
||||
try:
|
||||
with _cache_lock:
|
||||
result = _cache[f][key]
|
||||
except KeyError:
|
||||
result = f(*args, **kwargs)
|
||||
|
||||
with _cache_lock:
|
||||
_cache[f][key] = result
|
||||
|
||||
return result
|
||||
|
||||
return _f
|
||||
|
||||
def stackedmethod(f):
|
||||
"""
|
||||
Method using pushValue/popValue functions (fallback function for stack realignment)
|
||||
|
||||
>>> threadData = getCurrentThreadData()
|
||||
>>> original = len(threadData.valueStack)
|
||||
>>> __ = stackedmethod(lambda _: threadData.valueStack.append(_))
|
||||
>>> __(1)
|
||||
>>> len(threadData.valueStack) == original
|
||||
True
|
||||
"""
|
||||
|
||||
@functools.wraps(f)
|
||||
def _(*args, **kwargs):
|
||||
threadData = getCurrentThreadData()
|
||||
originalLevel = len(threadData.valueStack)
|
||||
|
||||
try:
|
||||
result = f(*args, **kwargs)
|
||||
finally:
|
||||
if len(threadData.valueStack) > originalLevel:
|
||||
threadData.valueStack = threadData.valueStack[:originalLevel]
|
||||
|
||||
return result
|
||||
|
||||
return _
|
||||
|
||||
def lockedmethod(f):
|
||||
@functools.wraps(f)
|
||||
def _(*args, **kwargs):
|
||||
if f not in _method_locks:
|
||||
_method_locks[f] = threading.RLock()
|
||||
|
||||
with _method_locks[f]:
|
||||
result = f(*args, **kwargs)
|
||||
|
||||
return result
|
||||
|
||||
return _
|
Loading…
Reference in new issue