Skip to content

Commit aceb088

Browse files
committed
Merge branch '2.8' into 2.9
2 parents ad47c20 + 233640b commit aceb088

File tree

4 files changed

+109
-2
lines changed

4 files changed

+109
-2
lines changed

release-notes/CREDITS-2.x

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,7 @@ Doug Roper (htmldoug@github)
159159
Alexander Eyers-Taylor (aeyerstaylor@github)
160160
* Reported #510: Fix ArrayIndexOutofBoundsException found by LGTM.com
161161
(2.9.9)
162+
163+
Henrik Gustafsson (gsson@github)
164+
* Reported #516: _inputPtr off-by-one in UTF8StreamJsonParser._parseNumber2()
165+
(2.9.9)

release-notes/VERSION-2.x

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ JSON library.
1414
=== Releases ===
1515
------------------------------------------------------------------------
1616

17+
2.9.9 (not yet released)
18+
19+
#516: _inputPtr off-by-one in UTF8StreamJsonParser._parseNumber2()
20+
(reported by Henrik G)
21+
1722
2.9.8 (15-Dec-2018)
1823

1924
#488: Fail earlier on coercions from "too big" `BigInteger` into

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1467,7 +1467,7 @@ private final JsonToken _parseNumber2(char[] outBuf, int outPtr, boolean negativ
14671467
_textBuffer.setCurrentLength(outPtr);
14681468
// As per #105, need separating space between root values; check here
14691469
if (_parsingContext.inRoot()) {
1470-
_verifyRootSpace(_inputBuffer[_inputPtr++] & 0xFF);
1470+
_verifyRootSpace(_inputBuffer[_inputPtr] & 0xFF);
14711471
}
14721472

14731473
// And there we have it!

src/test/java/com/fasterxml/jackson/core/json/TestRootValues.java

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public void testSimpleWrites() throws Exception
7979
_testSimpleWrites(true);
8080
}
8181

82-
public void _testSimpleWrites(boolean useStream) throws Exception
82+
private void _testSimpleWrites(boolean useStream) throws Exception
8383
{
8484
ByteArrayOutputStream out = new ByteArrayOutputStream();
8585
StringWriter w = new StringWriter();
@@ -102,4 +102,102 @@ public void _testSimpleWrites(boolean useStream) throws Exception
102102
String json = useStream ? out.toString("UTF-8") : w.toString();
103103
assertEquals("123 \"abc\" true", json);
104104
}
105+
106+
// [core#516]: Off-by-one read problem
107+
public void testRootOffsetIssue516Bytes() throws Exception
108+
{
109+
// InputStream that forces _parseNumber2 to be invoked.
110+
final InputStream in = new Issue516InputStream(new byte[][] {
111+
"1234".getBytes("UTF-8"),
112+
"5 true".getBytes("UTF-8")
113+
});
114+
115+
JsonParser parser = JSON_F.createParser(in);
116+
assertEquals(12345, parser.nextIntValue(0));
117+
118+
// Fails with com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'rue': was expecting ('true', 'false' or 'null')
119+
assertTrue(parser.nextBooleanValue());
120+
121+
parser.close();
122+
in.close();
123+
}
124+
125+
// [core#516]: Off-by-one read problem
126+
public void testRootOffsetIssue516Chars() throws Exception
127+
{
128+
// InputStream that forces _parseNumber2 to be invoked.
129+
final Reader in = new Issue516Reader(new char[][] {
130+
"1234".toCharArray(), "5 true".toCharArray()
131+
});
132+
133+
JsonParser parser = JSON_F.createParser(in);
134+
assertEquals(12345, parser.nextIntValue(0));
135+
136+
// Fails with com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'rue': was expecting ('true', 'false' or 'null')
137+
assertTrue(parser.nextBooleanValue());
138+
139+
parser.close();
140+
in.close();
141+
}
142+
143+
static class Issue516InputStream extends InputStream
144+
{
145+
private final byte[][] reads;
146+
private int currentRead;
147+
148+
public Issue516InputStream(byte[][] reads) {
149+
this.reads = reads;
150+
this.currentRead = 0;
151+
}
152+
153+
@Override
154+
public int read() throws IOException {
155+
throw new UnsupportedOperationException();
156+
}
157+
158+
@Override
159+
public int read(byte[] b, int off, int len) throws IOException {
160+
if (currentRead >= reads.length) {
161+
return -1;
162+
}
163+
byte[] bytes = reads[currentRead++];
164+
if (len < bytes.length) {
165+
throw new IllegalArgumentException();
166+
}
167+
System.arraycopy(bytes, 0, b, off, bytes.length);
168+
return bytes.length;
169+
}
170+
}
171+
172+
static class Issue516Reader extends Reader
173+
{
174+
private final char[][] reads;
175+
private int currentRead;
176+
177+
public Issue516Reader(char[][] reads) {
178+
this.reads = reads;
179+
this.currentRead = 0;
180+
}
181+
182+
@Override
183+
public void close() { }
184+
185+
@Override
186+
public int read() throws IOException {
187+
throw new UnsupportedOperationException();
188+
}
189+
190+
@Override
191+
public int read(char[] b, int off, int len) throws IOException {
192+
if (currentRead >= reads.length) {
193+
return -1;
194+
}
195+
char[] bytes = reads[currentRead++];
196+
if (len < bytes.length) {
197+
throw new IllegalArgumentException();
198+
}
199+
System.arraycopy(bytes, 0, b, off, bytes.length);
200+
return bytes.length;
201+
}
202+
}
105203
}

0 commit comments

Comments
 (0)