#320 ArrayIndexOutOfBounds in DescendantEnumeration

Michael Kay
Michael Kay

An ArrayIndexOutOfBoundsException can occur when
evaluating an expression such as //x - the exception
occurs at
net.sf.saxon.tinytree.DescendantEnumeration.next in

The problem is caused when two conditions occur
together: (a) the instruction that creates the tree
fails to close it properly when it has finished, and
(b) the number of nodes in the tree is exactly 50*2^N
for some integer N.

Condition (a) is known to arise when a stylesheet or
query constructs a temporary tree rooted at an element
rather than at a document node. The following patch
fixes this: at line 306 of
net.sf.saxon.event.SequenceOutputter.java, change the
close() method to read:

public void close() throws XPathException {
previousAtomic = false;
if (tree != null) {

Michael Kay


  • Michael Kay
    Michael Kay

    Logged In: YES

    Unfortunately the above patch, while correct, can cause a
    serious performance regression for some queries. In
    particular, it affects queries that write a large number of
    parentless elements, in situations where Saxon is able to
    hold all these elements in the same TinyTree structure. The
    performance regression is caused because the arrays within
    the TinyTree structure are condensed after writing each
    parentless element, meaning that they have to be expanded
    again when the next element is added, with ever-increasing
    cost as the arrays get larger. To fix this, the following
    patch ensures that condensing of the arrays does not happen
    if the TinyTree holds more than one root node (on the
    presumption that if it already holds more than one, the
    chances are that more will be added.)

    In net.sf.saxon.tinytree.TinyTree, method condense() at line
    319, add at the start of the method:

    if (rootIndexUsed > 1) return;

    Michael Kay