Project

Profile

Help

Bug #6380

closed

Internal error when match pattern invoked by xsl:next-match refers to global variable

Added by Michael Kay 9 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Internals
Sprint/Milestone:
-
Start date:
2024-03-27
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
12, trunk
Fix Committed on Branch:
12, trunk
Fixed in Maintenance Release:
Platforms:
.NET, Java

Description

Email on saxonica support

Actions #1

Updated by Michael Kay 9 months ago

Root cause: class net.sf.saxon.expr.instruct.UserFunction cannot be cast to class net.sf.saxon.expr.instruct.GlobalVariable (net.sf.saxon.expr.instruct.UserFunction

Caused by: java.lang.ClassCastException: class net.sf.saxon.expr.instruct.UserFunction cannot be cast to class net.sf.saxon.expr.instruct.GlobalVariable (net.sf.saxon.expr.instruct.UserFunction and net.sf.saxon.expr.instruct.GlobalVariable are in unnamed module of loader 'app')
	at net.sf.saxon.expr.GlobalVariableReference.evaluateVariable(GlobalVariableReference.java:126)
	at net.sf.saxon.expr.GlobalVariableReference$GlobalVariableReferenceElaborator.lambda$elaborateForItem$2(GlobalVariableReference.java:228)
	at net.sf.saxon.expr.ValueComparison$ValueComparisonElaborator.lambda$elaborateForBoolean$4(ValueComparison.java:609)
	at net.sf.saxon.expr.AndExpression$AndElaborator.lambda$elaborateForBoolean$0(AndExpression.java:212)
	at net.sf.saxon.expr.FilterExpression$FilterExprElaborator$SimpleFilteredIterator.next(FilterExpression.java:1472)
	at net.sf.saxon.expr.parser.ExpressionTool.effectiveBooleanValue(ExpressionTool.java:664)
	at net.sf.saxon.expr.elab.PullElaborator.lambda$elaborateForBoolean$2(PullElaborator.java:65)
	at net.sf.saxon.pattern.BasePatternWithPredicate.matchesPredicate(BasePatternWithPredicate.java:141)
	at net.sf.saxon.pattern.BasePatternWithPredicate.matches(BasePatternWithPredicate.java:129)
	at net.sf.saxon.pattern.Pattern.matchesItem(Pattern.java:268)
	at net.sf.saxon.trans.rules.Rule.matches(Rule.java:240)
	at com.saxonica.ee.trans.ModeEE.ruleMatches(ModeEE.java:142)
	at net.sf.saxon.trans.SimpleMode.searchRuleChain(SimpleMode.java:896)
	at net.sf.saxon.trans.SimpleMode.getRule(SimpleMode.java:786)
	at net.sf.saxon.trans.Mode.getNextMatchRule(Mode.java:378)
	at net.sf.saxon.expr.instruct.NextMatch$NextMatchElaborator.lambda$elaborateForPush$0(NextMatch.java:221)
	at net.sf.saxon.expr.instruct.Choose$ChooseExprElaborator.lambda$elaborateForPush$10(Choose.java:1177)
	at net.sf.saxon.expr.instruct.Choose$ChooseExprElaborator.lambda$elaborateForPush$12(Choose.java:1188)
	at net.sf.saxon.expr.instruct.NamedTemplate.expand(NamedTemplate.java:247)
	at net.sf.saxon.expr.instruct.CallTemplate$CallTemplatePackage.processLeavingTail(CallTemplate.java:515)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:476)
Actions #2

Updated by Michael Kay 9 months ago

It seems that the currentComponent in the context is wrong, so it's attempting to reference a global variable using the wrong binding slot number, and the slot that it's using is a reference to a user function rather than a global variable.

The variable it's trying to access is $logic.master in the match pattern predicate match="tr[td[1][choice and (count(child::*) eq 1) and $logic.master = false()]] (line 158 of eoc_preprocess.xsl). The current component is a named template, which I think is wrong: for evaluating match patterns I think the current component should be the mode.

Actions #3

Updated by Michael Kay 9 months ago

The Mode object has stackFrameSlotsNeeded=0, which means it's not going to create a new context for evaluating the match patterns, which means that the current component isn't going to be set (see Mode.makeNewContext()). Note there's a comment here pointing to bug #3706.

The theory is that stackFrameSlotsNeeded should be non-zero if there are any match patterns in the Mode that contain local variables. But in this case the reference is to a global variable.

If I artificially introduce a local variable in the match pattern, making it

<xsl:template match="tr[td[1][let $c := child::* return choice and (count($c) eq 1) and $logic.master = false()]]">

then the problem goes away.

Actions #4

Updated by Michael Kay 9 months ago

  • Subject changed from Internal error evaluating template rule at line 320 to Internal error evaluating template rule at line 320 (match pattern refers to global variable)
  • Category set to Internals
  • Status changed from New to In Progress
Actions #5

Updated by Michael Kay 9 months ago

BasePatternWithPredicate.matchesPredicate creates a new XPathContext object, but it doesn't change the current component to be the Mode.

In fact, it doesn't know the Mode.

I think it's relevant that we're in xsl:next-match rather than xsl:apply-templates. ApplyTemplates line 643 appears to create a new context unconditionally, and to set the current component at that point. This logic is missing from NextMatch.

Actions #6

Updated by Michael Kay 9 months ago

  • Subject changed from Internal error evaluating template rule at line 320 (match pattern refers to global variable) to Internal error when match pattern invoked by xsl:next-match refers to global variable
Actions #7

Updated by Michael Kay 9 months ago

  • Status changed from In Progress to Resolved
  • Applies to branch 12, trunk added
  • Fix Committed on Branch 12, trunk added
  • Platforms .NET, Java added

Patch regression tested, will go out in next maintenance release.

Actions #8

Updated by O'Neil Delpratt 5 months ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 12.5 added

Bug fix applied in the Saxon 12.5 Maintenance release.

Please register to edit this issue

Also available in: Atom PDF