Repository: johnzon
Updated Branches:
  refs/heads/master b2d205738 -> 78ad82adb


JOHNZON-194 ensure jsonparser tolerates multiple close calls


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/78ad82ad
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/78ad82ad
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/78ad82ad

Branch: refs/heads/master
Commit: 78ad82adb99fc9083506dca9afc5fb3089bbf37c
Parents: b2d2057
Author: Romain Manni-Bucau <[email protected]>
Authored: Sun Nov 11 18:02:39 2018 +0100
Committer: Romain Manni-Bucau <[email protected]>
Committed: Sun Nov 11 18:02:39 2018 +0100

----------------------------------------------------------------------
 .../johnzon/core/JsonStreamParserImpl.java      |  8 ++++
 .../org/apache/johnzon/core/JsonParserTest.java | 41 ++++++++++++++++++++
 2 files changed, 49 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/78ad82ad/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
----------------------------------------------------------------------
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 cd6022e..18f0a1c 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
@@ -95,6 +95,8 @@ public class JsonStreamParserImpl extends 
JohnzonJsonParserImpl implements JsonC
 
     private int arrayDepth = 0;
 
+    private boolean closed;
+
     //minimal stack implementation
     private static final class StructureElement {
         private final StructureElement previous;
@@ -973,6 +975,10 @@ public class JsonStreamParserImpl extends 
JohnzonJsonParserImpl implements JsonC
 
     @Override
     public void close() {
+        if (closed) {
+            return;
+        }
+
         bufferProvider.release(buffer);
         if (releaseFallBackCopyBufferLength) {
             valueProvider.release(fallBackCopyBuffer);
@@ -982,6 +988,8 @@ public class JsonStreamParserImpl extends 
JohnzonJsonParserImpl implements JsonC
             in.close();
         } catch (final IOException e) {
             throw new JsonException("Unexpected IO exception " + 
e.getMessage(), e);
+        } finally {
+            closed = true;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/johnzon/blob/78ad82ad/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
----------------------------------------------------------------------
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 fb84307..0eac634 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
@@ -31,9 +31,12 @@ import java.io.InputStream;
 import java.io.StringReader;
 import java.math.BigDecimal;
 import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.NoSuchElementException;
+import java.util.function.Function;
 
 import javax.json.Json;
 import javax.json.JsonArray;
@@ -67,6 +70,44 @@ public class JsonParserTest {
     }
 
     @Test
+    public void avoidBufferStrategyLeaks() {
+        final Function<JsonParser, String> parse = parser -> {
+            final Collection<String> output = new ArrayList<>();
+            Event e;
+            do {
+                e = parser.next();
+                switch (e) {
+                    case KEY_NAME:
+                        output.add("KEY_NAME: " + parser.getString());
+                        break;
+                    case VALUE_STRING:
+                        output.add("VALUE_STRING: " + parser.getString());
+                        break;
+                    default:
+                        break;
+                }
+            } while (parser.hasNext());
+            return String.join("/", output);
+        };
+        final String jsonText1 = "{\"name\":\"App_1\", \"value\":\"value_1\"}";
+        final String jsonText2 = "{\"name\":\"App_2\", \"value\":\"value_2\"}";
+        final JsonParser jsonParser = Json.createParser(new 
ByteArrayInputStream(jsonText1.getBytes()));
+        jsonParser.close();
+        jsonParser.close();
+
+        final JsonParser jsonParser1 = Json.createParser(new 
ByteArrayInputStream(jsonText1.getBytes()));
+        jsonParser1.next();   // write jsonParser1 buffer
+        final JsonParser jsonParser2 = Json.createParser(new 
ByteArrayInputStream(jsonText2.getBytes()));
+        jsonParser2.next();   // overwrite jsonParser1 buffer
+
+        assertEquals("KEY_NAME: name/VALUE_STRING: App_1/KEY_NAME: 
value/VALUE_STRING: value_1", parse.apply(jsonParser1));
+        assertEquals("KEY_NAME: name/VALUE_STRING: App_2/KEY_NAME: 
value/VALUE_STRING: value_2", parse.apply(jsonParser2));
+
+        jsonParser1.close();
+        jsonParser2.close();
+    }
+
+    @Test
     public void emptyObject() {
         final JsonParser parser = Json.createParser(new StringReader(""));
         assertFalse(parser.hasNext());

Reply via email to