Bug #2818
closedxsl:next-match as last instruction in a named template causes IndexOutOfBoundsException
100%
Description
The TEI docx/from stylesheets contain xsl:next-match at https://github.com/TEIC/Stylesheets/blob/dev/docx/from/wordsections.xsl#L119
This template is triggered by a docx containing:
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" >
<w:body>
<w:p>
<w:r>
<w:t>foo</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:sectPr >
<w:pgSz w:h="15840" w:w="12240"/>
<w:pgMar w:gutter="0" w:footer="720" w:header="720" w:left="1440" w:bottom="1440" w:right="1440" w:top="1440"/>
<w:cols w:space="720"/>
<w:docGrid w:linePitch="360"/>
</w:sectPr>
</w:pPr>
</w:p>
</w:body>
</w:document>
With Saxon HE 9.7.0.5 or 9.7.0.6 this causes:
java.lang.IndexOutOfBoundsException: Index: 10, Size: 1
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at net.sf.saxon.expr.XPathContextMajor.getTargetComponent(XPathContextMajor.java:692)
at net.sf.saxon.expr.instruct.CallTemplate.processLeavingTail(CallTemplate.java:382)
at net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:835)
at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:711)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:353)
at net.sf.saxon.expr.instruct.NextMatch$NextMatchPackage.processLeavingTail(NextMatch.java:208)
at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:300)
at net.sf.saxon.expr.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:255)
at net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:835)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:149)
at net.sf.saxon.expr.instruct.ForEachGroup.processLeavingTail(ForEachGroup.java:584)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:353)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:456)
at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:298)
at net.sf.saxon.expr.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:255)
at net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:835)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:149)
at net.sf.saxon.expr.instruct.ForEachGroup.processLeavingTail(ForEachGroup.java:584)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:149)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:364)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:311)
at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:711)
at net.sf.saxon.expr.instruct.NamedTemplate.expand(NamedTemplate.java:271)
at net.sf.saxon.expr.instruct.CallTemplate.process(CallTemplate.java:356)
at net.sf.saxon.expr.instruct.CallTemplate.processLeavingTail(CallTemplate.java:412)
at net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:835)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:149)
at net.sf.saxon.expr.instruct.ForEachGroup.processLeavingTail(ForEachGroup.java:584)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653)
at net.sf.saxon.expr.instruct.NamedTemplate.expand(NamedTemplate.java:271)
at net.sf.saxon.expr.instruct.CallTemplate.process(CallTemplate.java:356)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:364)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:311)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:149)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:364)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:311)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:353)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:456)
at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:298)
at net.sf.saxon.expr.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:255)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:149)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:364)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:311)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:353)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:456)
at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:298)
at net.sf.saxon.expr.instruct.ApplyTemplates.process(ApplyTemplates.java:251)
at net.sf.saxon.expr.instruct.ForEach.processLeavingTail(ForEach.java:453)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:149)
at net.sf.saxon.expr.instruct.DocumentInstr.evaluateItem(DocumentInstr.java:330)
at net.sf.saxon.expr.instruct.DocumentInstr.evaluateItem(DocumentInstr.java:54)
at net.sf.saxon.expr.parser.ExpressionTool.evaluate(ExpressionTool.java:304)
at net.sf.saxon.expr.LetExpression.eval(LetExpression.java:500)
at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:702)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:353)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:456)
at net.sf.saxon.Controller.transformDocument(Controller.java:2270)
at net.sf.saxon.Controller.transform(Controller.java:1847)
at net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:579)
Interestingly, a workaround is to insert an xsl:message immediately after the xsl:next-match tag.
May be related to the fixed issue 2770
Related issues
Updated by Michael Kay over 8 years ago
Thanks for reporting it. It's related to 2770 in the sense that it's caused by a failure of some component invocation construct (of which xsl:next-match is an example) to set the current component in the context; this is needed by the component binding mechanism to support XSLT 3.0 independently-compiled packages. Specifically in this case it appears to be the code for optimizing tail calls on xsl:next-match (evidenced by the presence of NextMatchPackage in the stack trace, and also by the fact that moving the next-match to a non-tail position (by adding xsl:message) eliminates the problem.
I can't immediately see where the problem lies in the code, and I can't immediately see how it can arise since the "component" in this case is a mode, and xsl:next-match never changes the mode. It will need a repro. Getting a big set of stylesheets like TEI to run is always a bit of a challenge, so I'll probably try to see if I can create a synthetic repro first.
Updated by Michael Kay over 8 years ago
- Category set to XSLT 3.0 packages
- Status changed from New to In Progress
- Assignee set to Michael Kay
I've just spotted what is probably the distinguishing feature of this stylesheet, which is the use of xsl:next-match in a named template (xsl:template[@name]), rather than in a template rule (xsl:template[@match]).
This is legal because the current template rule and current mode survive calls to named templates (though not calls to user-defined functions), but it means that the code is wrong to assume that xsl:next-match (and equally xsl:apply-imports) doesn't change the current component.
Updated by Michael Kay over 8 years ago
I have reproduced the problem with a new test case next-match-028, added to the W3C XSLT3 test suite.
Updated by Michael Kay over 8 years ago
- Subject changed from xsl:next-match causes IndexOutOfBoundsException to xsl:next-match as last instruction in a named template causes IndexOutOfBoundsException
- Status changed from In Progress to Resolved
- Applies to branch 9.7, 9.8 added
- Fix Committed on Branch 9.7, 9.8 added
Now fixed. Patch committed on the 9.7 and 9.8 branches.
Confirmed that the problem only occurs when xsl:next-match is the last instruction to be evaluated in a named template.
The problem does not affect xsl:apply-imports because we don't optimize tail calls for that instruction.
Updated by O'Neil Delpratt over 8 years ago
- % Done changed from 0 to 100
- Fixed in Maintenance Release 9.7.0.7 added
Bug fix applied in the Saxon 9.7.0.7 maintenance release.
Updated by O'Neil Delpratt over 8 years ago
- Status changed from Resolved to Closed
Updated by O'Neil Delpratt over 7 years ago
- Applies to branch trunk added
- Applies to branch deleted (
9.8)
Updated by O'Neil Delpratt over 7 years ago
- Fix Committed on Branch trunk added
- Fix Committed on Branch deleted (
9.8)
Updated by Michael Kay over 6 years ago
- Related to Bug #3706: Array out of bounds exception results from function in template predicate added
Please register to edit this issue