Bug 55357 - XSLT extension functions
Summary: XSLT extension functions
Status: UNCONFIRMED
Alias: None
Product: WebKit
Classification: Unclassified
Component: XML (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Enhancement
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-28 01:43 PST by Andreas Wictor
Modified: 2023-04-27 12:57 PDT (History)
4 users (show)

See Also:


Attachments
The patch (71.24 KB, patch)
2011-02-28 01:43 PST, Andreas Wictor
abarth: review-
Details | Formatted Diff | Diff
Full example mentioned in description (2.84 KB, text/html)
2011-02-28 01:45 PST, Andreas Wictor
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Wictor 2011-02-28 01:43:45 PST
Created attachment 84031 [details]
The patch

In MSIE, Microsoft offers the ability to extend XPath expressions in XSLT stylesheets using
JavaScript functions. This is done by calling the addObject() method on the XSLTemplate ActiveX
object.

This patch adds similar functionality to WebKit by adding methods to the XSLTProcessor object
(modelled after the existing *Parameter() methods): setExtensionObject(), getExtensionObject(),
removeExtensionObject() and clearExtensionObjects().

Basically, a JavaScript object is bound to an XML Namespace and member functions in this object
can then be referenced in the XSLT stylesheet as qualified XPath functions. Exceptions thrown in
the extension functions are propagated back to the XSLTProcessor.transform() caller.

JavaScript code:

  var myExt = {
    currentDate: function() {
      return new Date().toString();
    }
  };

  var proc = new XSLTProcessor();
  proc.importStylesheet(stylesheet);
  proc.setExtensionObject("urn:x-my-extensions", myExt)
  var result = proc.transformToDocument(page);


XSLT stylesheet:

<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'
                xmlns:my-ext='urn:x-my-extensions'>
  ...
    <address>Generated on <xsl:value-of select='my-ext:currentDate()' /> </address>
  ...
</xsl:stylesheet>


Please see the attached cross-browser example for the full example.

The patch is pretty straight-forward, except for xml/XSLTExtensions.cpp and
xml/XSLTProcessorLibxslt.cpp. Because the XSLT subsystem uses its own DOM, and we need to pass
nodes between XSLT and JavaScript, we link the two models together using LibXxml's _private
field.

This is why we no longer serialize the DOM to text and feed it into the other DOM's parser, but
instead traverse the tree and manually build the other DOM. This way, we can easily find the
WebKit DOM object when passing arguments to the JavaScript function.
Comment 1 Andreas Wictor 2011-02-28 01:45:46 PST
Created attachment 84032 [details]
Full example mentioned in description
Comment 2 Alexey Proskuryakov 2011-02-28 10:54:22 PST
Does this also work in Firefox? It's not obvious why this functionality is a good addition to WebKit.

Running arbitrary JavaScript during transformations sounds like it could trigger lots of subtle bugs, including security ones.

> This is why we no longer serialize the DOM to text and feed it into the other DOM's parser, but
instead traverse the tree and manually build the other DOM.

This is an independent change that should be done in a separate patch. It could enable fixing issues like bug 14101, possibly at the cost of some formal spec compliance.
Comment 3 Martin Blom 2011-03-02 09:11:24 PST
(In reply to comment #2)
> Does this also work in Firefox? It's not obvious why this functionality is a good addition to WebKit.

Being able to extend XSLT with custom functions is very useful. Think of all the good things that has come from the EXSLT project, for instance.

> Running arbitrary JavaScript during transformations sounds like it could trigger lots of subtle bugs, including security ones.

Calling JavaScript from the XSLT processor can only be initialized by a call to XSLTProcessor.tranformToDocument()/transformToFragment() so the only thing that we are aware of is when the callback initializes another transformation.

We have a proposed solution for this in bug 41348: Remove global variables from XSLTProcessorLibxslt.cpp

> > This is why we no longer serialize the DOM to text and feed it into the other DOM's parser, but
> instead traverse the tree and manually build the other DOM.
> 
> This is an independent change that should be done in a separate patch. It could enable fixing issues like bug 14101, possibly at the cost of some formal spec compliance.

The DOM construction thing does not really help with the bug you refer to, since the libxslt API does not provide a way to specify anything else than strings or XPath expressions for parameters.

It might be possible, however, use a similar approach that we used in the patch to register a special "parameter lookup" XPath function that converts the WebKit XPath::Value into something libxslt likes (see extFunction() and xpathResult() in the patch)
Comment 4 Alexey Proskuryakov 2011-03-02 11:32:12 PST
> Think of all the good things that has come from the EXSLT project, for instance.

Note that we don't enable EXSLT. That is tracked by bug 4079, but it's not clear if enabling it would do WebKit any good either.

> the only thing that we are aware of is when the callback initializes another transformation.

I've been thinking about changes to DOM tree specifically, but there are likely many attack vectors.
Comment 5 Martin Blom 2011-03-03 01:24:27 PST
(In reply to comment #4)
> > Think of all the good things that has come from the EXSLT project, for instance.
> 
> Note that we don't enable EXSLT. That is tracked by bug 4079, but it's not clear if enabling it would do WebKit any good either.

XSLT is a rather nice templating language in theory. However, in practice it is often pretty much useless for anything but very trivial transformations, if the processor cannot be extended with custom functions.

A great benefit of allowing the XSLTProcessor caller to extend the built-in set of XPath functions is that the browser may concern itself less with what extended APIs to provide. The user can just plug it in when setting up the transformation.

> > the only thing that we are aware of is when the callback initializes another transformation.
> 
> I've been thinking about changes to DOM tree specifically, but there are likely many attack vectors.

Can you please clarify that? XSLTProcessor.transfromTo*() are synchronous calls, so they should really not be any different from say the NS resolver callback in Document.evaluate().
Comment 6 Alexey Proskuryakov 2011-03-03 09:19:22 PST
Sure, XPath's calls out to NSResolver are no good either.
Comment 7 Adam Barth 2011-04-17 21:53:26 PDT
Comment on attachment 84031 [details]
The patch

This patch is very large, and it's not clear that adding this feature benefits the project.
Comment 8 Ahmad Saleem 2023-04-27 12:57:15 PDT
This was about extending functionality similar to IE.

IE is now long gone, I am not sure, any other browser have this functionality as well.

No sure on standards as well.

Do we need to track this?