In the JacksonAvroParserImpl::_finishShortText(int) method, there is a missing bound check-in handling the value reading from the byte array inputBuf and could cause unexpected IndexOutOfBoundsException if the provided input is not correctly ended.
In the first line of the do..while loop, the current index pointed by the inPtr variable is retrieved, processed and stored. Then the inPtr value is increased by one. From the study of the code, the value of inPtr must be within the range of the byte array inputBuf, but since it has increased by one in this line, the value of inPtr may be larger or equals to the length of inputBuf on some invalid input. This causes the subsequent inputBuf value access with the out-of-bound inPtr to throw an unexpected IndexOutOfBoundsException.
...
final int[] codes = sUtf8UnitLengths;
do {
i = inputBuf[inPtr++] & 0xFF;
switch (codes[i]) {
case 0:
break;
case 1:
i = ((i & 0x1F) << 6) | (inputBuf[inPtr++] & 0x3F);
break;
case 2:
i = ((i & 0x0F) << 12)
| ((inputBuf[inPtr++] & 0x3F) << 6)
| (inputBuf[inPtr++] & 0x3F);
break;
case 3:
i = ((i & 0x07) << 18)
| ((inputBuf[inPtr++] & 0x3F) << 12)
| ((inputBuf[inPtr++] & 0x3F) << 6)
| (inputBuf[inPtr++] & 0x3F);
// note: this is the codepoint value; need to split, too
i -= 0x10000;
outBuf[outPtr++] = (char) (0xD800 | (i >> 10));
i = 0xDC00 | (i & 0x3FF);
break;
default: // invalid
_reportError("Invalid byte "+Integer.toHexString(i)+" in Unicode text block");
}
outBuf[outPtr++] = (char) i;
} while (inPtr < end);
return _textBuffer.setCurrentAndReturn(outPtr);
...
Similar problem happened in JacksonAvroParserImpl::_finishLongText(int) method.
private final void _finishLongText(int len) throws IOException
...
case 3: // 4-byte UTF
c = _decodeUTF8_4(c);
// Let's add first part right away:
outBuf[outPtr++] = (char) (0xD800 | (c >> 10));
The suggested fix is to add a bound checking in the do..while loop after the inPtr++ process to ensure the inPtr is still within bound and throws an error if not for identifying invalid input.
In the
JacksonAvroParserImpl::_finishShortText(int)
method, there is a missing bound check-in handling the value reading from the byte arrayinputBuf
and could cause unexpectedIndexOutOfBoundsException
if the provided input is not correctly ended.In the first line of the
do..while
loop, the current index pointed by theinPtr
variable is retrieved, processed and stored. Then theinPtr
value is increased by one. From the study of the code, the value ofinPtr
must be within the range of the byte arrayinputBuf
, but since it has increased by one in this line, the value ofinPtr
may be larger or equals to the length ofinputBuf
on some invalid input. This causes the subsequentinputBuf
value access with the out-of-boundinPtr
to throw an unexpectedIndexOutOfBoundsException
.Similar problem happened in
JacksonAvroParserImpl::_finishLongText(int)
method.The suggested fix is to add a bound checking in the
do..while
loop after theinPtr++
process to ensure theinPtr
is still within bound and throws an error if not for identifying invalid input.We found this issue by OSS-Fuzz and it is reported in https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65618 and We found this issue by OSS-Fuzz and it is reported in https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65649.