Skip to content

Commit 18819b1

Browse files
fabienrenaudcowtowncoder
authored andcommitted
Backport #603 fix, update release notes
1 parent b2be2c4 commit 18819b1

File tree

5 files changed

+129
-11
lines changed

5 files changed

+129
-11
lines changed

release-notes/CREDITS-2.x

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,12 @@ David Nault (dnault@github)
196196
(2.10.0)
197197
198198
Fabien Renaud (fabienrenaud@github)
199-
* Reported, contributed fix fir #533: UTF-8 BOM not accounted for in
199+
* Reported, contributed fix for #533: UTF-8 BOM not accounted for in
200200
`JsonLocation.getByteOffset()`
201201
(2.10.0)
202+
* Reported, contributed fix for #603: 'JsonParser.getCurrentLocation()`
203+
byte/char offset update incorrectly for big payloads
204+
(2.10.3)
202205

203206
Todd O'Bryan (toddobryan@github)
204207
* Contributed fix fox #455: Jackson reports wrong locations for JsonEOFException

release-notes/VERSION-2.x

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ JSON library.
1818

1919
#592: DataFormatMatcher#getMatchedFormatName throws NPE when no match exists
2020
(reported by Scott L)
21+
#603: 'JsonParser.getCurrentLocation()` byte/char offset update incorrectly for big payloads
22+
(reported, fix contributed by Fabien R)
2123

2224
2.10.2 (05-Jan-2020)
2325

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,10 @@ protected void _loadMoreGuaranteed() throws IOException {
244244

245245
protected boolean _loadMore() throws IOException
246246
{
247-
final int bufSize = _inputEnd;
248-
249247
if (_reader != null) {
250248
int count = _reader.read(_inputBuffer, 0, _inputBuffer.length);
251249
if (count > 0) {
252-
_inputPtr = 0;
253-
_inputEnd = count;
254-
250+
final int bufSize = _inputEnd;
255251
_currInputProcessed += bufSize;
256252
_currInputRowStart -= bufSize;
257253

@@ -260,6 +256,9 @@ protected boolean _loadMore() throws IOException
260256
// in negative value, which is fine as combine value remains unchanged.
261257
_nameStartOffset -= bufSize;
262258

259+
_inputPtr = 0;
260+
_inputEnd = count;
261+
263262
return true;
264263
}
265264
// End of input

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@ public Object getInputSource() {
210210

211211
protected final boolean _loadMore() throws IOException
212212
{
213-
final int bufSize = _inputEnd;
214213
if (_inputStream != null) {
215214
int space = _inputBuffer.length;
216215
if (space == 0) { // only occurs when we've been closed
@@ -219,17 +218,19 @@ protected final boolean _loadMore() throws IOException
219218

220219
int count = _inputStream.read(_inputBuffer, 0, space);
221220
if (count > 0) {
222-
_inputPtr = 0;
223-
_inputEnd = count;
221+
final int bufSize = _inputEnd;
224222

225-
_currInputProcessed += _inputEnd;
226-
_currInputRowStart -= _inputEnd;
223+
_currInputProcessed += bufSize;
224+
_currInputRowStart -= bufSize;
227225

228226
// 26-Nov-2015, tatu: Since name-offset requires it too, must offset
229227
// this increase to avoid "moving" name-offset, resulting most likely
230228
// in negative value, which is fine as combine value remains unchanged.
231229
_nameStartOffset -= bufSize;
232230

231+
_inputPtr = 0;
232+
_inputEnd = count;
233+
233234
return true;
234235
}
235236
// End of input

src/test/java/com/fasterxml/jackson/core/read/LocationOffsetsTest.java

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import com.fasterxml.jackson.core.*;
44

5+
import java.io.IOException;
6+
import java.util.Random;
7+
58
public class LocationOffsetsTest extends com.fasterxml.jackson.core.BaseTest
69
{
710
final JsonFactory JSON_F = new JsonFactory();
@@ -104,6 +107,45 @@ public void testOffsetWithoutInputOffset() throws Exception
104107
p.close();
105108
}
106109

110+
public void testWithLazyStringReadStreaming() throws Exception
111+
{
112+
_testWithLazyStringRead(MODE_READER);
113+
_testWithLazyStringRead(MODE_INPUT_STREAM);
114+
}
115+
116+
public void testWithLazyStringReadDataInput() throws Exception
117+
{
118+
// DataInput-backed reader does not track column, so can not
119+
// verify much; but force finishToken() regardless
120+
JsonParser p = createParser(JSON_F, MODE_DATA_INPUT, "[\"text\"]");
121+
assertToken(JsonToken.START_ARRAY, p.nextToken());
122+
assertToken(JsonToken.VALUE_STRING, p.nextToken());
123+
assertEquals(1, p.getCurrentLocation().getLineNr());
124+
p.finishToken();
125+
assertEquals("text", p.getText());
126+
p.close();
127+
}
128+
129+
private void _testWithLazyStringRead(int readMode) throws Exception
130+
{
131+
JsonParser p = createParser(JSON_F, readMode, "[\"text\"]");
132+
assertToken(JsonToken.START_ARRAY, p.nextToken());
133+
assertToken(JsonToken.VALUE_STRING, p.nextToken());
134+
// initially location pointing to first character
135+
assertEquals(3, p.getCurrentLocation().getColumnNr());
136+
p.finishToken();
137+
// but will move once we force reading
138+
assertEquals(8, p.getCurrentLocation().getColumnNr());
139+
// and no change if we call again (but is ok to call)
140+
p.finishToken();
141+
assertEquals(8, p.getCurrentLocation().getColumnNr());
142+
143+
// also just for fun, verify content
144+
assertEquals("text", p.getText());
145+
assertEquals(8, p.getCurrentLocation().getColumnNr());
146+
p.close();
147+
}
148+
107149
// for [core#533]
108150
public void testUtf8Bom() throws Exception
109151
{
@@ -192,4 +234,75 @@ private byte[] withUtf8Bom(byte[] bytes) {
192234
System.arraycopy(bytes, 0, arr, 3, bytes.length);
193235
return arr;
194236
}
237+
238+
// [core#603]
239+
public void testBigPayload() throws IOException {
240+
JsonLocation loc;
241+
JsonParser p;
242+
243+
String doc = "{\"key\":\"" + generateRandomAlpha(50000) + "\"}";
244+
245+
p = createParserUsingStream(JSON_F, doc, "UTF-8");
246+
247+
assertToken(JsonToken.START_OBJECT, p.nextToken());
248+
loc = p.getTokenLocation();
249+
assertEquals(0, loc.getByteOffset());
250+
assertEquals(-1L, loc.getCharOffset());
251+
assertEquals(1, loc.getLineNr());
252+
assertEquals(1, loc.getColumnNr());
253+
loc = p.getCurrentLocation();
254+
assertEquals(1, loc.getByteOffset());
255+
assertEquals(-1L, loc.getCharOffset());
256+
assertEquals(1, loc.getLineNr());
257+
assertEquals(2, loc.getColumnNr());
258+
259+
assertToken(JsonToken.FIELD_NAME, p.nextToken());
260+
loc = p.getTokenLocation();
261+
assertEquals(1, loc.getByteOffset());
262+
assertEquals(-1L, loc.getCharOffset());
263+
assertEquals(1, loc.getLineNr());
264+
assertEquals(2, loc.getColumnNr());
265+
loc = p.getCurrentLocation();
266+
assertEquals(8, loc.getByteOffset());
267+
assertEquals(-1L, loc.getCharOffset());
268+
assertEquals(1, loc.getLineNr());
269+
assertEquals(9, loc.getColumnNr());
270+
271+
assertToken(JsonToken.VALUE_STRING, p.nextToken());
272+
loc = p.getTokenLocation();
273+
assertEquals(7, loc.getByteOffset());
274+
assertEquals(-1L, loc.getCharOffset());
275+
assertEquals(1, loc.getLineNr());
276+
assertEquals(8, loc.getColumnNr());
277+
loc = p.getCurrentLocation();
278+
assertEquals(8, loc.getByteOffset());
279+
assertEquals(-1L, loc.getCharOffset());
280+
assertEquals(1, loc.getLineNr());
281+
assertEquals(9, loc.getColumnNr());
282+
283+
p.getTextCharacters();
284+
loc = p.getTokenLocation();
285+
assertEquals(7, loc.getByteOffset());
286+
assertEquals(-1L, loc.getCharOffset());
287+
assertEquals(1, loc.getLineNr());
288+
assertEquals(8, loc.getColumnNr());
289+
loc = p.getCurrentLocation();
290+
assertEquals(doc.length() - 1, loc.getByteOffset());
291+
assertEquals(-1L, loc.getCharOffset());
292+
assertEquals(1, loc.getLineNr());
293+
assertEquals(doc.length(), loc.getColumnNr());
294+
295+
p.close();
296+
}
297+
298+
private String generateRandomAlpha(int length) {
299+
StringBuilder sb = new StringBuilder(length);
300+
Random rnd = new Random(length);
301+
for (int i = 0; i < length; ++i) {
302+
// let's limit it not to include surrogate pairs:
303+
char ch = (char) ('A' + rnd.nextInt(26));
304+
sb.append(ch);
305+
}
306+
return sb.toString();
307+
}
195308
}

0 commit comments

Comments
 (0)