sqlmap-AttribDict 类

sqlmap 中的 AttribDict 类的作用

  1. sqlmap 中存在如下 class。具体的实现如下 AttribDict 的实现代码
  2. 通过在 sqlmap/lib/core/data.py 中可以看到,存在多个全局变量是由 AttribDict 类初始化的。sqlmap-AttribDict_1.png|550
  3. 该类的作用也非常简单,从注释能够看出来实现了的功能如下。AttribDict(属性字典)相对于字典来说,可以直接通过 foo.bar 来进行赋值,而正常的字典则需要通过 foo["bar"]=1 的方式进行赋值,相对来说比较方便。从 sqlmap 代码的使用来看,均是将这些全局变量来保存状态/数据的值。
>>> foo = AttribDict()
>>> foo.bar = 1
>>> foo.bar
1

sqlmap 的 AttribDict 类的实现

AttribDict 类的实现也非常的简单。

  1. 首先继承 dict 类
  2. 通过重写 __getattr___setattr__ 两个内部函数,来保证在调用 foo.bar 的时候能够获取到值或者进行赋值。

AttribDict的实现代码

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 __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