This is an automated email from the ASF dual-hosted git repository.
rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/johnzon.git
The following commit(s) were added to refs/heads/master by this push:
new 62ed694 [JOHNZON-216] ensure escaped characters don't break the
parser and autoajust algorithm
62ed694 is described below
commit 62ed6949eb3e2053c6ea6720ef0125004f20b89a
Author: Romain Manni-Bucau <[email protected]>
AuthorDate: Tue Aug 4 08:56:24 2020 +0200
[JOHNZON-216] ensure escaped characters don't break the parser and
autoajust algorithm
---
.../apache/johnzon/core/JsonStreamParserImpl.java | 34 +++++++++++++---------
.../johnzon/core/JsonParserStreamingTest.java | 30 ++++++++++++++++---
.../org/apache/johnzon/core/JsonParserTest.java | 9 +++---
3 files changed, 51 insertions(+), 22 deletions(-)
diff --git
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
index bf4a2c0..3e75b5c 100644
---
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
+++
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
@@ -160,6 +160,9 @@ public class JsonStreamParserImpl extends
JohnzonJsonParserImpl implements JsonC
//append a single char to the value buffer
private void appendToCopyBuffer(final char c) {
+ if (fallBackCopyBufferLength >= fallBackCopyBuffer.length - 1) {
+ doAutoAdjust(1);
+ }
fallBackCopyBuffer[fallBackCopyBufferLength++] = c;
}
@@ -173,19 +176,7 @@ public class JsonStreamParserImpl extends
JohnzonJsonParserImpl implements JsonC
}
if (fallBackCopyBufferLength >= fallBackCopyBuffer.length -
length) { // not good at runtime but handled
- if (!autoAdjust) {
- throw new ArrayIndexOutOfBoundsException("Buffer too small
for such a long string");
- }
-
- final char[] newArray = new char[fallBackCopyBuffer.length +
Math.max(getBufferExtends(fallBackCopyBuffer.length), length)];
- // TODO: log to adjust size once?
- System.arraycopy(fallBackCopyBuffer, 0, newArray, 0,
fallBackCopyBufferLength);
- System.arraycopy(buffer, startOfValueInBuffer, newArray,
fallBackCopyBufferLength, length);
- if (releaseFallBackCopyBufferLength) {
- bufferProvider.release(fallBackCopyBuffer);
- releaseFallBackCopyBufferLength = false;
- }
- fallBackCopyBuffer = newArray;
+ doAutoAdjust(length);
} else {
System.arraycopy(buffer, startOfValueInBuffer,
fallBackCopyBuffer, fallBackCopyBufferLength, length);
}
@@ -195,6 +186,22 @@ public class JsonStreamParserImpl extends
JohnzonJsonParserImpl implements JsonC
startOfValueInBuffer = endOfValueInBuffer = -1;
}
+ private void doAutoAdjust(final int length) {
+ if (!autoAdjust) {
+ throw new ArrayIndexOutOfBoundsException("Buffer too small for
such a long string");
+ }
+
+ final char[] newArray = new char[fallBackCopyBuffer.length +
Math.max(getBufferExtends(fallBackCopyBuffer.length), length)];
+ // TODO: log to adjust size once?
+ System.arraycopy(fallBackCopyBuffer, 0, newArray, 0,
fallBackCopyBufferLength);
+ System.arraycopy(buffer, startOfValueInBuffer, newArray,
fallBackCopyBufferLength, length);
+ if (releaseFallBackCopyBufferLength) {
+ bufferProvider.release(fallBackCopyBuffer);
+ releaseFallBackCopyBufferLength = false;
+ }
+ fallBackCopyBuffer = newArray;
+ }
+
/**
* @return the amount of bytes the current buffer should get extended with
*/
@@ -614,7 +621,6 @@ public class JsonStreamParserImpl extends
JohnzonJsonParserImpl implements JsonC
//another escape chars, for example \t
} else {
appendToCopyBuffer(Strings.asEscapedChar(n));
-
}
} else {
diff --git
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserStreamingTest.java
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserStreamingTest.java
index 2cc5d21..dfdff4e 100644
---
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserStreamingTest.java
+++
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserStreamingTest.java
@@ -18,17 +18,39 @@
*/
package org.apache.johnzon.core;
-import java.io.StringReader;
-import java.util.stream.Collectors;
+import org.junit.Test;
import javax.json.Json;
import javax.json.stream.JsonParser;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.nio.charset.StandardCharsets;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
-import org.junit.Test;
-
+import static java.util.stream.Collectors.joining;
import static org.junit.Assert.assertEquals;
public class JsonParserStreamingTest {
+ @Test
+ public void parseEscapeCharacters() throws IOException {
+ final int len = 8192;
+ final byte[] bytes = ("{\"source\":\"" +
+ IntStream.range(0, 16558).mapToObj(it ->
"\\").collect(joining("")) +
+ "\t\"}").getBytes(StandardCharsets.UTF_8);
+
+ final BufferStrategy.BufferProvider<char[]> bs =
BufferStrategyFactory.valueOf("QUEUE").newCharProvider(len);
+ try (final InputStream stream = new ByteArrayInputStream(bytes)) {
+ final JsonStreamParserImpl impl = new JsonStreamParserImpl(stream,
len, bs, bs, false);
+ while (impl.hasNext()) {
+ impl.next();
+ }
+ } catch (final ArrayIndexOutOfBoundsException aioobe) {
+ assertEquals("Buffer too small for such a long string",
aioobe.getMessage());
+ }
+ }
@Test
public void testArrayStream() {
diff --git
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
index bbc8d71..d388f5f 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
@@ -32,6 +32,7 @@ import java.io.StringReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -57,10 +58,10 @@ import org.junit.Test;
public class JsonParserTest {
- static final Charset UTF_8 = Charset.forName("UTF-8");
- static final Charset UTF_16BE = Charset.forName("UTF-16BE");
- static final Charset UTF_16LE = Charset.forName("UTF-16LE");
- static final Charset UTF_16 = Charset.forName("UTF-16");
+ static final Charset UTF_8 = StandardCharsets.UTF_8;
+ static final Charset UTF_16BE = StandardCharsets.UTF_16BE;
+ static final Charset UTF_16LE = StandardCharsets.UTF_16LE;
+ static final Charset UTF_16 = StandardCharsets.UTF_16;
static final Charset UTF_32LE = Charset.forName("UTF-32LE");
static final Charset UTF_32BE = Charset.forName("UTF-32BE");