diff --git a/impl/src/main/java/org/glassfish/json/JsonParserImpl.java b/impl/src/main/java/org/glassfish/json/JsonParserImpl.java index e432c9e..b32f79a 100644 --- a/impl/src/main/java/org/glassfish/json/JsonParserImpl.java +++ b/impl/src/main/java/org/glassfish/json/JsonParserImpl.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012-2018 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -352,7 +352,13 @@ public JsonLocation getLastCharLocation() { @Override public boolean hasNext() { - return tokenizer.hasNextToken(); + if (!tokenizer.hasNextToken()) { + if (!stack.isEmpty()) { + currentContext.getNextEvent(); + } + return false; + } + return true; } @Override @@ -451,7 +457,16 @@ private final class ObjectContext extends Context { 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]"); @@ -516,6 +531,14 @@ private final class ArrayContext extends Context { @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/JsonParserTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java index 7c8bacc..3bc0ebb 100644 --- a/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java +++ b/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012-2018 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -60,6 +60,7 @@ import java.util.NoSuchElementException; import java.util.Random; import java.util.Scanner; +import javax.json.stream.JsonParsingException; import org.glassfish.json.api.BufferPool; @@ -787,4 +788,57 @@ public void testStringUsingBuffers() throws Throwable { } } + 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 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(); + } }