Bug #1968
closedShared indexes when xsl:key definition is context sensitive
0%
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.
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.
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.
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
Updated by Michael Kay over 10 years ago
- Status changed from In Progress to Resolved
Updated by O'Neil Delpratt about 10 years ago
- Fixed in version changed from 9.6 to 9.6.0.1
Updated by O'Neil Delpratt about 10 years ago
- Status changed from Resolved to Closed
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