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):