[lxml-dev] thread-related crash when using xslt

Stefan Behnel stefan_ml at behnel.de
Fri Feb 27 13:36:33 CET 2009


Stefan Behnel wrote:
> Martijn Faassen wrote:
>> Attached is a small tarball that demonstrates code that crashes when the
>> code is run in a thread but doesn't crash when it is run stand-alone. I
>> isolated the specific XSLT + XML combination that seems to trigger this
>> crash. I suspect it has to do with passing an XSLT object to a thread.
> 
> Ok, this is plain evil. What you do here is this:
> 
>      ...
>      <tr class="odd">
>         <xsl:attribute name="class">top-row</xsl:attribute>
>      ...
> 
> Note how the attribute value is changed after being set. In libxslt, this
> leads to a result tree update that removes the old attribute and replaces
> it by the new one.

Here is a minimal fix for the problem. There may be special cases where
this might not work (my guess would be custom XSLT elements), but at least
it works safely in this case.

Stefan


=== src/lxml/xslt.pxi
==================================================================
--- src/lxml/xslt.pxi   (revision 5056)
+++ src/lxml/xslt.pxi   (local)
@@ -486,7 +486,15 @@
             _destroyFakeDoc(input_doc._c_doc, c_doc)
             python.PyErr_NoMemory()

-        initTransformDict(transform_ctxt)
+        # using the stylesheet dict is safer than using a possibly
+        # unrelated dict from the current thread.  Almost all
+        # non-input tag/attr names will come from the stylesheet
+        # anyway.
+        if transform_ctxt.dict is not NULL:
+            xmlparser.xmlDictFree(transform_ctxt.dict)
+        transform_ctxt.dict = self._c_style.doc.dict
+        xmlparser.xmlDictReference(transform_ctxt.dict)
+
         xslt.xsltSetCtxtParseOptions(
             transform_ctxt, input_doc._parser._parse_options)




More information about the lxml-dev mailing list