[Dev OpenGP] [70] Added protection against dangerous attribute modifications in ogp. plugins and ogp.etree. |
[ Thread Index |
Date Index
| More opengp.tuxfamily.org/development Archives
]
Revision: 70
Author: nicolaf
Date: 2009-03-21 12:18:45 +0100 (Sat, 21 Mar 2009)
Log Message:
-----------
Added protection against dangerous attribute modifications in ogp.plugins and ogp.etree.
Modified Paths:
--------------
trunk/src/lib/ogp/etree/elementmethods.py
trunk/src/lib/ogp/plugins/plugin.py
trunk/src/tests/etree-test.py
Modified: trunk/src/lib/ogp/etree/elementmethods.py
===================================================================
--- trunk/src/lib/ogp/etree/elementmethods.py 2009-03-20 12:35:38 UTC (rev 69)
+++ trunk/src/lib/ogp/etree/elementmethods.py 2009-03-21 11:18:45 UTC (rev 70)
@@ -8,15 +8,19 @@
class OgpElement(ElementBase):
"""
lxml Element class providing redefined secure methods, compliant with the merge algorithm :
- def delElements(self):
- def append(self, newChild):
- def insert(self, index, newChild):
- def extend(self, elements):
- def set(self, name, value):
- def merge(self, peer):
- def toString(self, xsl=None, params=None):
+ delElements(self):
+ append(self, newChild):
+ insert(self, index, newChild):
+ extend(self, elements):
+ set(self, name, value):
+ merge(self, peer):
+ toString(self, xsl=None, params=None):
attributes = property(__getAttributes)
- You should NOT use other methods or modify attributes because it may crash the merge algorithm.
+ text attribute is protected : setting it to something not None deletes all subelements.
+ tail is protected : if you try to modify it, it will still be None
+ attrib if protected : you can only get a copy, so yon can't modify it without using self.set(name, value)
+
+ You should NOT use other methods because it may crash the merge algorithm.
"""
def __setattr__(self, item, value):
@@ -27,10 +31,28 @@
if item == "text" and value is not None:
self.delElements()
if item == "tail":
- value = None
-
+ raise OgpXmlError('__setattr__: setting tail is forbiden, it must be None')
+ if item == "attrib":
+ raise OgpXmlError('__setattr__: setting attributes directly is forbiden, please use self.set(name, value)')
ElementBase.__setattr__(self, item, value)
+ def __getattribute__(self, item):
+ """
+ Protects the 'attrib' attributes by returning a copy instead of the real object.
+ This returns a dict instance, not an _Attrib, but it seems to work
+ """
+ if item == "attrib":
+ return dict(ElementBase.__getattribute__(self, item))
+ else:
+ return ElementBase.__getattribute__(self, item)
+
+ def __getRealAttrib(self):
+ """
+ Provides a private property to access the real 'attrib' attribute.
+ """
+ return ElementBase.__getattribute__(self, "attrib")
+ __attrib = property(__getRealAttrib)
+
def __getAttributes(self):
"""
Returns the attributes dict(), without the OgpXmlConsts.ATTR_BLOCK ('block') attribute.
@@ -58,10 +80,10 @@
"""
assert isinstance(blocking, bool)
if blocking:
- self.attrib[OgpXmlConsts.ATTR_BLOCK] = str(blocking).lower()
+ self.__attrib[OgpXmlConsts.ATTR_BLOCK] = str(blocking).lower()
else:
try:
- del self.attrib[OgpXmlConsts.ATTR_BLOCK]
+ del self.__attrib[OgpXmlConsts.ATTR_BLOCK]
except:
pass
blocking = property(__getBlocking, __setBlocking)
@@ -133,7 +155,7 @@
for br in parent:
if br is not self and br.tag == self.tag and br.attributes == newattrs:
raise OgpXmlError('set: element would no more be unique')
- self.attrib[name] = value
+ self.__attrib[name] = value
def merge(self, peer):
"""
Modified: trunk/src/lib/ogp/plugins/plugin.py
===================================================================
--- trunk/src/lib/ogp/plugins/plugin.py 2009-03-20 12:35:38 UTC (rev 69)
+++ trunk/src/lib/ogp/plugins/plugin.py 2009-03-21 11:18:45 UTC (rev 70)
@@ -1,13 +1,33 @@
#!/usr/bin/python
# -*- coding: utf-8 -*
+def setattr(self, item, value):
+ """
+ Plugin class and metaclass __setattr__ method
+ Throws an exception when attempting to modify the plugin name.
+ """
+ if item == "name":
+ raise OgpPluginError('__setattr__: name is readonly.')
+ self.__dict__[item] = value
+
+class M_Plugin(type):
+ """
+ Makes the 'name' __CLASS__ attribute readonly.
+ """
+ __setattr__ = setattr
+
class Plugin(object):
"""
- Provides plugins' base class and plugin registration mechanism
+ Provides plugins' base class and plugin registration mechanism.
"""
+
+ __metaclass__ = M_Plugin
+
def __init__(self, dn):
self.__dn = dn
+ __setattr__ = setattr
+
name = None # the plugin name
__registeredPlugins = dict()
@@ -25,7 +45,7 @@
"""
try:
Plugin.__registeredPlugins[pluginClass.name]
- raise OgpPluginError("registerPlugin: duplicated plugin name '" + pluginClass.name + "'")
+ raise OgpPluginError("registerPlugin: duplicated plugin name '" + pluginClass.name + "'.")
except:
pass
Plugin.__registeredPlugins[pluginClass.name] = pluginClass
Modified: trunk/src/tests/etree-test.py
===================================================================
--- trunk/src/tests/etree-test.py 2009-03-20 12:35:38 UTC (rev 69)
+++ trunk/src/tests/etree-test.py 2009-03-21 11:18:45 UTC (rev 70)
@@ -69,7 +69,19 @@
print obj.toString()
obj.text = "toto"
print obj.text
+
+print "----PROTECTION ATTRIB----"
+try:
+ obj.attrib = {"test": "aaa"}
+except:
+ print "crash"
print obj.toString()
-
-print "------- TOSTRING -----------"
-
+obj.set("test", "a")
+print obj.toString()
+a=obj.attrib
+a['test2'] = 'bb'
+print obj.toString()
+try:
+ obj.tail = "hkhk"
+except:
+ print "crash"