ngs-doo/dsl-json

bug in `writerBinary` method of class `JsonWriter`

Opened this issue · 1 comments

Current implementation

	public final void writeBinary(final byte[] value) {
		if (position + (value.length << 1) + 2 >= buffer.length) {
			enlargeOrFlush(position, (value.length << 1) + 2);
		}
		buffer[position++] = '"';
		position += Base64.encodeToBytes(value, buffer, position);
		buffer[position++] = '"';
	}

it produces in my tests at times the exception java.lang.IndexOutOfBoundsException: Range [0, 0 + 513) out of bounds for length 512.

The calculation of the space needed in the buffer for encoding the binary data to Base64 in the current implementation seems incorrect. The formula (value.length << 1) + 2 suggests that each byte in the binary array requires at most two bytes in the Base64-encoded form, which falls short when the array has length one. In this case we need 6 bytes and not 4

Here's the corrected version of the code:

public final void writeBinary(final byte[] value) {
    int neededSize = (int) Math.ceil((double) length / 3) * 4 + 2;
    if (position + neededSize >= buffer.length) {
        enlargeOrFlush(position, neededSize);
    }
    buffer[position++] = '"';
    position += Base64.encodeToBytes(value, buffer, position);
    buffer[position++] = '"';
}

After this change, all my test passes.

Tnx for the report. Would be nice to have a test for this.
As for the fix, I'd rather fix is as len << 1 + 4 than doing more complex math