From mtharp at rpath.com Wed Dec 9 13:42:26 2009 From: mtharp at rpath.com (Michael Tharp) Date: Wed, 09 Dec 2009 18:42:26 +0000 Subject: xobj: Fixed the re-definition of the model after bad XML is fed in (RBL-5328) Message-ID: <200912091842.nB9IgQw2001353@scc.eng.rpath.com> changeset: 37f11b32cb54 user: Mihai Ibanescu date: Fri, 06 Nov 2009 10:45:21 -0500 Fixed the re-definition of the model after bad XML is fed in (RBL-5328) diff --git a/py/test/xobjtest.py b/py/test/xobjtest.py --- a/py/test/xobjtest.py +++ b/py/test/xobjtest.py @@ -834,5 +834,36 @@ x = xobj.parse(s, typeMap = { 'foo' : Foo }) assert(x.foo.i == 1 << 33) + def testGlobalsPoisoning(self): + # RBL-5328 + class Foo(object): + _xobj = xobj.XObjMetadata(attributes = [ ], + elements = [ 'elem1', 'elem2' ]) + + f = Foo() + f.elem1 = 'val1' + f.elem2 = 'val2' + s = xobj.toxml(f, 'root') + self.assertXMLEquals(s, + "val1val2") + + # Now feed it an XML string that uses attributes instead of elements + x = xobj.parse('', + typeMap = { 'root' : Foo }) + self.failUnlessEqual(x.root.elem1, f.elem1) + self.failUnlessEqual(x.root.elem2, f.elem2) + + # Now serialize f again, elements should continue to be elements + s = xobj.toxml(f, 'root') + self.assertXMLEquals(s, + "val1val2") + + # Brand new object + f2 = Foo() + f2.elem1 = 'val2' + s2 = xobj.toxml(f2, 'root') + self.assertXMLEquals(s2, + "val2") + if __name__ == "__main__": testsuite.main() diff --git a/py/xobj/xobj.py b/py/xobj/xobj.py --- a/py/xobj/xobj.py +++ b/py/xobj/xobj.py @@ -387,13 +387,18 @@ def addAttribute(xobj, key, val, xType = None): setItem(xobj, key, val, xType) - if key not in xobj._xobj.attributes: - # preserver any type information we copied in + if key not in xobj._xobj.attributes and (key not in + xobj._xobj.elements): + # preserve any type information we copied in, but only if it + # wasn't previously defined (either element or attribute). xobj._xobj.attributes[key] = None def addElement(xobj, key, val, xType = None): setItem(xobj, key, val, xType = xType) - if key not in xobj._xobj.elements: + if key not in xobj._xobj.elements and (key not in + xobj._xobj.attributes): + # preserve any type information we copied in, but only if it + # wasn't previously defined (either element or attribute). xobj._xobj.elements.append(key) def setItem(xobj, key, val, xType = None):