Project

Profile

Help

Bug #1968

closed

Shared indexes when xsl:key definition is context sensitive

Added by Michael Kay almost 11 years ago. Updated about 9 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
XSLT conformance
Sprint/Milestone:
-
Start date:
2013-12-30
Due date:
% Done:

0%

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

Description

I haven't confirmed this by testing, but I suspect there could be a problem if a key is defined like this:

<xsl:variable name="v" select="base-uri(.)"/>

<xsl:key name="k" match="*[. = $v]" use="name()"/>

<xsl:param name="p" as="document-node()"/>

<xsl:template match="/">

<xsl:value-of select="key('k', 'abcd', $p)"/>

</xsl:template>

If this stylesheet is invoked twice with different initial context items but with the same value of $p, the two invocations will attempt to share the same index supporting the key definition k, but actually the key definitions are different for the two stylesheet invocations because of the dependency on $v.

Actions #1

Updated by Michael Kay over 10 years ago

I have written xslt30 test key-085a/b which confirms that this bug exists. There are two tests using the same stylesheet and source document but with different values of a global parameter; the key index is incorrectly reused for the second test if both tests are run together.

Actions #2

Updated by Michael Kay over 10 years ago

  • Priority changed from Low to Normal

The first step is to detect that an xsl:key declaration is not reusable across transformations. As a first step it is sufficient to test whether either the match pattern or use expression contains a global variable reference. We ought also to test that the key is not dependent on a non-reusable key, which is a rather more complex test, and is getting pretty arcane.

The next step is that if a key is non-reusable, we need to hold details of the document indexes at the level of the Controller rather than the Executable (currently the KeyManager is owned by the Executable). This is trickier because all requests for indexed access (for example the selectByKey() method) go directly to the shared KeyManager. Probably the cleanest approach is to have a local KeyManager owned by the Transformer, and a shared KeyManager owned by the Executable, and for all requests to go first to the local KeyManager, which delegates to the shared one if the key is reusable.

Actions #3

Updated by Michael Kay over 10 years ago

  • Status changed from New to In Progress
  • Found in version set to 9.5

I have implemented a solution to this in the 9.6 branch, but I'm not going to retro-fit it to 9.5 unless anyone actually encounters the problem.

The solution involves:

  • changes to XSLKey to detect that the match pattern or use expression has dependencies on global variables, user-written functions, or user-written templates

  • in this case, marking the KeyDefinitionSet as non-shareable

  • in KeyManager, where the KeyDefinitionSet is non-shareable, storing and retrieving indexes locally in the Controller, rather than in the shared WeakHashMap contained within the KeyManager itself

Actions #4

Updated by Michael Kay over 10 years ago

  • Status changed from In Progress to Resolved
Actions #5

Updated by Michael Kay over 10 years ago

  • Fixed in version set to 9.6
Actions #6

Updated by O'Neil Delpratt about 10 years ago

  • Fixed in version changed from 9.6 to 9.6.0.1
Actions #7

Updated by O'Neil Delpratt about 10 years ago

  • Status changed from Resolved to Closed
Actions #8

Updated by O'Neil Delpratt about 9 years ago

  • Applies to branch 9.5, 9.6 added
  • Fix Committed on Branch 9.6 added

Please register to edit this issue

Also available in: Atom PDF