ReadOnlySpan<byte> localBuffer = _buffer.Slice(_consumed + 1);
int leftOver = 2;
- SequencePosition start = new SequencePosition(_currentPosition.GetObject(), _currentPosition.GetInteger() + _consumed);
if (localBuffer.Length == 0)
{
if (IsLastSpan)
{
- ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedStartOfValueNotFound, JsonConstants.Slash);
+ ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.UnexpectedEndOfDataWhileReadingComment);
}
if (!GetNextSpan())
{
if (IsLastSpan)
{
- ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedStartOfValueNotFound, JsonConstants.Slash);
+ ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.UnexpectedEndOfDataWhileReadingComment);
}
return false;
}
}
byte marker = localBuffer[0];
-
- if (marker == JsonConstants.Slash)
+ if (marker != JsonConstants.Slash && marker != JsonConstants.Asterisk)
{
- return ConsumeSingleLineCommentMultiSegment(localBuffer.Slice(1), leftOver, start, _consumed);
+ ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.InvalidCharacterAtStartOfComment, marker);
}
- if (marker != JsonConstants.Asterisk)
+ localBuffer = localBuffer.Slice(1);
+ if (localBuffer.Length == 0)
{
- ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedStartOfValueNotFound, marker);
+ if (IsLastSpan)
+ {
+ ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.UnexpectedEndOfDataWhileReadingComment);
+ }
+ if (!GetNextSpan())
+ {
+ if (IsLastSpan)
+ {
+ ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.UnexpectedEndOfDataWhileReadingComment);
+ }
+ return false;
+ }
+ _totalConsumed++;
+ _bytePositionInLine++;
+ localBuffer = _buffer;
+ leftOver = 0;
}
- return ConsumeMultiLineCommentMultiSegment(localBuffer.Slice(1), leftOver, start, _consumed);
+ SequencePosition start = new SequencePosition(_currentPosition.GetObject(), _currentPosition.GetInteger() + _consumed + leftOver);
+ if (marker == JsonConstants.Slash)
+ {
+ return ConsumeSingleLineCommentMultiSegment(localBuffer, leftOver, start, _consumed);
+ }
+ return ConsumeMultiLineCommentMultiSegment(localBuffer, leftOver, start, _consumed);
}
private bool ConsumeSingleLineCommentMultiSegment(ReadOnlySpan<byte> localBuffer, int leftOver, SequencePosition start, int previousConsumed)
{
+ SequencePosition end = start;
+
long prevTotalConsumed = _totalConsumed;
int idx = -1;
bool expectLF = false;
+ int toConsume = idx;
do
{
if (expectLF)
idx = localBuffer.IndexOfAny(JsonConstants.LineFeed, JsonConstants.CarriageReturn);
if (idx != -1)
{
+ toConsume = idx;
+ end = new SequencePosition(_currentPosition.GetObject(), _currentPosition.GetInteger() + previousConsumed + leftOver + idx);
if (localBuffer[idx] == JsonConstants.LineFeed)
{
break;
}
expectLF = true;
}
+ else
+ {
+ end = new SequencePosition(_currentPosition.GetObject(), _currentPosition.GetInteger() + previousConsumed + leftOver + localBuffer.Length);
+ }
if (IsLastSpan)
{
idx = localBuffer.Length;
+ toConsume = idx;
// Assume everything on this line is a comment and there is no more data.
_bytePositionInLine += 2 + localBuffer.Length;
goto Done;
}
HasValueSequence = true;
_totalConsumed += localBuffer.Length + leftOver;
+ previousConsumed = 0;
leftOver = 0;
localBuffer = _buffer;
idx = -1;
Done:
if (HasValueSequence)
{
- SequencePosition end = new SequencePosition(_currentPosition.GetObject(), _currentPosition.GetInteger() + idx);
ReadOnlySequence<byte> commentSequence = _sequence.Slice(start, end);
if (commentSequence.IsSingleSegment)
{
}
else
{
- ValueSpan = _buffer.Slice(previousConsumed, idx + 2); // Include the double slash and potential line feed at the end of the comment as part of it.
+ // Exclude start-of-comment chars //, if not already skipped and
+ // take characters until the first line separator character
+ ValueSpan = _buffer.Slice(previousConsumed + leftOver, toConsume);
}
if (_tokenType != JsonTokenType.Comment)
private bool ConsumeMultiLineCommentMultiSegment(ReadOnlySpan<byte> localBuffer, int leftOver, SequencePosition start, int previousConsumed)
{
+ SequencePosition end = start;
long prevTotalConsumed = _totalConsumed;
int i;
int lastLineFeedIndex;
if (nextByte == JsonConstants.Asterisk)
{
+ end = new SequencePosition(_currentPosition.GetObject(), _currentPosition.GetInteger() + previousConsumed + leftOver + i);
i++;
lastAsterisk = true;
if (i < localBuffer.Length)
}
lastLineFeedIndex = -1;
leftOver = 0;
+ previousConsumed = 0;
localBuffer = _buffer;
i = 0;
if (localBuffer[i] == JsonConstants.Slash)
}
HasValueSequence = true;
_totalConsumed += localBuffer.Length + leftOver;
+
if (lastLineFeedIndex == -1)
{
_bytePositionInLine += localBuffer.Length + leftOver;
}
lastLineFeedIndex = -1;
leftOver = 0;
+ previousConsumed = 0;
localBuffer = _buffer;
}
}
Done:
if (HasValueSequence)
{
- // Include the final slash at the end of the comment as part of it.
- SequencePosition end = new SequencePosition(_currentPosition.GetObject(), _currentPosition.GetInteger() + i + 1);
ReadOnlySequence<byte> commentSequence = _sequence.Slice(start, end);
if (commentSequence.IsSingleSegment)
{
}
else
{
- ValueSpan = _buffer.Slice(previousConsumed, i + 3); // Include the slash/asterisk and final slash at the end of the comment as part of it.
+ // Exclude the start-of-comment characters /*, if not already skipped
+ // and end-of-comment characters */
+ ValueSpan = _buffer.Slice(previousConsumed + leftOver, i - 1);
}
if (_tokenType != JsonTokenType.Comment)
[Theory]
[InlineData("[123, 456]", "123456", "123456")]
- [InlineData("/*a*/[{\"testA\":[{\"testB\":[{\"testC\":123}]}]}]", "testAtestBtestC123", "/*a*/testAtestBtestC123")]
- [InlineData("{\"testA\":[1/*hi*//*bye*/, 2, 3], \"testB\": 4}", "testA123testB4", "testA1/*hi*//*bye*/23testB4")]
+ [InlineData("/*a*/[{\"testA\":[{\"testB\":[{\"testC\":123}]}]}]", "testAtestBtestC123", "atestAtestBtestC123")]
+ [InlineData("{\"testA\":[1/*hi*//*bye*/, 2, 3], \"testB\": 4}", "testA123testB4", "testA1hibye23testB4")]
[InlineData("{\"test\":[[[123,456]]]}", "test123456", "test123456")]
- [InlineData("/*a*//*z*/[/*b*//*z*/123/*c*//*z*/,/*d*//*z*/456/*e*//*z*/]/*f*//*z*/", "123456", "/*a*//*z*//*b*//*z*/123/*c*//*z*//*d*//*z*/456/*e*//*z*//*f*//*z*/")]
- [InlineData("[123,/*hi*/456/*bye*/]", "123456", "123/*hi*/456/*bye*/")]
- [InlineData("[123,//hi\n456//bye\n]", "123456", "123//hi\n456//bye\n")]
- [InlineData("[123,//hi\r456//bye\r]", "123456", "123//hi\r456//bye\r")]
- [InlineData("[123,//hi\r\n456]", "123456", "123//hi\r\n456")]
+ [InlineData("/*a*//*z*/[/*b*//*z*/123/*c*//*z*/,/*d*//*z*/456/*e*//*z*/]/*f*//*z*/", "123456", "azbz123czdz456ezfz")]
+ [InlineData("[123,/*hi*/456/*bye*/]", "123456", "123hi456bye")]
+ [InlineData("[123,//hi\n456//bye\n]", "123456", "123hi456bye")]
+ [InlineData("[123,//hi\r456//bye\r]", "123456", "123hi456bye")]
+ [InlineData("[123,//hi\r\n456]", "123456", "123hi456")]
[InlineData("/*a*//*z*/{/*b*//*z*/\"test\":/*c*//*z*/[/*d*//*z*/[/*e*//*z*/[/*f*//*z*/123/*g*//*z*/,/*h*//*z*/456/*i*//*z*/]/*j*//*z*/]/*k*//*z*/]/*l*//*z*/}/*m*//*z*/",
- "test123456", "/*a*//*z*//*b*//*z*/test/*c*//*z*//*d*//*z*//*e*//*z*//*f*//*z*/123/*g*//*z*//*h*//*z*/456/*i*//*z*//*j*//*z*//*k*//*z*//*l*//*z*//*m*//*z*/")]
+ "test123456", "azbztestczdzezfz123gzhz456izjzkzlzmz")]
[InlineData("//a\n//z\n{//b\n//z\n\"test\"://c\n//z\n[//d\n//z\n[//e\n//z\n[//f\n//z\n123//g\n//z\n,//h\n//z\n456//i\n//z\n]//j\n//z\n]//k\n//z\n]//l\n//z\n}//m\n//z\n",
- "test123456", "//a\n//z\n//b\n//z\ntest//c\n//z\n//d\n//z\n//e\n//z\n//f\n//z\n123//g\n//z\n//h\n//z\n456//i\n//z\n//j\n//z\n//k\n//z\n//l\n//z\n//m\n//z\n")]
+ "test123456", "azbztestczdzezfz123gzhz456izjzkzlzmz")]
public static void AllowCommentStackMismatchMultiSegment(string jsonString, string expectedWithoutComments, string expectedWithComments)
{
byte[] data = Encoding.UTF8.GetBytes(jsonString);
sequence = JsonTestHelper.GetSequence(data, 1);
TestReadingJsonWithComments(data, sequence, expectedWithoutComments, expectedWithComments);
+ sequence = JsonTestHelper.GetSequence(data, 6);
+ TestReadingJsonWithComments(data, sequence, expectedWithoutComments, expectedWithComments);
+
var firstSegment = new BufferSegment<byte>(ReadOnlyMemory<byte>.Empty);
ReadOnlyMemory<byte> secondMem = data;
BufferSegment<byte> secondSegment = firstSegment.Append(secondMem);
}
}
+ // For first line in each case:
+ // . represents contiguous characters in input.
+ // | represents end of a segment in the sequence. Character below | is last character of particular segment.
+ //
+ // Note: \ for escape sequence has neither a . nor a |
+ //
+ // Second line in each case represents whether the resulting token after parsing has a value sequence or not.
+ // T(rue) indicates presence of value sequence and F(alse) indicates otherwise. T or F is written above first
+ // character of partiular token.
+ // - indicates that token that begins at character right below it has been skipped during parsing and hence there
+ // is no truth value representation of the same in the expectedValueSequence* in each case.
[Theory]
+ // . .........|.... .... ........ ... ........|............... ...............|......................|||
+ // F T F F T F T F F F FF
[InlineData(0, "{\"property name\": [\"value 1\", \"value 2 across sequence\", 12345, 1234567890, true, false, null]}")]
+
+ // .. .............. .... ........ ... .......|................ .....|.................|......|......|..||
+ // FF F F F T T F T T T FFF
[InlineData(1, "[{\"property name\": [\"value 1\", \"value 2 across sequence\", 12345, 1234567890, true, false, null]}]")]
+
+ // . .............. .................... | . ...........|............ ..................|...... . |..
+ // Skip: F F F- T - FF
+ // Allow: F F FF T T FF
[InlineData(2, "{\"property name\": [// comment value\r\n\"value 2 across sequence\"// another comment value\r\n]}")]
public static void CheckOnlyOneOfValueSpanOrSequenceIsSet(int testCase, string jsonString)
{
buffers[4] = dataUtf8.AsSpan(88, 2).ToArray();
sequence = BufferFactory.Create(buffers);
expectedHasValueSequenceSkip = new bool[] { false, false, false, true, false, false };
- expectedHasValueSequenceAllow = new bool[] { false, false, false, true, true, true, false, false };
+ expectedHasValueSequenceAllow = new bool[] { false, false, false, false, true, true, false, false };
break;
default:
return;
}
[Theory]
- [MemberData(nameof(SingleLineCommentData))]
- public static void ConsumeSingleLineCommentMultiSpanTest(string expected)
+ [MemberData(nameof(CommentTestLineSeparators))]
+ public static void ConsumeSingleLineCommentMultiSpanTest(string lineSeparator)
{
- string jsonData = "{" + expected + "}";
+ string expected = "Comment";
+ string jsonData = "{//" + expected + lineSeparator + "}";
byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonData);
ReadOnlySequence<byte> sequence = JsonTestHelper.GetSequence(dataUtf8, 1);
}
[Theory]
- [MemberData(nameof(SingleLineCommentData))]
- public static void SkipSingleLineCommentMultiSpanTest(string expected)
+ [MemberData(nameof(CommentTestLineSeparators))]
+ public static void SkipSingleLineCommentMultiSpanTest(string lineSeparator)
{
- string jsonData = "{" + expected + "}";
+ string expected = "Comment";
+ string jsonData = "{//" + expected + lineSeparator + "}";
byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonData);
ReadOnlySequence<byte> sequence = JsonTestHelper.GetSequence(dataUtf8, 1);
[Theory]
[InlineData("[123, 456]", "123456", "123456")]
- [InlineData("/*a*/[{\"testA\":[{\"testB\":[{\"testC\":123}]}]}]", "testAtestBtestC123", "/*a*/testAtestBtestC123")]
- [InlineData("{\"testA\":[1/*hi*//*bye*/, 2, 3], \"testB\": 4}", "testA123testB4", "testA1/*hi*//*bye*/23testB4")]
+ [InlineData("/*a*/[{\"testA\":[{\"testB\":[{\"testC\":123}]}]}]", "testAtestBtestC123", "atestAtestBtestC123")]
+ [InlineData("{\"testA\":[1/*hi*//*bye*/, 2, 3], \"testB\": 4}", "testA123testB4", "testA1hibye23testB4")]
[InlineData("{\"test\":[[[123,456]]]}", "test123456", "test123456")]
- [InlineData("/*a*//*z*/[/*b*//*z*/123/*c*//*z*/,/*d*//*z*/456/*e*//*z*/]/*f*//*z*/", "123456", "/*a*//*z*//*b*//*z*/123/*c*//*z*//*d*//*z*/456/*e*//*z*//*f*//*z*/")]
- [InlineData("[123,/*hi*/456/*bye*/]", "123456", "123/*hi*/456/*bye*/")]
- [InlineData("[123,//hi\n456//bye\n]", "123456", "123//hi\n456//bye\n")]
- [InlineData("[123,//hi\r456//bye\r]", "123456", "123//hi\r456//bye\r")]
- [InlineData("[123,//hi\r\n456\r\n]", "123456", "123//hi\r\n456")]
+ [InlineData("/*a*//*z*/[/*b*//*z*/123/*c*//*z*/,/*d*//*z*/456/*e*//*z*/]/*f*//*z*/", "123456", "azbz123czdz456ezfz")]
+ [InlineData("[123,/*hi*/456/*bye*/]", "123456", "123hi456bye")]
+ [InlineData("[123,//hi\n456//bye\n]", "123456", "123hi456bye")]
+ [InlineData("[123,//hi\r456//bye\r]", "123456", "123hi456bye")]
+ [InlineData("[123,//hi\r\n456\r\n]", "123456", "123hi456")]
[InlineData("/*a*//*z*/{/*b*//*z*/\"test\":/*c*//*z*/[/*d*//*z*/[/*e*//*z*/[/*f*//*z*/123/*g*//*z*/,/*h*//*z*/456/*i*//*z*/]/*j*//*z*/]/*k*//*z*/]/*l*//*z*/}/*m*//*z*/",
- "test123456", "/*a*//*z*//*b*//*z*/test/*c*//*z*//*d*//*z*//*e*//*z*//*f*//*z*/123/*g*//*z*//*h*//*z*/456/*i*//*z*//*j*//*z*//*k*//*z*//*l*//*z*//*m*//*z*/")]
+ "test123456", "azbztestczdzezfz123gzhz456izjzkzlzmz")]
[InlineData("//a\n//z\n{//b\n//z\n\"test\"://c\n//z\n[//d\n//z\n[//e\n//z\n[//f\n//z\n123//g\n//z\n,//h\n//z\n456//i\n//z\n]//j\n//z\n]//k\n//z\n]//l\n//z\n}//m\n//z\n",
- "test123456", "//a\n//z\n//b\n//z\ntest//c\n//z\n//d\n//z\n//e\n//z\n//f\n//z\n123//g\n//z\n//h\n//z\n456//i\n//z\n//j\n//z\n//k\n//z\n//l\n//z\n//m\n//z\n")]
+ "test123456", "azbztestczdzezfz123gzhz456izjzkzlzmz")]
public static void AllowCommentStackMismatch(string jsonString, string expectedWithoutComments, string expectedWithComments)
{
byte[] data = Encoding.UTF8.GetBytes(jsonString);
}
[Theory]
- [InlineData("//", "//", 2)]
- [InlineData("//\n", "//\n", 3)]
- [InlineData("/**/", "/**/", 4)]
- [InlineData("/*/*/", "/*/*/", 5)]
-
- [InlineData("//T\u6F22\u5B57his is a \u6F22\u5B57comment before json\n\"hello\"", "//T\u6F22\u5B57his is a \u6F22\u5B57comment before json\n", 44)]
- [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json", "//This is a \u6F22\u5B57comment after json", 49)]
- [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json\n", "//This is a \u6F22\u5B57comment after json\n", 50)]
- [InlineData("\"a\u6F22\u5B57lpha\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment/*and a multi-line comment*///Another single-line comment", "//This is a \u6F22\u5B57comment after json\n", 53)]
- [InlineData("\"b\u6F22\u5B57eta\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "//This is a \u6F22\u5B57comment after json\n", 52)]
- [InlineData("\"g\u6F22\u5B57amma\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment\n/*and a multi-line comment*///Another single-line comment", "//This is a \u6F22\u5B57comment after json\n", 53)]
- [InlineData("\"d\u6F22\u5B57elta\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "//This is a \u6F22\u5B57comment after json\n", 53)]
- [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json with new line\n", "//This is a \u6F22\u5B57comment after json with new line\n", 64)]
- [InlineData("{\"a\u6F22\u5B57ge\" : \n//This is a \u6F22\u5B57comment between key-value pairs\n 30}", "//This is a \u6F22\u5B57comment between key-value pairs\n", 66)]
- [InlineData("{\"a\u6F22\u5B57ge\" : 30//This is a \u6F22\u5B57comment between key-value pairs on the same line\n}", "//This is a \u6F22\u5B57comment between key-value pairs on the same line\n", 84)]
-
- [InlineData("/*T\u6F22\u5B57his is a multi-line \u6F22\u5B57comment before json*/\"hello\"", "/*T\u6F22\u5B57his is a multi-line \u6F22\u5B57comment before json*/", 56)]
- [InlineData("\"h\u6F22\u5B57ello\"/*This is a multi-line \u6F22\u5B57comment after json*/", "/*This is a multi-line \u6F22\u5B57comment after json*/", 62)]
- [InlineData("\"a\u6F22\u5B57lpha\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment", "/*This is a multi-line \u6F22\u5B57comment after json*/", 65)]
- [InlineData("\"b\u6F22\u5B57eta\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "/*This is a multi-line \u6F22\u5B57comment after json*/", 64)]
- [InlineData("\"g\u6F22\u5B57amma\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment", "/*This is a multi-line \u6F22\u5B57comment after json*/", 65)]
- [InlineData("\"d\u6F22\u5B57elta\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "/*This is a multi-line \u6F22\u5B57comment after json*/", 65)]
- [InlineData("{\"a\u6F22\u5B57ge\" : \n/*This is a \u6F22\u5B57comment between key-value pairs*/ 30}", "/*This is a \u6F22\u5B57comment between key-value pairs*/", 67)]
- [InlineData("{\"a\u6F22\u5B57ge\" : 30/*This is a \u6F22\u5B57comment between key-value pairs on the same line*/}", "/*This is a \u6F22\u5B57comment between key-value pairs on the same line*/", 85)]
-
- [InlineData("/*T\u6F22\u5B57his is a split multi-line \n\u6F22\u5B57comment before json*/\"hello\"", "/*T\u6F22\u5B57his is a split multi-line \n\u6F22\u5B57comment before json*/", 63)]
- [InlineData("\"h\u6F22\u5B57ello\"/*This is a split multi-line \n\u6F22\u5B57comment after json*/", "/*This is a split multi-line \n\u6F22\u5B57comment after json*/", 69)]
- [InlineData("\"a\u6F22\u5B57lpha\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment", "/*This is a split multi-line \n\u6F22\u5B57comment after json*/", 72)]
- [InlineData("\"b\u6F22\u5B57eta\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "/*This is a split multi-line \n\u6F22\u5B57comment after json*/", 71)]
- [InlineData("\"g\u6F22\u5B57amma\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment", "/*This is a split multi-line \n\u6F22\u5B57comment after json*/", 72)]
- [InlineData("\"d\u6F22\u5B57elta\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "/*This is a split multi-line \n\u6F22\u5B57comment after json*/", 72)]
- [InlineData("{\"a\u6F22\u5B57ge\" : \n/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs*/ 30}", "/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs*/", 85)]
- [InlineData("{\"a\u6F22\u5B57ge\" : 30/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs on the same line*/}", "/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs on the same line*/", 103)]
+ [InlineData("//", "", 2)]
+ [InlineData("//\n", "", 3)]
+ [InlineData("/**/", "", 4)]
+ [InlineData("/*/*/", "/", 5)]
+
+ [InlineData("//T\u6F22\u5B57his is a \u6F22\u5B57comment before json\n\"hello\"", "T\u6F22\u5B57his is a \u6F22\u5B57comment before json", 44)]
+ [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json", "This is a \u6F22\u5B57comment after json", 49)]
+ [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json\n", "This is a \u6F22\u5B57comment after json", 50)]
+ [InlineData("\"a\u6F22\u5B57lpha\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment/*and a multi-line comment*///Another single-line comment", "This is a \u6F22\u5B57comment after json", 53)]
+ [InlineData("\"b\u6F22\u5B57eta\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a \u6F22\u5B57comment after json", 52)]
+ [InlineData("\"g\u6F22\u5B57amma\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment\n/*and a multi-line comment*///Another single-line comment", "This is a \u6F22\u5B57comment after json", 53)]
+ [InlineData("\"d\u6F22\u5B57elta\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a \u6F22\u5B57comment after json", 53)]
+ [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json with new line\n", "This is a \u6F22\u5B57comment after json with new line", 64)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : \n//This is a \u6F22\u5B57comment between key-value pairs\n 30}", "This is a \u6F22\u5B57comment between key-value pairs", 66)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : 30//This is a \u6F22\u5B57comment between key-value pairs on the same line\n}", "This is a \u6F22\u5B57comment between key-value pairs on the same line", 84)]
+
+ [InlineData("/*T\u6F22\u5B57his is a multi-line \u6F22\u5B57comment before json*/\"hello\"", "T\u6F22\u5B57his is a multi-line \u6F22\u5B57comment before json", 56)]
+ [InlineData("\"h\u6F22\u5B57ello\"/*This is a multi-line \u6F22\u5B57comment after json*/", "This is a multi-line \u6F22\u5B57comment after json", 62)]
+ [InlineData("\"a\u6F22\u5B57lpha\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment", "This is a multi-line \u6F22\u5B57comment after json", 65)]
+ [InlineData("\"b\u6F22\u5B57eta\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a multi-line \u6F22\u5B57comment after json", 64)]
+ [InlineData("\"g\u6F22\u5B57amma\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment", "This is a multi-line \u6F22\u5B57comment after json", 65)]
+ [InlineData("\"d\u6F22\u5B57elta\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a multi-line \u6F22\u5B57comment after json", 65)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : \n/*This is a \u6F22\u5B57comment between key-value pairs*/ 30}", "This is a \u6F22\u5B57comment between key-value pairs", 67)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : 30/*This is a \u6F22\u5B57comment between key-value pairs on the same line*/}", "This is a \u6F22\u5B57comment between key-value pairs on the same line", 85)]
+
+ [InlineData("/*T\u6F22\u5B57his is a split multi-line \n\u6F22\u5B57comment before json*/\"hello\"", "T\u6F22\u5B57his is a split multi-line \n\u6F22\u5B57comment before json", 63)]
+ [InlineData("\"h\u6F22\u5B57ello\"/*This is a split multi-line \n\u6F22\u5B57comment after json*/", "This is a split multi-line \n\u6F22\u5B57comment after json", 69)]
+ [InlineData("\"a\u6F22\u5B57lpha\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment", "This is a split multi-line \n\u6F22\u5B57comment after json", 72)]
+ [InlineData("\"b\u6F22\u5B57eta\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a split multi-line \n\u6F22\u5B57comment after json", 71)]
+ [InlineData("\"g\u6F22\u5B57amma\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment", "This is a split multi-line \n\u6F22\u5B57comment after json", 72)]
+ [InlineData("\"d\u6F22\u5B57elta\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a split multi-line \n\u6F22\u5B57comment after json", 72)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : \n/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs*/ 30}", "This is a split multi-line \n\u6F22\u5B57comment between key-value pairs", 85)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : 30/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs on the same line*/}", "This is a split multi-line \n\u6F22\u5B57comment between key-value pairs on the same line", 103)]
public static void Allow(string jsonString, string expectedComment, int expectedIndex)
{
byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonString);
}
[Theory]
- [InlineData("//", "//", 2)]
- [InlineData("//\n", "//\n", 3)]
- [InlineData("/**/", "/**/", 4)]
- [InlineData("/*/*/", "/*/*/", 5)]
-
- [InlineData("//T\u6F22\u5B57his is a \u6F22\u5B57comment before json\n\"hello\"", "//T\u6F22\u5B57his is a \u6F22\u5B57comment before json\n", 44)]
- [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json", "//This is a \u6F22\u5B57comment after json", 49)]
- [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json\n", "//This is a \u6F22\u5B57comment after json\n", 50)]
- [InlineData("\"a\u6F22\u5B57lpha\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment/*and a multi-line comment*///Another single-line comment", "//This is a \u6F22\u5B57comment after json\n", 53)]
- [InlineData("\"b\u6F22\u5B57eta\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "//This is a \u6F22\u5B57comment after json\n", 52)]
- [InlineData("\"g\u6F22\u5B57amma\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment\n/*and a multi-line comment*///Another single-line comment", "//This is a \u6F22\u5B57comment after json\n", 53)]
- [InlineData("\"d\u6F22\u5B57elta\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "//This is a \u6F22\u5B57comment after json\n", 53)]
- [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json with new line\n", "//This is a \u6F22\u5B57comment after json with new line\n", 64)]
- [InlineData("{\"a\u6F22\u5B57ge\" : \n//This is a \u6F22\u5B57comment between key-value pairs\n 30}", "//This is a \u6F22\u5B57comment between key-value pairs\n", 66)]
- [InlineData("{\"a\u6F22\u5B57ge\" : 30//This is a \u6F22\u5B57comment between key-value pairs on the same line\n}", "//This is a \u6F22\u5B57comment between key-value pairs on the same line\n", 84)]
- [InlineData("\"a\u6F22\u5B57lpha\" \r\n//This is a comment with a carriage return\r//Another single-line comment", "//This is a comment with a carriage return\r", 59)]
- [InlineData("\"a\u6F22\u5B57lpha\" \r\n//This is a comment with a line break\n//Another single-line comment", "//This is a comment with a line break\n", 54)]
- [InlineData("\"a\u6F22\u5B57lpha\" \r\n//This is a comment with a carriage return and line break\r\n//Another single-line comment", "//This is a comment with a carriage return and line break\r\n", 75)]
-
- [InlineData("/*T\u6F22\u5B57his is a multi-line \u6F22\u5B57comment before json*/\"hello\"", "/*T\u6F22\u5B57his is a multi-line \u6F22\u5B57comment before json*/", 56)]
- [InlineData("\"h\u6F22\u5B57ello\"/*This is a multi-line \u6F22\u5B57comment after json*/", "/*This is a multi-line \u6F22\u5B57comment after json*/", 62)]
- [InlineData("\"a\u6F22\u5B57lpha\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment", "/*This is a multi-line \u6F22\u5B57comment after json*/", 65)]
- [InlineData("\"b\u6F22\u5B57eta\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "/*This is a multi-line \u6F22\u5B57comment after json*/", 64)]
- [InlineData("\"g\u6F22\u5B57amma\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment", "/*This is a multi-line \u6F22\u5B57comment after json*/", 65)]
- [InlineData("\"d\u6F22\u5B57elta\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "/*This is a multi-line \u6F22\u5B57comment after json*/", 65)]
- [InlineData("{\"a\u6F22\u5B57ge\" : \n/*This is a \u6F22\u5B57comment between key-value pairs*/ 30}", "/*This is a \u6F22\u5B57comment between key-value pairs*/", 67)]
- [InlineData("{\"a\u6F22\u5B57ge\" : 30/*This is a \u6F22\u5B57comment between key-value pairs on the same line*/}", "/*This is a \u6F22\u5B57comment between key-value pairs on the same line*/", 85)]
-
- [InlineData("/*T\u6F22\u5B57his is a split multi-line \n\u6F22\u5B57comment before json*/\"hello\"", "/*T\u6F22\u5B57his is a split multi-line \n\u6F22\u5B57comment before json*/", 63)]
- [InlineData("\"h\u6F22\u5B57ello\"/*This is a split multi-line \n\u6F22\u5B57comment after json*/", "/*This is a split multi-line \n\u6F22\u5B57comment after json*/", 69)]
- [InlineData("\"a\u6F22\u5B57lpha\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment", "/*This is a split multi-line \n\u6F22\u5B57comment after json*/", 72)]
- [InlineData("\"b\u6F22\u5B57eta\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "/*This is a split multi-line \n\u6F22\u5B57comment after json*/", 71)]
- [InlineData("\"g\u6F22\u5B57amma\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment", "/*This is a split multi-line \n\u6F22\u5B57comment after json*/", 72)]
- [InlineData("\"d\u6F22\u5B57elta\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "/*This is a split multi-line \n\u6F22\u5B57comment after json*/", 72)]
- [InlineData("{\"a\u6F22\u5B57ge\" : \n/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs*/ 30}", "/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs*/", 85)]
- [InlineData("{\"a\u6F22\u5B57ge\" : 30/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs on the same line*/}", "/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs on the same line*/", 103)]
-
- [InlineData("{\r\n \"value\": 11,\r\n /* yes, it's mis-spelled */\r\n \"deelay\": 3\r\n}", "/* yes, it's mis-spelled */", 50)]
+ [InlineData("//", "", 2)]
+ [InlineData("//\n", "", 3)]
+ [InlineData("/**/", "", 4)]
+ [InlineData("/*/*/", "/", 5)]
+
+ [InlineData("//T\u6F22\u5B57his is a \u6F22\u5B57comment before json\n\"hello\"", "T\u6F22\u5B57his is a \u6F22\u5B57comment before json", 44)]
+ [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json", "This is a \u6F22\u5B57comment after json", 49)]
+ [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json\n", "This is a \u6F22\u5B57comment after json", 50)]
+ [InlineData("\"a\u6F22\u5B57lpha\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment/*and a multi-line comment*///Another single-line comment", "This is a \u6F22\u5B57comment after json", 53)]
+ [InlineData("\"b\u6F22\u5B57eta\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a \u6F22\u5B57comment after json", 52)]
+ [InlineData("\"g\u6F22\u5B57amma\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment\n/*and a multi-line comment*///Another single-line comment", "This is a \u6F22\u5B57comment after json", 53)]
+ [InlineData("\"d\u6F22\u5B57elta\" \r\n//This is a \u6F22\u5B57comment after json\n//Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a \u6F22\u5B57comment after json", 53)]
+ [InlineData("\"h\u6F22\u5B57ello\"//This is a \u6F22\u5B57comment after json with new line\n", "This is a \u6F22\u5B57comment after json with new line", 64)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : \n//This is a \u6F22\u5B57comment between key-value pairs\n 30}", "This is a \u6F22\u5B57comment between key-value pairs", 66)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : 30//This is a \u6F22\u5B57comment between key-value pairs on the same line\n}", "This is a \u6F22\u5B57comment between key-value pairs on the same line", 84)]
+ [InlineData("\"a\u6F22\u5B57lpha\" \r\n//This is a comment with a carriage return\r//Another single-line comment", "This is a comment with a carriage return", 59)]
+ [InlineData("\"a\u6F22\u5B57lpha\" \r\n//This is a comment with a line break\n//Another single-line comment", "This is a comment with a line break", 54)]
+ [InlineData("\"a\u6F22\u5B57lpha\" \r\n//This is a comment with a carriage return and line break\r\n//Another single-line comment", "This is a comment with a carriage return and line break", 75)]
+
+ [InlineData("/*T\u6F22\u5B57his is a multi-line \u6F22\u5B57comment before json*/\"hello\"", "T\u6F22\u5B57his is a multi-line \u6F22\u5B57comment before json", 56)]
+ [InlineData("\"h\u6F22\u5B57ello\"/*This is a multi-line \u6F22\u5B57comment after json*/", "This is a multi-line \u6F22\u5B57comment after json", 62)]
+ [InlineData("\"a\u6F22\u5B57lpha\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment", "This is a multi-line \u6F22\u5B57comment after json", 65)]
+ [InlineData("\"b\u6F22\u5B57eta\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a multi-line \u6F22\u5B57comment after json", 64)]
+ [InlineData("\"g\u6F22\u5B57amma\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment", "This is a multi-line \u6F22\u5B57comment after json", 65)]
+ [InlineData("\"d\u6F22\u5B57elta\" \r\n/*This is a multi-line \u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a multi-line \u6F22\u5B57comment after json", 65)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : \n/*This is a \u6F22\u5B57comment between key-value pairs*/ 30}", "This is a \u6F22\u5B57comment between key-value pairs", 67)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : 30/*This is a \u6F22\u5B57comment between key-value pairs on the same line*/}", "This is a \u6F22\u5B57comment between key-value pairs on the same line", 85)]
+
+ [InlineData("/*T\u6F22\u5B57his is a split multi-line \n\u6F22\u5B57comment before json*/\"hello\"", "T\u6F22\u5B57his is a split multi-line \n\u6F22\u5B57comment before json", 63)]
+ [InlineData("\"h\u6F22\u5B57ello\"/*This is a split multi-line \n\u6F22\u5B57comment after json*/", "This is a split multi-line \n\u6F22\u5B57comment after json", 69)]
+ [InlineData("\"a\u6F22\u5B57lpha\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment", "This is a split multi-line \n\u6F22\u5B57comment after json", 72)]
+ [InlineData("\"b\u6F22\u5B57eta\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a split multi-line \n\u6F22\u5B57comment after json", 71)]
+ [InlineData("\"g\u6F22\u5B57amma\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment", "This is a split multi-line \n\u6F22\u5B57comment after json", 72)]
+ [InlineData("\"d\u6F22\u5B57elta\" \r\n/*This is a split multi-line \n\u6F22\u5B57comment after json*///Here is another comment\n/*and a multi-line comment*///Another single-line comment\n\t /*blah * blah*/", "This is a split multi-line \n\u6F22\u5B57comment after json", 72)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : \n/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs*/ 30}", "This is a split multi-line \n\u6F22\u5B57comment between key-value pairs", 85)]
+ [InlineData("{\"a\u6F22\u5B57ge\" : 30/*This is a split multi-line \n\u6F22\u5B57comment between key-value pairs on the same line*/}", "This is a split multi-line \n\u6F22\u5B57comment between key-value pairs on the same line", 103)]
+
+ [InlineData("{\r\n \"value\": 11,\r\n /* yes, it's mis-spelled */\r\n \"deelay\": 3\r\n}", " yes, it's mis-spelled ", 50)]
[InlineData("[\r\n 12,\r\n 87,\r\n /* Isn't it \"nice\" that JSON provides no limits on the length of numbers? */\r\n 123456789012345678901234567890123456789.01234567890123456789e+9876543218976543219876543210\r\n]",
- "/* Isn't it \"nice\" that JSON provides no limits on the length of numbers? */", 98)]
+ " Isn't it \"nice\" that JSON provides no limits on the length of numbers? ", 98)]
public static void AllowSingleSegment(string jsonString, string expectedComment, int expectedIndex)
{
byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonString);
}
[Theory]
- [MemberData(nameof(SingleLineCommentData))]
- public static void ConsumeSingleLineCommentSingleSpanTest(string expected)
+ [MemberData(nameof(CommentTestLineSeparators))]
+ public static void ConsumeSingleLineCommentSingleSpanTest(string lineSeparator)
{
- var jsonData = "{" + expected + "}";
+ var expected = "Comment";
+ var jsonData = "{//" + expected + lineSeparator + "}";
byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonData);
for (int i = 0; i < jsonData.Length; i++)
}
[Theory]
- [MemberData(nameof(SingleLineCommentData))]
- public static void SkipSingleLineCommentSingleSpanTest(string expected)
+ [MemberData(nameof(CommentTestLineSeparators))]
+ public static void SkipSingleLineCommentSingleSpanTest(string lineSeparator)
{
- var jsonData = "{" + expected + "}";
+ var expected = "Comment";
+ var jsonData = "{//" + expected + lineSeparator + "}";
byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonData);
for (int i = 0; i < jsonData.Length; i++)
}
}
- public static IEnumerable<object[]> SingleLineCommentData
+ public static IEnumerable<object[]> CommentTestLineSeparators
{
get
{
return new List<object[]>
{
- // \r as the line separator
- new object [] {"//Comment\r" },
- new object [] {"//Comment\r" },
- new object [] {"//Comment\r" },
-
- // \r\n as line separator
- new object [] {"//Comment\r\n" },
- new object [] {"//Comment\r\n" },
- new object [] {"//Comment\r\n" },
- new object [] {"//Comment\r\n" },
-
- // \n as line separator
- new object [] {"//Comment\n" },
- new object [] {"//Comment\n" },
- new object [] {"//Comment\n" }
+ new object [] {"\r" },
+ new object [] {"\r\n" },
+ new object [] {"\n" },
};
}
}