Project

Profile

Help

Bug #2818

closed

xsl:next-match as last instruction in a named template causes IndexOutOfBoundsException

Added by Jason Harrop over 8 years ago. Updated over 7 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
XSLT 3.0 packages
Sprint/Milestone:
-
Start date:
2016-07-02
Due date:
% Done:

100%

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

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

Related to Saxon - Bug #3706: Array out of bounds exception results from function in template predicateClosedMichael Kay2018-02-28

Actions
Actions #1

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.

Actions #2

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.

Actions #3

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.

Actions #4

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.

Actions #5

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.

Actions #6

Updated by O'Neil Delpratt over 8 years ago

  • Status changed from Resolved to Closed
Actions #7

Updated by O'Neil Delpratt over 7 years ago

  • Applies to branch trunk added
  • Applies to branch deleted (9.8)
Actions #8

Updated by O'Neil Delpratt over 7 years ago

  • Fix Committed on Branch trunk added
  • Fix Committed on Branch deleted (9.8)
Actions #9

Updated by Michael Kay almost 7 years ago

  • Related to Bug #3706: Array out of bounds exception results from function in template predicate added

Please register to edit this issue

Also available in: Atom PDF