Re: [xslt] Few questions



On Fri, Sep 12, 2003 at 05:08:40PM -0400, Daniel Veillard wrote:
> > When xsltApplyOneTemplate finds the <fallback node, it looks for 
> > the compiled data in the _private pointer, but the fallback private 
> > ptr is NULL, and there comes the error.
> 
>   It's possible that the compilation process didn't recurse inside
> myown:ext-tag though that would be surprizing.
That is what I was thinking about at first. However, from preproc.c, it 
seems to me that <fallback nodes are _not_ compiled (xsltStylePreCompute()), 
they are just looked up when an extension tag is found but cannot be 
handled. The problem seems more like the library does not expect to 
find the <fallback node in the children list of the node
passed to xsltApplyOneTemplate. Let's see... given a stylesheet
like:
---- fuffa.xsl
<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:template match="fuffa">
    <xsl:fallback>
    This is fuffa
    </xsl:fallback>
  </xsl:template>
</xsl:stylesheet>
----				      
And given a xml document like
---- fuffa.xml
<?xml version="1.0" encoding="ISO8859-1" standalone="yes"?>
<?xml-stylesheet type="text/xsl" method="http" href="./fuffa.xsl"
  		 media="screen" alternate="no" title="Fuffa"
		 charset="ISO8859-1"?>

<fuffa>
  This is fuffa
</fuffa>
----
running ``xsltproc fuffa.xml'' I get:
---
xsltApplyOneTemplate: fallback was not compiled
---
This error is printed from 
  libxslt-1.0.32:transform.c:xsltApplyOneTemplate():4283
by something like:
---
xsltGenericError(xsltGenericDebugContext, 
		"xsltApplyOneTemplate: %s was not compiled\n", 
		cur->name);
---
However: 
  - xsltGenericError(xsltGenericDebugContext would cause a segfault
    in any application that changes one (or both) of the error/debug
    handlers (my case).
  - from ``REC-xslt-19991116.html#fallback'' it seems like 
      "Normally, instantiating an xsl:fallback element does nothing."
    so I may be wrong, but I believe in this case the fallback node 
    should be just ignored.  

The following micro-patch should solve the problem:
------
diff -Naur libxslt-1.0.32/libxslt/transform.c libxslt-1.0.32.patched/libxslt/transform.c
--- libxslt-1.0.32/libxslt/transform.c	2003-08-10 00:20:28.000000000 +0200
+++ libxslt-1.0.32.patched/libxslt/transform.c	2003-09-14 14:58:53.000000000 +0200
@@ -1490,8 +1490,8 @@
 
             if (info == NULL) {
                 if (IS_XSLT_NAME(cur, "message")) {
-                    xsltMessage(ctxt, node, cur);
-                } else {
+                  xsltMessage(ctxt, node, cur);
+                } else if (!IS_XSLT_NAME(cur, "fallback")) {
                     /*
                      * That's an error try to apply one of the fallback cases
                      */
-----

>   That doesn't work. If the module call xmlParserCleanup, the entities
> for examples are destroyed, they are global to the library but not handled
> by the thread module. If you use code you have no source nor control
> to and it makes crazy thing there is no way I can help you, nobody can.
Most of the modules are not `closed' binary. My own code will be
opensource and I don't want to work with closed sources either 
(both for philosophical and practical reasons :). The closed `binary' 
source is just the worst case scenario. However, the problem does
not change much: I cannot pretend to rewrite (or debug) all the 
modules using libxml nor that everyone using libxml or libxslt will 
follow a particular standard (unless they are told to do so). 

And the working model I described here is not that uncommon: think of 
apache, php, openldap (slapd), bayonne, asterisk, mysql (for user 
defined functions).. they all load modules at run time. Modules
normally made by third parties that are usually initialized once
and then called in a big loop (that may make use of libxml
in the most unthinkable ways and that may be closed source or
made by someone we know nothing about - that's usually the whole
purpose of having modules). 
It doesn't however seems to me that crazy if those modules initialize 
the library just once and then assume the globals will have the same
value every time. Otherwise, they would have to initialize the library
on each iteration of the loop, which means: on each apache request,
each time a particular php function is called, each time openldap
needs to access a particular backend, each time...
And it is not that much uncommon to have many modules using libxml
either: it is a nice library, and as an example, just in apache there 
are at least 3 modules I know of making use of libxml, that, AFAIK may
(will) cause problems if used together.

>   You're starting to enter a very crazy model which is that you have
> binary code (using libxml2) that you can't trust and debug. Very sincerely
> I'm not interested in debugging that kind of madness otherwise I would
> be selling proprietary software. To be frank it's your problem, I would
> just say don't do that.
I don't want to debug somebody else code either. I just would like
to know what would be for my module ``the right thing'' to do for
me to be able to say ``hey, it's your problem: you don't access
libxml correctly''!
At time of writing, if I simply ignore the problem I end up with something 
which is _unusable_ most of the times if used with other modules linked
with libxml, either crashing my module or crashing another module the first 
time it accesses libxml (or getting unpredictable results). gdb is useless: 
I could solve the problem for the combination of modules I'm using, but it 
would be just a workaround for a problem I already know where it comes from 
and I won't have any guarantee that any new module using libxml won't crash 
my own. 
The problem must be solved at the root. Copying the global state was an attempt
to do so, and thanks to that most things will work correctly (haven't noticed an 
error yet), and will work even when other modules access the library (as they want) 
and (as you pointed out) as long as they don't change memory handlers or change 
(in some way) those ``private globals''. 
However this is still a workaround... it won't _always_ work...

Another solution could be for any module to call xmlParserCleanup 
after each iteration in the loop. This way, the library would
be left clean for the next module to be run, and would be
cleaned by whoever changed the memory routines (if they were
changed). 
This could be one of those ``right thing to do'', but I'd 
need everybody who creates a module (for any application)
using libxml to follow this ``standard'', and to be able
to open up a bug report saying: ``hey, how you use libxml 
in your module breaks mine, look at http://... and change 
this code that way...''.

>   There are global variables which are not stored into the thread system
> like the entities. They are allocated at initialization time. They use
> the memory system as a result.
Well, the change of ``memory'' handlers I choose as an example is
quite uncommon (again, probably the worst case scenario). The purpose
of my memcpys was for me to have something that works _most_ of the 
times without touching the code written by others (and most of the 
times, problems are due the error handlers being changed and some sax 
defaults modifyed). 

>   No, there are others, but they are not "exported" from an API point
> of view, the application is not supposed to access them directly, like
>    static xmlHashTablePtr xmlPredefinedEntities = NULL;
Ok, this is what I wanted to know :).

> > I apologize if I haven't been clear enough or if I may sound rude.
>   Same here. You're trying to do far too complex stuff IMHO. I don't
> know where you design comes from, obviously it wasn't discussed here 
> before, libxml2 may not be adequate. 
Well, I looked around for a while but libxml seemed to me like the
best choice. If you (or anybody on the list) can suggest any other 
opensource xml+xslt library that keeps the _entire_ state in a structure 
which is either always passed as an argument to the functions or stored 
somewhere I can make copies of as good (and as fast) as libxml, you're 
welcome...
Still, if you intend by ``design'' the execution path followed by 
modules I described, it does not look that uncommon to me, and as
more ``modules'' will be using libxml and more programs be 
``modularized'', the problem will become even worse...

I'm glad we finally got to understand 
each other :), thanks a lot,

Bye,
Carlo

-- 
  GPG Fingerprint: 2383 7B14 4D08 53A4 2C1A CA29 9E98 5431 1A68 6975
                        -------------
I think it's a new feature.  Don't tell anyone it was an accident.  :-)
         -- Larry Wall on s/foo/bar/eieio in <10911@jpl-devvax.JPL.NASA.GOV>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]