[ee4j_8] fix for regression #104 (#127) (#128) Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
diff --git a/impl/src/main/java/org/glassfish/json/JsonParserImpl.java b/impl/src/main/java/org/glassfish/json/JsonParserImpl.java index 1857a92..899cfe0 100644 --- a/impl/src/main/java/org/glassfish/json/JsonParserImpl.java +++ b/impl/src/main/java/org/glassfish/json/JsonParserImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -282,6 +282,7 @@ if (currentEvent == Event.START_ARRAY) { currentContext.skip(); currentContext = stack.pop(); + currentEvent = Event.END_ARRAY; } } @@ -290,6 +291,7 @@ if (currentEvent == Event.START_OBJECT) { currentContext.skip(); currentContext = stack.pop(); + currentEvent = Event.END_OBJECT; } } @@ -328,7 +330,18 @@ @Override public boolean hasNext() { - return tokenizer.hasNextToken(); + if (stack.isEmpty() && (currentEvent != null && currentEvent.compareTo(Event.KEY_NAME) > 0)) { + JsonToken token = tokenizer.nextToken(); + if (token != JsonToken.EOF) { + throw new JsonParsingException(JsonMessages.PARSER_EXPECTED_EOF(token), + getLastCharLocation()); + } + return false; + } else if (!stack.isEmpty() && !tokenizer.hasNextToken()) { + currentEvent = currentContext.getNextEvent(); + return false; + } + return true; } @Override @@ -427,7 +440,16 @@ public Event getNextEvent() { // Handle 1. } 2. name:value 3. ,name:value JsonToken token = tokenizer.nextToken(); - if (currentEvent == Event.KEY_NAME) { + if (token == JsonToken.EOF) { + switch (currentEvent) { + case START_OBJECT: + throw parsingException(token, "[STRING, CURLYCLOSE]"); + case KEY_NAME: + throw parsingException(token, "[COLON]"); + default: + throw parsingException(token, "[COMMA, CURLYCLOSE]"); + } + } else if (currentEvent == Event.KEY_NAME) { // Handle 1. :value if (token != JsonToken.COLON) { throw parsingException(token, "[COLON]"); @@ -492,6 +514,14 @@ @Override public Event getNextEvent() { JsonToken token = tokenizer.nextToken(); + if (token == JsonToken.EOF) { + switch (currentEvent) { + case START_ARRAY: + throw parsingException(token, "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL]"); + default: + throw parsingException(token, "[COMMA, CURLYCLOSE]"); + } + } if (token == JsonToken.SQUARECLOSE) { currentContext = stack.pop(); return Event.END_ARRAY;
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonParserSkipTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonParserSkipTest.java index a44e214..c77d87b 100644 --- a/tests/src/test/java/org/glassfish/json/tests/JsonParserSkipTest.java +++ b/tests/src/test/java/org/glassfish/json/tests/JsonParserSkipTest.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java index 0f6ca53..83eb517 100644 --- a/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java +++ b/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -36,6 +36,7 @@ import java.util.NoSuchElementException; import java.util.Random; import java.util.Scanner; +import javax.json.stream.JsonParsingException; import org.glassfish.json.api.BufferPool; @@ -763,4 +764,64 @@ } } + public void testExceptionsFromHasNext() { + checkExceptionFromHasNext("{"); + checkExceptionFromHasNext("{\"key\""); + checkExceptionFromHasNext("{\"name\" : \"prop\""); + checkExceptionFromHasNext("{\"name\" : 3"); + checkExceptionFromHasNext("{\"name\" : true"); + checkExceptionFromHasNext("{\"name\" : null"); + checkExceptionFromHasNext("{\"name\" : {\"$eq\":\"cdc\"}"); + checkExceptionFromHasNext("{\"name\" : [{\"$eq\":\"cdc\"}]"); + checkExceptionFromHasNext("["); + checkExceptionFromHasNext("{\"name\" : [{\"key\" : [[{\"a\" : 1}]"); + checkExceptionFromHasNext("{\"unique\":true,\"name\":\"jUnitTestIndexNeg005\", \"fields\":[{\"order\":-1,\"path\":\"city.zip\"}"); + } + + public void testEOFFromHasNext() { + checkExceptionFromHasNext("{ \"d\" : 1 } 2 3 4"); + checkExceptionFromHasNext("[ {\"d\" : 1 }] 2 3 4"); + checkExceptionFromHasNext("1 2 3 4"); + checkExceptionFromHasNext("null 2 3 4"); + } + + public void testExceptionsFromNext() { + checkExceptionFromNext("{\"name\" : fal"); + checkExceptionFromNext("{\"name\" : nu"); + checkExceptionFromNext("{\"name\" : \"pro"); + checkExceptionFromNext("{\"key\":"); + checkExceptionFromNext("fal"); + } + + private void checkExceptionFromHasNext(String input) { + try (JsonParser parser = Json.createParser(new StringReader(input))) { + try { + while (parser.hasNext()) { + try { + parser.next(); + } catch (Throwable t1) { + fail("Exception should occur from hasNext() for '" + input + "'"); + } + } + } catch (JsonParsingException t) { + //this is OK + return; + } + } + fail(); + } + + private void checkExceptionFromNext(String input) { + try (JsonParser parser = Json.createParser(new StringReader(input))) { + while (parser.hasNext()) { + try { + parser.next(); + } catch (JsonParsingException t) { + //this is OK + return; + } + } + } + fail(); + } }