Skip to content

Commit 8d70e30

Browse files
committed
More coverage wrt #811, improved checks
1 parent 10edea2 commit 8d70e30

File tree

5 files changed

+74
-66
lines changed

5 files changed

+74
-66
lines changed

src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,60 @@ protected final int _decodeSurrogate(int surr1, int surr2) throws IOException
497497
int c = 0x10000 + ((surr1 - SURR1_FIRST) << 10) + (surr2 - SURR2_FIRST);
498498
return c;
499499
}
500+
501+
/*
502+
/**********************************************************************
503+
/* Helper methods for validating parameters
504+
/**********************************************************************
505+
*/
506+
507+
// @since 2.14
508+
protected void _checkRangeBoundsForByteArray(int offset, int len, int dataLen)
509+
throws IOException
510+
{
511+
final int end = offset+len;
512+
513+
// Note: we are checking that:
514+
//
515+
// !(offset < 0)
516+
// !(len < 0)
517+
// !((offset + len) < 0) // int overflow!
518+
// !((offset + len) > dataLen) == !((datalen - (offset+len)) < 0)
519+
520+
// All can be optimized by OR'ing and checking for negative:
521+
int anyNegs = offset | len | end | (dataLen - end);
522+
if (anyNegs < 0) {
523+
_reportError(String.format(
524+
"Invalid 'offset' (%d) and/or 'len' (%d) arguments for `byte[]` of length %d",
525+
offset, len, dataLen));
526+
}
527+
}
528+
529+
// @since 2.14
530+
protected void _checkRangeBoundsForCharArray(int offset, int len, int dataLen)
531+
throws IOException
532+
{
533+
final int end = offset+len;
534+
// Note: we are checking same things as with other bounds-checks
535+
int anyNegs = offset | len | end | (dataLen - end);
536+
if (anyNegs < 0) {
537+
_reportError(String.format(
538+
"Invalid 'offset' (%d) and/or 'len' (%d) arguments for `char[]` of length %d",
539+
offset, len, dataLen));
540+
}
541+
}
542+
543+
// @since 2.14
544+
protected void _checkRangeBoundsForString(int offset, int len, int dataLen)
545+
throws IOException
546+
{
547+
final int end = offset+len;
548+
// Note: we are checking same things as with other bounds-checks
549+
int anyNegs = offset | len | end | (dataLen - end);
550+
if (anyNegs < 0) {
551+
_reportError(String.format(
552+
"Invalid 'offset' (%d) and/or 'len' (%d) arguments for `String` of length %d",
553+
offset, len, dataLen));
554+
}
555+
}
500556
}

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

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -248,54 +248,4 @@ protected void _reportCantWriteValueExpectName(String typeMsg) throws IOExceptio
248248
_reportError(String.format("Can not %s, expecting field name (context: %s)",
249249
typeMsg, _writeContext.typeDesc()));
250250
}
251-
252-
// @since 2.14
253-
protected void _checkRangeBoundsForByteArray(int offset, int len, int dataLen)
254-
throws IOException
255-
{
256-
final int end = offset+len;
257-
258-
// Note: we are checking that:
259-
//
260-
// !(offset < 0)
261-
// !(len < 0)
262-
// !((offset + len) < 0) // int overflow!
263-
// !((offset + len) > dataLen)
264-
265-
// First 3 can be optimized by OR'ing and checking for negative:
266-
int anyNegs = offset | len | end;
267-
if ((anyNegs < 0) || (end > dataLen)) {
268-
_reportError(String.format(
269-
"Invalid 'offset' (%d) and/or 'len' (%d) arguments for `byte[]` of length %d",
270-
offset, len, dataLen));
271-
}
272-
}
273-
274-
// @since 2.14
275-
protected void _checkRangeBoundsForCharArray(int offset, int len, int dataLen)
276-
throws IOException
277-
{
278-
final int end = offset+len;
279-
// Note: we are checking same things as with other bounds-checks
280-
int anyNegs = offset | len | end;
281-
if ((anyNegs < 0) || (end > dataLen)) {
282-
_reportError(String.format(
283-
"Invalid 'offset' (%d) and/or 'len' (%d) arguments for `char[]` of length %d",
284-
offset, len, dataLen));
285-
}
286-
}
287-
288-
// @since 2.14
289-
protected void _checkRangeBoundsForString(int offset, int len, int dataLen)
290-
throws IOException
291-
{
292-
final int end = offset+len;
293-
// Note: we are checking same things as with other bounds-checks
294-
int anyNegs = offset | len | end;
295-
if ((anyNegs < 0) || (end > dataLen)) {
296-
_reportError(String.format(
297-
"Invalid 'offset' (%d) and/or 'len' (%d) arguments for `String` of length %d",
298-
offset, len, dataLen));
299-
}
300-
}
301251
}

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -741,14 +741,7 @@ public void writeRawValue(SerializableString text) throws IOException {
741741
@Override
742742
public final void writeRaw(char[] cbuf, int offset, int len) throws IOException
743743
{
744-
// 03-Aug-2022, tatu: Maybe need to do bounds checks first (found by Fuzzer)
745-
// ... note that "end < 0" may occur with int overflow
746-
final int end = offset + len;
747-
if ((offset < 0) || (len < 0) || (end < 0) || (end > cbuf.length)) {
748-
_reportError(String.format(
749-
"Invalid 'offset' (%d) and/or 'len' (%d) arguments for `char[]` of length %d",
750-
offset, len, cbuf.length));
751-
}
744+
_checkRangeBoundsForCharArray(offset, len, cbuf.length);
752745

753746
// First: if we have 3 x charCount spaces, we know it'll fit just fine
754747
{

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -597,14 +597,7 @@ public void writeRaw(SerializableString text) throws IOException {
597597
@Override
598598
public void writeRaw(char[] cbuf, int offset, int len) throws IOException
599599
{
600-
// 03-Aug-2022, tatu: Maybe need to do bounds checks first (found by Fuzzer)
601-
// ... note that "end < 0" may occur with int overflow
602-
final int end = offset + len;
603-
if ((offset < 0) || (len < 0) || (end < 0) || (end > cbuf.length)) {
604-
_reportError(String.format(
605-
"Invalid 'offset' (%d) and/or 'len' (%d) arguments for `char[]` of length %d",
606-
offset, len, cbuf.length));
607-
}
600+
_checkRangeBoundsForCharArray(offset, len, cbuf.length);
608601

609602
// Only worth buffering if it's a short write?
610603
if (len < SHORT_WRITE) {

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ private void _testBoundsWithByteArrayInput(GeneratorCreator genc,
9292
ByteBackedOperation oper) throws Exception {
9393
final byte[] BYTES10 = new byte[10];
9494
_testBoundsWithByteArrayInput(genc, oper, BYTES10, -1, 1);
95+
_testBoundsWithByteArrayInput(genc, oper, BYTES10, 4, -1);
96+
_testBoundsWithByteArrayInput(genc, oper, BYTES10, 4, -6);
97+
_testBoundsWithByteArrayInput(genc, oper, BYTES10, 9, 5);
98+
// and the integer overflow, too
99+
_testBoundsWithByteArrayInput(genc, oper, BYTES10, Integer.MAX_VALUE, 4);
100+
_testBoundsWithByteArrayInput(genc, oper, BYTES10, Integer.MAX_VALUE, Integer.MAX_VALUE);
95101
}
96102

97103
private void _testBoundsWithByteArrayInput(GeneratorCreator genc,
@@ -156,6 +162,11 @@ private void _testBoundsWithCharArrayInput(GeneratorCreator genc,
156162
CharBackedOperation oper) throws Exception {
157163
final char[] CHARS10 = new char[10];
158164
_testBoundsWithCharArrayInput(genc, oper, CHARS10, -1, 1);
165+
_testBoundsWithCharArrayInput(genc, oper, CHARS10, 4, -1);
166+
_testBoundsWithCharArrayInput(genc, oper, CHARS10, 4, -6);
167+
_testBoundsWithCharArrayInput(genc, oper, CHARS10, 9, 5);
168+
_testBoundsWithCharArrayInput(genc, oper, CHARS10, Integer.MAX_VALUE, 4);
169+
_testBoundsWithCharArrayInput(genc, oper, CHARS10, Integer.MAX_VALUE, Integer.MAX_VALUE);
159170
}
160171

161172
private void _testBoundsWithCharArrayInput(GeneratorCreator genc,
@@ -214,6 +225,11 @@ private void _testBoundsWithStringInput(GeneratorCreator genc,
214225
StringBackedOperation oper) throws Exception {
215226
final String STRING10 = new String(new char[10]);
216227
_testBoundsWithStringInput(genc, oper, STRING10, -1, 1);
228+
_testBoundsWithStringInput(genc, oper, STRING10, 4, -1);
229+
_testBoundsWithStringInput(genc, oper, STRING10, 4, -6);
230+
_testBoundsWithStringInput(genc, oper, STRING10, 9, 5);
231+
_testBoundsWithStringInput(genc, oper, STRING10, Integer.MAX_VALUE, 4);
232+
_testBoundsWithStringInput(genc, oper, STRING10, Integer.MAX_VALUE, Integer.MAX_VALUE);
217233
}
218234

219235
private void _testBoundsWithStringInput(GeneratorCreator genc,

0 commit comments

Comments
 (0)