ArrowFlightJdbcArray.checkBoundaries validates the caller-supplied index against startOffset + valuesCount:
private void checkBoundaries(long index, int count) {
if (index < 0 || index + count > this.startOffset + this.valuesCount) {
throw new ArrayIndexOutOfBoundsException();
}
}
but index is relative to the start of the array; both call sites add startOffset to it only afterwards, e.g.
checkBoundaries(index, count);
return getArrayNoBoundCheck(
this.dataVector, LargeMemoryUtil.checkedCastToInt(this.startOffset + index), count);
So the accepted range is too large by exactly startOffset elements, and getArray(index, count) / getResultSet(index, count) will read up to that far past the end of the row's slice.
AbstractArrowFlightJdbcListVectorAccessor builds these with the offsets of the list element being read, so any row of a list column that does not start at child offset 0 is affected. Reading within the element count the driver itself advertises then returns values belonging to other rows of the shared child vector, and past the child vector's valueCount it returns whatever is in allocated-but-unwritten memory.
Reproducer against an IntVector of 127 values, with an array covering elements 5..7:
ArrowFlightJdbcArray array = new ArrowFlightJdbcArray(dataVector, 5, 3);
array.getArray(1, 3); // accepted; returns elements 6, 7, 8 — element 8 is outside the array
Every existing test constructs the array with startOffset 0, where the wrong bound happens to coincide with the correct one, which is why this is not currently caught.
ArrowFlightJdbcArray.checkBoundariesvalidates the caller-supplied index againststartOffset + valuesCount:but
indexis relative to the start of the array; both call sites addstartOffsetto it only afterwards, e.g.So the accepted range is too large by exactly
startOffsetelements, andgetArray(index, count)/getResultSet(index, count)will read up to that far past the end of the row's slice.AbstractArrowFlightJdbcListVectorAccessorbuilds these with the offsets of the list element being read, so any row of a list column that does not start at child offset 0 is affected. Reading within the element count the driver itself advertises then returns values belonging to other rows of the shared child vector, and past the child vector'svalueCountit returns whatever is in allocated-but-unwritten memory.Reproducer against an
IntVectorof 127 values, with an array covering elements 5..7:Every existing test constructs the array with
startOffset0, where the wrong bound happens to coincide with the correct one, which is why this is not currently caught.