Skip to content

Commit ff38ff4

Browse files
committed
Reject conditional after root object
1 parent ab0572d commit ff38ff4

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

ValveKeyValue/ValveKeyValue.Test/MultipleRootObjectsTestCase.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ public void StrayObjectEndInTextThrows()
5353
Assert.That(ex.Message, Does.Contain("Found data after the root object at line 4, column 1"));
5454
}
5555

56-
// A stray '}' used to end the read loop early, silently discarding everything after it.
5756
[Test]
5857
public void SecondRootObjectAfterStrayObjectEndInTextThrows()
5958
{
@@ -64,6 +63,18 @@ public void SecondRootObjectAfterStrayObjectEndInTextThrows()
6463
() => KVSerializer.Create(KVSerializationFormat.KeyValues1Text).Deserialize(stream));
6564
}
6665

66+
[TestCase("[$NEVERDEFINED]")]
67+
[TestCase("[!$NEVERDEFINED]")]
68+
public void TrailingConditionalAfterRootInTextThrows(string conditional)
69+
{
70+
var text = "\"a\"\n{\n\t\"k\" \"v\"\n}\n" + conditional + "\n";
71+
72+
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(text));
73+
var ex = Assert.Throws<KeyValueException>(
74+
() => KVSerializer.Create(KVSerializationFormat.KeyValues1Text).Deserialize(stream));
75+
Assert.That(ex.Message, Does.Contain("Found data after the root object at line 5, column 1"));
76+
}
77+
6778
[Test]
6879
public void SecondRootObjectInBinaryThrows()
6980
{

ValveKeyValue/ValveKeyValue/Deserialization/KeyValues1/KV1TextReader.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,13 @@ void HandleCondition(string text)
240240
throw tokenReader.MakeSyntaxException($"Found conditional while in state {stateMachine.Current} at {tokenReader.TokenStartPosition}.");
241241
}
242242

243+
// A conditional between a root object's name and its '{' is valid and applies to that
244+
// object, but after the root has closed it would otherwise discard the entire document.
245+
if (stateMachine.Current == KV1TextReaderState.InObjectAfterValue && stateMachine.IsAtDocumentLevel)
246+
{
247+
throw tokenReader.MakeSyntaxException($"Found data after the root object at {tokenReader.TokenStartPosition}, documents with multiple root objects are not supported.");
248+
}
249+
243250
bool matches;
244251

245252
try

0 commit comments

Comments
 (0)