diff --git a/src/main/java/com/fasterxml/jackson/core/JsonParser.java b/src/main/java/com/fasterxml/jackson/core/JsonParser.java index 4265d48437..77ce5dd135 100644 --- a/src/main/java/com/fasterxml/jackson/core/JsonParser.java +++ b/src/main/java/com/fasterxml/jackson/core/JsonParser.java @@ -177,6 +177,23 @@ public enum Feature { */ ALLOW_SINGLE_QUOTES(false), + /** + * Feature that determines whether parser will allow use + * of the RS control character ({@code 0x1E}) within ignorable + * whitespace portion of input content (similar to TAB which + * is an allowed control character). + *

+ * Since JSON specification only allows a small set of control characters + * as whitespace by default, + * this is a non-standard feature, and as such disabled by default. + *

+ * NOTE: while not technically deprecated, it is recommended to use + * {@link com.fasterxml.jackson.core.json.JsonReadFeature#ALLOW_RS_CONTROL_CHAR} instead. + * + * @since 2.17 + */ + ALLOW_RS_CONTROL_CHAR(false), + /** * Feature that determines whether parser will allow * JSON Strings to contain unquoted control characters diff --git a/src/main/java/com/fasterxml/jackson/core/base/ParserMinimalBase.java b/src/main/java/com/fasterxml/jackson/core/base/ParserMinimalBase.java index e6d7b2f28d..73f8b371b2 100644 --- a/src/main/java/com/fasterxml/jackson/core/base/ParserMinimalBase.java +++ b/src/main/java/com/fasterxml/jackson/core/base/ParserMinimalBase.java @@ -30,6 +30,7 @@ public abstract class ParserMinimalBase extends JsonParser protected final static int INT_LF = '\n'; protected final static int INT_CR = '\r'; protected final static int INT_SPACE = 0x0020; + protected final static int INT_RS = 0x001E; // Markup protected final static int INT_LBRACKET = '['; diff --git a/src/main/java/com/fasterxml/jackson/core/json/JsonReadFeature.java b/src/main/java/com/fasterxml/jackson/core/json/JsonReadFeature.java index aa2a7d7073..d04a75010c 100644 --- a/src/main/java/com/fasterxml/jackson/core/json/JsonReadFeature.java +++ b/src/main/java/com/fasterxml/jackson/core/json/JsonReadFeature.java @@ -11,6 +11,22 @@ public enum JsonReadFeature implements FormatFeature { + // // // Support for non-standard data format constructs: whitespaces + + /** + * Feature that determines whether parser will allow use + * of the RS control character ({@code 0x1E}) within ignorable + * whitespace portion of input content (similar to TAB which + * is an allowed control character). + *

+ * Since JSON specification only allows a small set of control characters + * as whitespace by default, + * this is a non-standard feature, and as such disabled by default. + * + * @since 2.17 + */ + ALLOW_RS_CONTROL_CHAR(false, JsonParser.Feature.ALLOW_RS_CONTROL_CHAR), + // // // Support for non-standard data format constructs: comments /** diff --git a/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java b/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java index 1876b9e1d4..017e191e76 100644 --- a/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java +++ b/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java @@ -2505,7 +2505,8 @@ private final int _skipWSOrEnd() throws IOException _currInputRowStart = _inputPtr; } else if (i == INT_CR) { _skipCR(); - } else if (i != INT_TAB) { + } else if (i != INT_TAB + && ((_features & FEAT_MASK_ALLOW_RS_CTRL_CHAR) == 0 || i != INT_RS)) { _throwInvalidSpace(i); } } @@ -2525,7 +2526,7 @@ private final int _skipWSOrEnd() throws IOException _currInputRowStart = _inputPtr; } else if (i == INT_CR) { _skipCR(); - } else if (i != INT_TAB) { + } else if (i != INT_TAB && ((_features & FEAT_MASK_ALLOW_RS_CTRL_CHAR) != 0 && i != INT_RS)) { _throwInvalidSpace(i); } } diff --git a/src/test/java/com/fasterxml/jackson/core/json/async/AsyncNonStdParsingTest.java b/src/test/java/com/fasterxml/jackson/core/json/async/AsyncNonStdParsingTest.java index 3f2a0557b6..b8bd8c22ca 100644 --- a/src/test/java/com/fasterxml/jackson/core/json/async/AsyncNonStdParsingTest.java +++ b/src/test/java/com/fasterxml/jackson/core/json/async/AsyncNonStdParsingTest.java @@ -400,4 +400,5 @@ private AsyncReaderWrapper createParser(JsonFactory f, String doc, { return asyncForBytes(f, readSize, _jsonDoc(doc), offset); } + }