ClobConsumer copies CLOB data into the VarCharVector data buffer with MemoryUtil.copyToMemory at offset startIndex + totalBytes, but the buffer-growth guard checks dataBuffer.writerIndex() + bytes.length > dataBuffer.capacity(). copyToMemory never advances writerIndex(), and nothing else does either, so it stays at 0 and the guard only ever checks that a single chunk fits at offset 0. Once the cumulative bytes of a CLOB (or a batch of CLOB rows) exceed the initial data-buffer allocation of about 32 KB, reallocDataBuffer() is never called and copyToMemory, which performs no ArrowBuf bounds checking, writes past the allocation into adjacent off-heap memory.
The sibling BinaryConsumer uses the correct check: while (vector.getDataBuffer().capacity() < (startOffset + dataLength + read)).
To reproduce, consume a single CLOB whose UTF-8 length exceeds the initial data buffer (for example INITIAL_VALUE_ALLOCATION * 8 * 4 characters). The out-of-bounds write corrupts the adjacent offset buffer, and reading the value back throws NegativeArraySizeException.
ClobConsumer copies CLOB data into the VarCharVector data buffer with
MemoryUtil.copyToMemoryat offsetstartIndex + totalBytes, but the buffer-growth guard checksdataBuffer.writerIndex() + bytes.length > dataBuffer.capacity().copyToMemorynever advanceswriterIndex(), and nothing else does either, so it stays at 0 and the guard only ever checks that a single chunk fits at offset 0. Once the cumulative bytes of a CLOB (or a batch of CLOB rows) exceed the initial data-buffer allocation of about 32 KB,reallocDataBuffer()is never called andcopyToMemory, which performs no ArrowBuf bounds checking, writes past the allocation into adjacent off-heap memory.The sibling
BinaryConsumeruses the correct check:while (vector.getDataBuffer().capacity() < (startOffset + dataLength + read)).To reproduce, consume a single CLOB whose UTF-8 length exceeds the initial data buffer (for example
INITIAL_VALUE_ALLOCATION * 8 * 4characters). The out-of-bounds write corrupts the adjacent offset buffer, and reading the value back throwsNegativeArraySizeException.