[XML-SIG] 4XSLT Bug Affecting Document()

Thomas B. Passin tpassin@home.com
Wed, 16 Jan 2002 00:21:32 -0500


While running transformations from Zope using 4xslt from 4suite 0.11.1, I
found a bug that prevented document() from finding the specified file.  This
occurs in Windows, when a relative uri is used.  I have hacked up a partial
fix, but really a more comprehensive fix is needed.

The problem fundamentally arises (I think) because urlparse.urlparse(uri)
can wrongly think that a Windows drive specifier is a scheme.  Thus, this
code fragment from Ft\Uri.py does not work right (lines 20-23):

        scheme = urlparse.urlparse(uri)[0]
        if scheme in ['', 'http', 'ftp', 'file', 'gopher']:
            uri = urllib.basejoin(base, uri)
        return uri

When you run from the stylesheet directory, and the relative document uri is
in the same directory, everything works.  But when invoked from Zope, you
are running in a different directory, possibly on a different drive, and it
fails.  In my case, if I invoked document('file.xml') in my stylesheet on
the d: drive, the above code returned d:file.xml which is not correct - it
would depend on whatever default directory happened to be in effect on the
d: drive.

This code is called from file xml\xslt\XsltFunctions.py (for python 1.5.2),
at line 55.  I decided this would be the best place for a quick fix.  Here
is my temporary hack - I added these lines:

            # Fix for Windows relative file uris
            import os,os.path
            if os.name in ['nt','dos']:   # maybe use sys.platform instead?
                # Check for relative path
                basepath=os.path.dirname(baseUri)
                candidate=Conversions.StringValue(object) # The uri from
document(uri)
                objectpath=os.path.dirname(candidate)
                if not os.path.isdir(objectpath):
                    uri=os.path.normpath(os.path.join(basepath,candidate))

The code assumes that, if there is a non-empty directory part of the path
(found by isdir()), then we have an absolute (file) uri that does not need
to be fixed.  This probably won't handle all relative uris - those not in
the stylesheet or source document directories may not work right, and there
are other places that apparently ought to changed in similar ways too, but
this is enough to make my current stylesheets work.

I think the code in Ft\Uri.py should be fixed to make sure it works.
Really, urlparse should be fixed but we need to do something to make sure
4xslt will work with a range of versions of python, so we can't depend on
some particualr version of urlparse.

What do our 4Thought people think is the best approach here?  A complete fix
for any possible relative path specification may not be easy, since they may
start with various numbers of ../../ or ./ steps, and still be recognized as
a relative specification - and then, only adjusted if it is a relative
***file*** specification.  Also, the fix probably should be robust enough to
handle forward and backslashes in the relative path, just in case they
appear.

Cheers,

Tom P