[Python-checkins] cpython (merge 3.3 -> default): Merge for Issue #18997: Issue #18997: fix ElementTree crash with using pickle
eli.bendersky
python-checkins at python.org
Fri Sep 13 15:28:16 CEST 2013
http://hg.python.org/cpython/rev/bda5a87df1c8
changeset: 85678:bda5a87df1c8
parent: 85675:c902ceaf7825
parent: 85677:db01fc8c1a7b
user: Eli Bendersky <eliben at gmail.com>
date: Fri Sep 13 06:27:52 2013 -0700
summary:
Merge for Issue #18997: Issue #18997: fix ElementTree crash with using pickle and __getstate__.
files:
Lib/test/test_xml_etree.py | 12 ++++++
Misc/ACKS | 1 +
Modules/_elementtree.c | 52 ++++++++++++-------------
3 files changed, 38 insertions(+), 27 deletions(-)
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
--- a/Lib/test/test_xml_etree.py
+++ b/Lib/test/test_xml_etree.py
@@ -1697,6 +1697,18 @@
self.assertEqual(len(e2), 2)
self.assertEqualElements(e, e2)
+ def test_pickle_issue18997(self):
+ for dumper, loader in product(self.modules, repeat=2):
+ XMLTEXT = """<?xml version="1.0"?>
+ <group><dogs>4</dogs>
+ </group>"""
+ e1 = dumper.fromstring(XMLTEXT)
+ if hasattr(e1, '__getstate__'):
+ self.assertEqual(e1.__getstate__()['tag'], 'group')
+ e2 = self.pickleRoundTrip(e1, 'xml.etree.ElementTree', dumper, loader)
+ self.assertEqual(e2.tag, 'group')
+ self.assertEqual(e2[0].tag, 'dogs')
+
class ElementTreeTypeTest(unittest.TestCase):
def test_istype(self):
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -154,6 +154,7 @@
Georg Brandl
Christopher Brannon
Terrence Brannon
+Germán M. Bravo
Sven Brauch
Erik Bray
Brian Brazil
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -59,6 +59,18 @@
#define JOIN_SET(p, flag) ((void*) ((Py_uintptr_t) (JOIN_OBJ(p)) | (flag)))
#define JOIN_OBJ(p) ((PyObject*) ((Py_uintptr_t) (p) & ~(Py_uintptr_t)1))
+/* Py_CLEAR for a PyObject* that uses a join flag. Pass the pointer by
+ * reference since this function sets it to NULL.
+*/
+void _clear_joined_ptr(PyObject **p)
+{
+ if (*p) {
+ PyObject *tmp = JOIN_OBJ(*p);
+ *p = NULL;
+ Py_DECREF(tmp);
+ }
+}
+
/* Types defined by this extension */
static PyTypeObject Element_Type;
static PyTypeObject ElementIter_Type;
@@ -613,22 +625,8 @@
element_gc_clear(ElementObject *self)
{
Py_CLEAR(self->tag);
-
- /* The following is like Py_CLEAR for self->text and self->tail, but
- * written explicitily because the real pointers hide behind access
- * macros.
- */
- if (self->text) {
- PyObject *tmp = JOIN_OBJ(self->text);
- self->text = NULL;
- Py_DECREF(tmp);
- }
-
- if (self->tail) {
- PyObject *tmp = JOIN_OBJ(self->tail);
- self->tail = NULL;
- Py_DECREF(tmp);
- }
+ _clear_joined_ptr(&self->text);
+ _clear_joined_ptr(&self->tail);
/* After dropping all references from extra, it's no longer valid anyway,
* so fully deallocate it.
@@ -866,15 +864,15 @@
PICKLED_TAG, self->tag,
PICKLED_CHILDREN, children,
PICKLED_ATTRIB,
- PICKLED_TEXT, self->text,
- PICKLED_TAIL, self->tail);
+ PICKLED_TEXT, JOIN_OBJ(self->text),
+ PICKLED_TAIL, JOIN_OBJ(self->tail));
else
instancedict = Py_BuildValue("{sOsOsOsOsO}",
PICKLED_TAG, self->tag,
PICKLED_CHILDREN, children,
PICKLED_ATTRIB, self->extra->attrib,
- PICKLED_TEXT, self->text,
- PICKLED_TAIL, self->tail);
+ PICKLED_TEXT, JOIN_OBJ(self->text),
+ PICKLED_TAIL, JOIN_OBJ(self->tail));
if (instancedict) {
Py_DECREF(children);
return instancedict;
@@ -907,13 +905,13 @@
self->tag = tag;
Py_INCREF(self->tag);
- Py_CLEAR(self->text);
- self->text = text ? text : Py_None;
- Py_INCREF(self->text);
-
- Py_CLEAR(self->tail);
- self->tail = tail ? tail : Py_None;
- Py_INCREF(self->tail);
+ _clear_joined_ptr(&self->text);
+ self->text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None;
+ Py_INCREF(JOIN_OBJ(self->text));
+
+ _clear_joined_ptr(&self->tail);
+ self->tail = tail ? JOIN_SET(tail, PyList_CheckExact(tail)) : Py_None;
+ Py_INCREF(JOIN_OBJ(self->tail));
/* Handle ATTRIB and CHILDREN. */
if (!children && !attrib)
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list