Merge pull request #745 from square/eric.incorrect-skipValue

Fix infinite loop when calling skipValue at the end an object or array.
This commit is contained in:
Jesse Wilson 2018-11-18 10:18:02 -05:00 committed by GitHub
commit 8b17ecedae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 2 deletions

View file

@ -957,11 +957,19 @@ final class JsonUtf8Reader extends JsonReader {
pushScope(JsonScope.EMPTY_OBJECT); pushScope(JsonScope.EMPTY_OBJECT);
count++; count++;
} else if (p == PEEKED_END_ARRAY) { } else if (p == PEEKED_END_ARRAY) {
stackSize--;
count--; count--;
if (count < 0) {
throw new JsonDataException(
"Expected a value but was " + peek() + " at path " + getPath());
}
stackSize--;
} else if (p == PEEKED_END_OBJECT) { } else if (p == PEEKED_END_OBJECT) {
stackSize--;
count--; count--;
if (count < 0) {
throw new JsonDataException(
"Expected a value but was " + peek() + " at path " + getPath());
}
stackSize--;
} else if (p == PEEKED_UNQUOTED_NAME || p == PEEKED_UNQUOTED) { } else if (p == PEEKED_UNQUOTED_NAME || p == PEEKED_UNQUOTED) {
skipUnquotedValue(); skipUnquotedValue();
} else if (p == PEEKED_DOUBLE_QUOTED || p == PEEKED_DOUBLE_QUOTED_NAME) { } else if (p == PEEKED_DOUBLE_QUOTED || p == PEEKED_DOUBLE_QUOTED_NAME) {
@ -970,6 +978,9 @@ final class JsonUtf8Reader extends JsonReader {
skipQuotedValue(SINGLE_QUOTE_OR_SLASH); skipQuotedValue(SINGLE_QUOTE_OR_SLASH);
} else if (p == PEEKED_NUMBER) { } else if (p == PEEKED_NUMBER) {
buffer.skip(peekedNumberLength); buffer.skip(peekedNumberLength);
} else if (p == PEEKED_EOF) {
throw new JsonDataException(
"Expected a value but was " + peek() + " at path " + getPath());
} }
peeked = PEEKED_NONE; peeked = PEEKED_NONE;
} while (count != 0); } while (count != 0);

View file

@ -308,6 +308,9 @@ final class JsonValueReader extends JsonReader {
Object skipped = stackSize != 0 ? stack[stackSize - 1] : null; Object skipped = stackSize != 0 ? stack[stackSize - 1] : null;
if (skipped instanceof JsonIterator) {
throw new JsonDataException("Expected a value but was " + peek() + " at path " + getPath());
}
if (skipped instanceof Map.Entry) { if (skipped instanceof Map.Entry) {
// We're skipping a name. Promote the map entry's value. // We're skipping a name. Promote the map entry's value.
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) stack[stackSize - 1]; Map.Entry<?, ?> entry = (Map.Entry<?, ?>) stack[stackSize - 1];
@ -315,6 +318,8 @@ final class JsonValueReader extends JsonReader {
} else if (stackSize > 0) { } else if (stackSize > 0) {
// We're skipping a value. // We're skipping a value.
remove(); remove();
} else {
throw new JsonDataException("Expected a value but was " + peek() + " at path " + getPath());
} }
} }

View file

@ -988,6 +988,44 @@ public final class JsonReaderTest {
assertThat(reader.hasNext()).isFalse(); assertThat(reader.hasNext()).isFalse();
} }
@Test public void skipValueAtEndOfObjectFails() throws IOException {
JsonReader reader = newReader("{}");
reader.beginObject();
try {
reader.skipValue();
fail();
} catch (JsonDataException expected) {
assertThat(expected).hasMessage("Expected a value but was END_OBJECT at path $.");
}
reader.endObject();
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
}
@Test public void skipValueAtEndOfArrayFails() throws IOException {
JsonReader reader = newReader("[]");
reader.beginArray();
try {
reader.skipValue();
fail();
} catch (JsonDataException expected) {
assertThat(expected).hasMessage("Expected a value but was END_ARRAY at path $[0]");
}
reader.endArray();
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
}
@Test public void skipValueAtEndOfDocumentFails() throws IOException {
JsonReader reader = newReader("1");
reader.nextInt();
try {
reader.skipValue();
fail();
} catch (JsonDataException expected) {
assertThat(expected).hasMessage("Expected a value but was END_DOCUMENT at path $");
}
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
}
@Test public void basicPeekJson() throws IOException { @Test public void basicPeekJson() throws IOException {
JsonReader reader = newReader("{\"a\":12,\"b\":[34,56],\"c\":78}"); JsonReader reader = newReader("{\"a\":12,\"b\":[34,56],\"c\":78}");
reader.beginObject(); reader.beginObject();