Skip to content

Commit 10edea2

Browse files
committed
Fix #811
1 parent 425da97 commit 10edea2

File tree

4 files changed

+50
-7
lines changed

4 files changed

+50
-7
lines changed

release-notes/VERSION-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ JSON library.
5757
with key of ""
5858
#798: Avoid copy when parsing `BigDecimal`
5959
(contributed by Philippe M)
60+
#811: Add explicit bounds checks for `JsonGenerator` methods that take
61+
`byte[]`/`char[]`/String-with-offsets input
6062

6163
2.13.3 (14-May-2022)
6264

src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -615,14 +615,15 @@ public final void writeString(SerializableString text) throws IOException
615615
}
616616

617617
@Override
618-
public void writeRawUTF8String(byte[] text, int offset, int length) throws IOException
618+
public void writeRawUTF8String(byte[] text, int offset, int len) throws IOException
619619
{
620+
_checkRangeBoundsForByteArray(offset, len, text.length);
620621
_verifyValueWrite(WRITE_STRING);
621622
if (_outputTail >= _outputEnd) {
622623
_flushBuffer();
623624
}
624625
_outputBuffer[_outputTail++] = _quoteChar;
625-
_writeBytes(text, offset, length);
626+
_writeBytes(text, offset, len);
626627
if (_outputTail >= _outputEnd) {
627628
_flushBuffer();
628629
}
@@ -632,6 +633,7 @@ public void writeRawUTF8String(byte[] text, int offset, int length) throws IOExc
632633
@Override
633634
public void writeUTF8String(byte[] text, int offset, int len) throws IOException
634635
{
636+
_checkRangeBoundsForByteArray(offset, len, text.length);
635637
_verifyValueWrite(WRITE_STRING);
636638
if (_outputTail >= _outputEnd) {
637639
_flushBuffer();

src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java

+2
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,8 @@ private void writeRawLong(String text) throws IOException
665665
public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len)
666666
throws IOException, JsonGenerationException
667667
{
668+
_checkRangeBoundsForByteArray(offset, len, data.length);
669+
668670
_verifyValueWrite(WRITE_BINARY);
669671
// Starting quotes
670672
if (_outputTail >= _outputEnd) {

src/test/java/com/fasterxml/jackson/core/write/GeneratorBoundsChecksTest.java

+42-5
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,38 @@ public void call(JsonGenerator g, byte[] data, int offset, int len) throws Excep
5454
g.writeBinary(data, offset, len);
5555
}
5656
};
57-
57+
58+
private final ByteBackedOperation WRITE_RAW_UTF8_FROM_BYTES = new ByteBackedOperation() {
59+
@Override
60+
public void call(JsonGenerator g, byte[] data, int offset, int len) throws Exception {
61+
g.writeRawUTF8String(data, offset, len);
62+
}
63+
};
64+
65+
private final ByteBackedOperation WRITE_UTF8_STRING_FROM_BYTES = new ByteBackedOperation() {
66+
@Override
67+
public void call(JsonGenerator g, byte[] data, int offset, int len) throws Exception {
68+
g.writeUTF8String(data, offset, len);
69+
}
70+
};
71+
5872
public void testBoundsWithByteArrayInputFromBytes() throws Exception {
59-
// _testBoundsWithByteArrayInput(BYTE_GENERATOR_CREATOR);
73+
_testBoundsWithByteArrayInput(BYTE_GENERATOR_CREATOR, true);
6074
}
6175

6276
public void testBoundsWithByteArrayInputFromChars() throws Exception {
63-
// _testBoundsWithByteArrayInput(CHAR_GENERATOR_CREATOR);
77+
_testBoundsWithByteArrayInput(CHAR_GENERATOR_CREATOR, false);
6478
}
6579

66-
private void _testBoundsWithByteArrayInput(GeneratorCreator genc) throws Exception {
80+
private void _testBoundsWithByteArrayInput(GeneratorCreator genc, boolean byteBacked)
81+
throws Exception {
6782
_testBoundsWithByteArrayInput(genc, WRITE_BINARY_FROM_BYTES);
83+
// NOTE: byte[] writes of pre-encoded UTF-8 not supported for Writer-backed
84+
// generator, so:
85+
if (byteBacked) {
86+
_testBoundsWithByteArrayInput(genc, WRITE_RAW_UTF8_FROM_BYTES);
87+
_testBoundsWithByteArrayInput(genc, WRITE_UTF8_STRING_FROM_BYTES);
88+
}
6889
}
6990

7091
private void _testBoundsWithByteArrayInput(GeneratorCreator genc,
@@ -83,7 +104,7 @@ private void _testBoundsWithByteArrayInput(GeneratorCreator genc,
83104
} catch (StreamWriteException e) {
84105
verifyException(e, "Invalid 'offset'");
85106
verifyException(e, "'len'");
86-
verifyException(e, "arguments for String of length "+data.length);
107+
verifyException(e, "arguments for `byte[]` of length "+data.length);
87108
}
88109
}
89110
}
@@ -96,7 +117,21 @@ private void _testBoundsWithByteArrayInput(GeneratorCreator genc,
96117

97118
// // // Individual generator calls to check, char[]-backed
98119

120+
private final CharBackedOperation WRITE_NUMBER_FROM_CHARS = new CharBackedOperation() {
121+
@Override
122+
public void call(JsonGenerator g, char[] data, int offset, int len) throws Exception {
123+
g.writeNumber(data, offset, len);
124+
}
125+
};
126+
99127
private final CharBackedOperation WRITE_RAW_FROM_CHARS = new CharBackedOperation() {
128+
@Override
129+
public void call(JsonGenerator g, char[] data, int offset, int len) throws Exception {
130+
g.writeRaw(data, offset, len);
131+
}
132+
};
133+
134+
private final CharBackedOperation WRITE_RAWVALUE_FROM_CHARS = new CharBackedOperation() {
100135
@Override
101136
public void call(JsonGenerator g, char[] data, int offset, int len) throws Exception {
102137
g.writeRawValue(data, offset, len);
@@ -112,7 +147,9 @@ public void testBoundsWithCharArrayInputFromChars() throws Exception {
112147
}
113148

114149
private void _testBoundsWithCharArrayInput(GeneratorCreator genc) throws Exception {
150+
_testBoundsWithCharArrayInput(genc, WRITE_NUMBER_FROM_CHARS);
115151
_testBoundsWithCharArrayInput(genc, WRITE_RAW_FROM_CHARS);
152+
_testBoundsWithCharArrayInput(genc, WRITE_RAWVALUE_FROM_CHARS);
116153
}
117154

118155
private void _testBoundsWithCharArrayInput(GeneratorCreator genc,

0 commit comments

Comments
 (0)