Project

Profile

Help

Bug #3109

closed

XSLT functions are exposed to xsl:evaluate but shouldn't be exposed

Added by Martin Honnen over 7 years ago. Updated over 6 years ago.

Status:
Closed
Priority:
Low
Assignee:
Category:
XSLT conformance
Sprint/Milestone:
-
Start date:
2017-01-16
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
9.7
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:

Description

Both the latest internal draft of the XSLT 3.0 spec in https://www.w3.org/XML/Group/qtspecs/specifications/xslt-30/html/#dynamic-xpath as well as the official https://www.w3.org/TR/xslt-30/#element-evaluate say about the function signatures in the context of dynamic XPath evaluation using xsl:evaluate: "Note that this set deliberately excludes XSLT-defined functions in the standard function namespace".

However when I run tests with Saxon 9.7 EE I find that xsl:evaluate exposes XSLT only functions like document@, @copy-of or key to @xsl:evaluate@.

Here is a test case that checks whether function-lookup returns a function for certain XSLT functions:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
	xmlns:math="http://www.w3.org/2005/xpath-functions/math"
	xmlns:array="http://www.w3.org/2005/xpath-functions/array"
	xmlns:map="http://www.w3.org/2005/xpath-functions/map"
	expand-text="true"
	exclude-result-prefixes="array fn map math xs">
	
	<xsl:param name="function-list" as="xs:string*" select="'document', 'key', 'current', 'copy-of', 'snapshot'"/>
	<xsl:param name="arities" as="xs:integer*" select="1, 2, 0, 1, 1"/>
	
	<xsl:output method="xml" indent="yes"/>
	
	<xsl:template name="main" match="/">
		<results>
			<xsl:for-each select="$function-list">
				<xsl:variable name="pos" select="position()"/>
				<xsl:variable name="xpath" as="xs:string">
					exists(function-lookup(xs:QName('fn:{.}'), {$arities[$pos]}))
				</xsl:variable>
				<result function="{.}">
					<xsl:evaluate xpath="$xpath"></xsl:evaluate>
				</result>
			</xsl:for-each>
		</results>		
	</xsl:template>
	
</xsl:stylesheet>

When run with Saxon 9.7 EE (Saxon-EE 9.7.0.14J) from the command line with -it:main it outputs

<?xml version="1.0" encoding="UTF-8"?>
<results>
   <result function="document">true</result>
   <result function="key">true</result>
   <result function="current">true</result>
   <result function="copy-of">true</result>
   <result function="snapshot">true</result>
</results>

Exselt outputs


<?xml version="1.0" encoding="UTF-8"?>
<results>
   <result function="document">false</result>
   <result function="key">false</result>
   <result function="current">false</result>
   <result function="copy-of">false</result>
   <result function="snapshot">false</result>
</results>

Another test case I wrote is

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
	xmlns:math="http://www.w3.org/2005/xpath-functions/math"
	xmlns:array="http://www.w3.org/2005/xpath-functions/array"
	xmlns:map="http://www.w3.org/2005/xpath-functions/map"
	exclude-result-prefixes="array fn map math xs">
	
	<xsl:output method="xml"/>
	
	<xsl:template name="main" match="/">
		<xsl:sequence
			select="
			let $f := function-lookup(xs:QName('fn:document'), 1)
			return
			if (exists($f)) then
			$f('')
			else
			'not found'"/>
		<xsl:variable name="path" as="xs:string">
			let $f := function-lookup(xs:QName('fn:document'), 1)
			return
			if (exists($f)) then
			$f('')
			else
			'not found'</xsl:variable>
		<xsl:evaluate xpath="$path"/>
	</xsl:template>
	
</xsl:stylesheet>

which tests whether document is not only exposed but also callable, indeed Saxon calls it and returns the stylesheet while Exselt return the not found for the @xsl:evaluate@.

Actions #1

Updated by Michael Kay over 7 years ago

The spec of fn:function-lookup says:

If the arguments to fn:function-lookup identify a function that is present in the static context of the function call, the function will always return the same function that a static reference to this function would bind to. If there is no such function in the static context, then the results depend on what is present in the dynamic context, which is ·implementation-defined·.

I seem to recall there was a fair bit of discussion about situations that might lead to the dynamic context containing functions not present in the static context, but I don't recall the details - I think a number of people had different reasons for suggesting this could be useful. For Saxon, certainly, it's useful not to have to impose what would be a completely artificial restriction.

Actions #2

Updated by Michael Kay over 7 years ago

Further, the XSLT 3.0 spec says of xsl:evaluate, "All other aspects of the dynamic context are the same as the dynamic context for the xsl:evaluate instruction itself", which suggests that the dynamic context must include the fn:document function. Though I'm sure that was never intended.

Actions #3

Updated by Michael Kay about 7 years ago

The spec has now been clarified (see https://www.w3.org/Bugs/Public/show_bug.cgi?id=30049)

The functions available in the dynamic context of the xsl:evaluate instruction are now aligned with those in the static context (which exclude XSLT-specific function like key()) so you can no longer by-pass the restrictions in what functions are available by finding them dynamically.

If a function is available that shouldn't be, I don't think that's a serious enough bug to justify a patch for 9.7, which we now need to manage for stability rather than for conformance. But I'll try and make sure we get it right for 9.8.

Actions #4

Updated by Michael Kay about 7 years ago

  • Assignee set to Michael Kay
Actions #5

Updated by Michael Kay over 6 years ago

  • Status changed from New to Resolved

Saxon 9.8 is conformant with the current spec here (which permits dynamic calls to XSLT-defined functions at implementation discretion, but disallowed static calls).

Saxon 9.7 was published before the spec was clarified and will not be updated because we are now managing it for stability rather than conformance.

A test case evaluate-048 has been added.

Actions #6

Updated by Michael Kay over 6 years ago

  • Status changed from Resolved to Closed

Please register to edit this issue

Also available in: Atom PDF