[Python-checkins] r84692 - in python/branches/py3k: Lib/test/test_pyexpat.py Modules/pyexpat.c

victor.stinner python-checkins at python.org
Sat Sep 11 00:25:19 CEST 2010


Author: victor.stinner
Date: Sat Sep 11 00:25:19 2010
New Revision: 84692

Log:
Issue #9402: pyexpat uses Py_DECREF() instead of PyObject_DEL()

Fix a crash if Python is compiled in pydebug mode.


Modified:
   python/branches/py3k/Lib/test/test_pyexpat.py
   python/branches/py3k/Modules/pyexpat.c

Modified: python/branches/py3k/Lib/test/test_pyexpat.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pyexpat.py	(original)
+++ python/branches/py3k/Lib/test/test_pyexpat.py	Sat Sep 11 00:25:19 2010
@@ -221,6 +221,25 @@
             # L should have the same string repeated over and over.
             self.assertTrue(tag is entry)
 
+    def test_issue9402(self):
+        # create an ExternalEntityParserCreate with buffer text
+        class ExternalOutputter:
+            def __init__(self, parser):
+                self.parser = parser
+                self.parser_result = None
+
+            def ExternalEntityRefHandler(self, context, base, sysId, pubId):
+                external_parser = self.parser.ExternalEntityParserCreate("")
+                self.parser_result = external_parser.Parse("", 1)
+                return 1
+
+        parser = expat.ParserCreate(namespace_separator='!')
+        parser.buffer_text = 1
+        out = ExternalOutputter(parser)
+        parser.ExternalEntityRefHandler = out.ExternalEntityRefHandler
+        parser.Parse(data, 1)
+        self.assertEquals(out.parser_result, 1)
+
 
 class BufferTextTest(unittest.TestCase):
     def setUp(self):

Modified: python/branches/py3k/Modules/pyexpat.c
==============================================================================
--- python/branches/py3k/Modules/pyexpat.c	(original)
+++ python/branches/py3k/Modules/pyexpat.c	Sat Sep 11 00:25:19 2010
@@ -973,21 +973,7 @@
         return NULL;
     new_parser->buffer_size = self->buffer_size;
     new_parser->buffer_used = 0;
-    if (self->buffer != NULL) {
-        new_parser->buffer = malloc(new_parser->buffer_size);
-        if (new_parser->buffer == NULL) {
-#ifndef Py_TPFLAGS_HAVE_GC
-            /* Code for versions 2.0 and 2.1 */
-            PyObject_Del(new_parser);
-#else
-            /* Code for versions 2.2 and later. */
-            PyObject_GC_Del(new_parser);
-#endif
-            return PyErr_NoMemory();
-        }
-    }
-    else
-        new_parser->buffer = NULL;
+    new_parser->buffer = NULL;
     new_parser->ordered_attributes = self->ordered_attributes;
     new_parser->specified_attributes = self->specified_attributes;
     new_parser->in_callback = 0;
@@ -1003,6 +989,13 @@
     PyObject_GC_Init(new_parser);
 #endif
 
+    if (self->buffer != NULL) {
+        new_parser->buffer = malloc(new_parser->buffer_size);
+        if (new_parser->buffer == NULL) {
+            Py_DECREF(new_parser);
+            return PyErr_NoMemory();
+        }
+    }
     if (!new_parser->itself) {
         Py_DECREF(new_parser);
         return PyErr_NoMemory();


More information about the Python-checkins mailing list