[Lxml-checkins] r47319 - in lxml/branch/lxml-1.3: . src/lxml

scoder at codespeak.net scoder at codespeak.net
Mon Oct 8 22:59:19 CEST 2007


Author: scoder
Date: Mon Oct  8 22:59:18 2007
New Revision: 47319

Modified:
   lxml/branch/lxml-1.3/CHANGES.txt
   lxml/branch/lxml-1.3/src/lxml/etree.pyx
Log:
make namespace prefix counter a Python long to avoid crashes by counter overflow

Modified: lxml/branch/lxml-1.3/CHANGES.txt
==============================================================================
--- lxml/branch/lxml-1.3/CHANGES.txt	(original)
+++ lxml/branch/lxml-1.3/CHANGES.txt	Mon Oct  8 22:59:18 2007
@@ -11,6 +11,9 @@
 Bugs fixed
 ----------
 
+* lxml.etree could crash when adding more than 10000 namespaces to a
+  document
+
 * lxml failed to serialise namespace declarations of elements other than the
   root node of a tree
 

Modified: lxml/branch/lxml-1.3/src/lxml/etree.pyx
==============================================================================
--- lxml/branch/lxml-1.3/src/lxml/etree.pyx	(original)
+++ lxml/branch/lxml-1.3/src/lxml/etree.pyx	Mon Oct  8 22:59:18 2007
@@ -231,7 +231,7 @@
     When instances of this class are garbage collected, the libxml
     document is cleaned up.
     """
-    cdef int _ns_counter
+    cdef object _ns_counter
     cdef xmlDoc* _c_doc
     cdef _BaseParser _parser
     
@@ -297,7 +297,7 @@
             return self._c_doc.URL
 
     cdef buildNewPrefix(self):
-        ns = python.PyString_FromFormat("ns%d", self._ns_counter)
+        ns = "ns%d" % self._ns_counter
         self._ns_counter = self._ns_counter + 1
         return ns
 
@@ -306,7 +306,6 @@
         """Get or create namespace structure for a node.  Reuses the prefix if
         possible.
         """
-        cdef int i
         cdef xmlNs* c_ns
         cdef xmlNs* c_doc_ns
         # look for existing ns
@@ -317,15 +316,12 @@
         if c_prefix is NULL or \
                tree.xmlSearchNs(self._c_doc, c_node, c_prefix) is not NULL:
             # try to simulate ElementTree's namespace prefix creation
-            for i from 0 <= i < 10000:
+            while 1:
                 prefix = self.buildNewPrefix()
                 c_prefix = _cstr(prefix)
                 # make sure it's not used already
                 if tree.xmlSearchNs(self._c_doc, c_node, c_prefix) is NULL:
                     break
-            if i >= 10000:
-                # XXX too many prefixes in use - this is pretty bad!
-                return NULL
 
         return tree.xmlNewNs(c_node, c_href, c_prefix)
 
@@ -335,8 +331,8 @@
         c_ns = self._findOrBuildNodeNs(c_node, href, NULL)
         tree.xmlSetNs(c_node, c_ns)
 
-    cdef void _setNodeNamespaces(self, xmlNode* c_node,
-                                 object node_ns_utf, object nsmap):
+    cdef int _setNodeNamespaces(self, xmlNode* c_node,
+                                object node_ns_utf, object nsmap) except -1:
         """Lookup current namespace prefixes, then set namespace structure for
         node and register new ns-prefix mappings.
 
@@ -349,7 +345,7 @@
         if not nsmap:
             if node_ns_utf is not None:
                 self._setNodeNs(c_node, _cstr(node_ns_utf))
-            return
+            return 0
 
         c_doc  = self._c_doc
         for prefix, href in nsmap.items():
@@ -370,12 +366,13 @@
 
         if node_ns_utf is not None:
             self._setNodeNs(c_node, _cstr(node_ns_utf))
+        return 0
 
 cdef _Document _documentFactory(xmlDoc* c_doc, _BaseParser parser):
     cdef _Document result
     result = _Document()
     result._c_doc = c_doc
-    result._ns_counter = 0
+    result._ns_counter = 0L
     if parser is None:
         parser = __GLOBAL_PARSER_CONTEXT.getDefaultParser()
     result._parser = parser


More information about the lxml-checkins mailing list