Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/main/java/tools/jackson/core/json/ReaderBasedJsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -1393,6 +1393,9 @@ protected final JsonToken _parseUnsignedNumber(int ch) throws JacksonException
// As per #105, need separating space between root values; check here
if (_streamReadContext.inRoot()) {
_verifyRootSpace(ch);
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator(ch);
}
int len = ptr-startPtr;
_textBuffer.resetWithShared(_inputBuffer, startPtr, len);
Expand Down Expand Up @@ -1458,6 +1461,9 @@ private final JsonToken _parseFloat(int ch, int startPtr, int ptr, boolean neg,
// As per #105, need separating space between root values; check here
if (_streamReadContext.inRoot()) {
_verifyRootSpace(ch);
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator(ch);
}
int len = ptr-startPtr;
_textBuffer.resetWithShared(_inputBuffer, startPtr, len);
Expand Down Expand Up @@ -1515,6 +1521,9 @@ private final JsonToken _parseSignedNumber(final boolean negative) throws Jackso
_inputPtr = ptr;
if (_streamReadContext.inRoot()) {
_verifyRootSpace(ch);
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator(ch);
}
int len = ptr-startPtr;
_textBuffer.resetWithShared(_inputBuffer, startPtr, len);
Expand Down Expand Up @@ -1668,6 +1677,9 @@ private final JsonToken _parseNumber2(boolean neg, int startPtr) throws JacksonE
--_inputPtr;
if (_streamReadContext.inRoot()) {
_verifyRootSpace(c);
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator(c);
}
}
_textBuffer.setCurrentLength(outPtr);
Expand Down Expand Up @@ -1807,6 +1819,40 @@ private final void _verifyRootSpace(int ch) throws JacksonException
_reportMissingRootWS(ch);
}

// [core#105]: Verify non-root values followed by valid separator
private final void _verifyNonRootSeparator(int ch) throws JacksonException
{
// caller had pushed it back, before calling; reset
++_inputPtr;
switch (ch) {
// Whitespace is always valid
case ' ':
case '\t':
return;
case '\r':
--_inputPtr;
return;
case '\n':
++_currInputRow;
_currInputRowStart = _inputPtr;
return;
// Valid structural characters
case ',': // next value
case ']': // end of array
case '}': // end of object
--_inputPtr; // push back for proper processing
return;
}
// Could be a comment - need to check
if (ch == '/' || ch == '#') {
// Let it fall through to be handled by nextToken() which will
// properly validate based on enabled features
--_inputPtr;
return;
}
_reportUnexpectedChar(ch, "Expected space, comma, or structural character after number");
}

/*
/**********************************************************************
/* Internal methods, secondary parsing
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/tools/jackson/core/json/UTF8DataInputJsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,9 @@ protected JsonToken _parseUnsignedNumber(int c) throws IOException
_nextByte = c;
if (_streamReadContext.inRoot()) {
_verifyRootSpace();
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator();
}
// And there we have it!
return resetInt(false, intLen);
Expand Down Expand Up @@ -1122,6 +1125,9 @@ private final JsonToken _parseSignedNumber(boolean negative) throws IOException
_nextByte = c;
if (_streamReadContext.inRoot()) {
_verifyRootSpace();
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator();
}
// And there we have it!
return resetInt(negative, intLen);
Expand Down Expand Up @@ -1227,6 +1233,9 @@ private final JsonToken _parseFloat(char[] outBuf, int outPtr, int c,
_nextByte = c;
if (_streamReadContext.inRoot()) {
_verifyRootSpace();
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator();
}
_textBuffer.setCurrentLength(outPtr);

Expand Down Expand Up @@ -1255,6 +1264,26 @@ private final void _verifyRootSpace() throws JacksonException
_reportMissingRootWS(ch);
}

// [core#105]: Verify non-root values followed by valid separator
private final void _verifyNonRootSeparator() throws JacksonException
{
int ch = _nextByte;
if (ch <= INT_SPACE) {
_nextByte = -1;
if (ch == INT_CR || ch == INT_LF) {
++_currInputRow;
}
return;
}
// Valid structural characters and comment starts
if (ch == INT_COMMA || ch == INT_RBRACKET || ch == INT_RCURLY
|| ch == INT_SLASH || ch == INT_HASH) {
// Keep _nextByte set for proper processing
return;
}
_reportUnexpectedChar(ch, "Expected space, comma, or structural character after number");
}

/*
/**********************************************************************
/* Internal methods, secondary parsing
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/tools/jackson/core/json/UTF8StreamJsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -1824,6 +1824,9 @@ protected JsonToken _parseUnsignedNumber(int c) throws JacksonException
// As per #105, need separating space between root values; check here
if (_streamReadContext.inRoot()) {
_verifyRootSpace(c);
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator(c);
}
// And there we have it!
return resetInt(false, intLen);
Expand Down Expand Up @@ -1884,6 +1887,9 @@ private final JsonToken _parseSignedNumber(boolean negative) throws JacksonExcep
// As per #105, need separating space between root values; check here
if (_streamReadContext.inRoot()) {
_verifyRootSpace(c);
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator(c);
}

// And there we have it!
Expand Down Expand Up @@ -1920,6 +1926,9 @@ private final JsonToken _parseNumber2(char[] outBuf, int outPtr, boolean negativ
// As per #105, need separating space between root values; check here
if (_streamReadContext.inRoot()) {
_verifyRootSpace(_inputBuffer[_inputPtr] & 0xFF);
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator(_inputBuffer[_inputPtr] & 0xFF);
}

// And there we have it!
Expand Down Expand Up @@ -2052,6 +2061,9 @@ private final JsonToken _parseFloat(char[] outBuf, int outPtr, int c,
// As per [core#105], need separating space between root values; check here
if (_streamReadContext.inRoot()) {
_verifyRootSpace(c);
} else {
// [core#105]: Also verify non-root values have valid separator
_verifyNonRootSeparator(c);
}
}
_textBuffer.setCurrentLength(outPtr);
Expand Down Expand Up @@ -2095,6 +2107,35 @@ private final void _verifyRootSpace(int ch) throws JacksonException
_reportMissingRootWS(ch);
}

// [core#105]: Verify non-root values followed by valid separator
private final void _verifyNonRootSeparator(int ch) throws JacksonException
{
// caller had pushed it back, before calling; reset
++_inputPtr;
switch (ch) {
// Whitespace is always valid
case ' ':
case '\t':
return;
case '\r':
--_inputPtr;
return;
case '\n':
++_currInputRow;
_currInputRowStart = _inputPtr;
return;
// Valid structural characters
case ',': // next value
case ']': // end of array
case '}': // end of object
case '/': // start of comment (C-style)
case '#': // start of comment (YAML-style)
--_inputPtr; // push back for proper processing
return;
}
_reportUnexpectedChar(ch, "Expected space, comma, or structural character after number");
}

/*
/**********************************************************************
/* Internal methods, secondary parsing
Expand Down
1 change: 0 additions & 1 deletion src/test/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
opens tools.jackson.core.unittest.jsonptr;
opens tools.jackson.core.unittest.read;
opens tools.jackson.core.unittest.read.loc;
opens tools.jackson.core.unittest.tofix;
opens tools.jackson.core.unittest.tofix.async;
opens tools.jackson.core.unittest.sym;
opens tools.jackson.core.unittest.type;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tools.jackson.core.unittest.tofix;
package tools.jackson.core.unittest.read;

import org.junit.jupiter.api.Test;

Expand All @@ -10,47 +10,40 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;

// Tests for [core#679] - partially fixed by #105 fix, but "/" case still fails
class ParserErrorHandling679Test
extends tools.jackson.core.unittest.JacksonCoreTestBase
{
// [core#679]
@JacksonTestFailureExpected
@Test
void nonRootMangledFloats679Bytes() throws Exception {
_testNonRootMangledFloats679(MODE_INPUT_STREAM);
_testNonRootMangledFloats679(MODE_INPUT_STREAM_THROTTLED);
}

// [core#679]
@JacksonTestFailureExpected
@Test
void nonRootMangledFloats679DataInput() throws Exception {
_testNonRootMangledFloats679(MODE_DATA_INPUT);
}

// [core#679]
@Test
@JacksonTestFailureExpected
void nonRootMangledFloats679Chars() throws Exception {
_testNonRootMangledFloats679(MODE_READER);
}

// [core#679]
// "/" tests still fail - need more work to distinguish "/" from "//" and "/*"
@JacksonTestFailureExpected
@Test
void nonRootMangledInts679Bytes() throws Exception {
_testNonRootMangledInts(MODE_INPUT_STREAM);
_testNonRootMangledInts(MODE_INPUT_STREAM_THROTTLED);
}

// [core#679]
@JacksonTestFailureExpected
@Test
void nonRootMangledInts679DataInput() throws Exception {
_testNonRootMangledInts(MODE_DATA_INPUT);
}

// [core#679]
@JacksonTestFailureExpected
@Test
void nonRootMangledInts679Chars() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
package tools.jackson.core.unittest.tofix;
package tools.jackson.core.unittest.read;

import org.junit.jupiter.api.Test;

import tools.jackson.core.JsonParser;
import tools.jackson.core.JsonToken;
import tools.jackson.core.exc.StreamReadException;
import tools.jackson.core.unittest.testutil.failure.JacksonTestFailureExpected;

import static org.junit.jupiter.api.Assertions.fail;

// Failing tests for non-root-token problem
// Tests for [core#105] ("eager number parsing misses errors")
class ParserErrorHandlingBytes105Test
extends tools.jackson.core.unittest.JacksonCoreTestBase
{
// Tests for [core#105] ("eager number parsing misses errors")
@JacksonTestFailureExpected
@Test
void mangledIntsBytes() throws Exception {
_testMangledNonRootInts(MODE_INPUT_STREAM);
_testMangledNonRootInts(MODE_INPUT_STREAM_THROTTLED);
}

@JacksonTestFailureExpected
@Test
void mangledFloatsBytes() throws Exception {
_testMangledNonRootFloats(MODE_INPUT_STREAM);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
package tools.jackson.core.unittest.tofix;
package tools.jackson.core.unittest.read;

import org.junit.jupiter.api.Test;

import tools.jackson.core.JsonParser;
import tools.jackson.core.JsonToken;
import tools.jackson.core.exc.StreamReadException;
import tools.jackson.core.unittest.testutil.failure.JacksonTestFailureExpected;

import static org.junit.jupiter.api.Assertions.fail;

// Failing tests for non-root-token problem
// Tests for [core#105] ("eager number parsing misses errors")
class ParserErrorHandlingChars105Test
extends tools.jackson.core.unittest.JacksonCoreTestBase
{
// Tests for [core#105] ("eager number parsing misses errors")
@JacksonTestFailureExpected
@Test
void mangledIntsChars() throws Exception {
_testMangledNonRootInts(MODE_READER);
}

@JacksonTestFailureExpected
@Test
void mangledFloatsChars() throws Exception {
_testMangledNonRootFloats(MODE_READER);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
package tools.jackson.core.unittest.tofix;
package tools.jackson.core.unittest.read;

import org.junit.jupiter.api.Test;

import tools.jackson.core.JsonParser;
import tools.jackson.core.JsonToken;
import tools.jackson.core.exc.StreamReadException;
import tools.jackson.core.unittest.testutil.failure.JacksonTestFailureExpected;

import static org.junit.jupiter.api.Assertions.fail;

// Failing tests for non-root-token problem
// Tests for [core#105] ("eager number parsing misses errors")
class ParserErrorHandlingDataInput105Test
extends tools.jackson.core.unittest.JacksonCoreTestBase
{
// Tests for [core#105] ("eager number parsing misses errors")
@JacksonTestFailureExpected
@Test
void mangledIntsDataInput() throws Exception {
// 02-Jun-2017, tatu: Fails to fail; should check whether this is expected
// (since DataInput can't do look-ahead)
_testMangledNonRootInts(MODE_DATA_INPUT);
}

@JacksonTestFailureExpected
@Test
void mangledFloatsDataInput() throws Exception {
_testMangledNonRootFloats(MODE_DATA_INPUT);
Expand Down
Loading