diff --git a/YamlDotNet.Test/Serialization/SerializationTests.cs b/YamlDotNet.Test/Serialization/SerializationTests.cs index 5b78d43f9..2851dfa2d 100644 --- a/YamlDotNet.Test/Serialization/SerializationTests.cs +++ b/YamlDotNet.Test/Serialization/SerializationTests.cs @@ -243,19 +243,6 @@ public void DeserializeConvertible() result.aaa.Should().Be("[hello, world]"); } - [Fact] - public void DeserializationOfObjectsHandlesForwardReferences() - { - var text = Lines( - "Nothing: *forward", - "MyString: &forward ForwardReference"); - - var result = Deserializer.Deserialize(UsingReaderFor(text)); - - result.ShouldBeEquivalentTo( - new { Nothing = "ForwardReference", MyString = "ForwardReference" }, o => o.ExcludingMissingMembers()); - } - [Fact] public void DeserializationFailsForUndefinedForwardReferences() { @@ -521,30 +508,6 @@ public void DeserializeExplicitList() .Subject.As>().Should().Equal(3, 4, 5); } - [Fact] - public void DeserializationOfGenericListsHandlesForwardReferences() - { - var text = Lines( - "- *forward", - "- &forward ForwardReference"); - - var result = Deserializer.Deserialize(UsingReaderFor(text)); - - result.Should().Equal(new[] { "ForwardReference", "ForwardReference" }); - } - - [Fact] - public void DeserializationOfNonGenericListsHandlesForwardReferences() - { - var text = Lines( - "- *forward", - "- &forward ForwardReference"); - - var result = Deserializer.Deserialize(UsingReaderFor(text)); - - result.Should().Equal(new[] { "ForwardReference", "ForwardReference" }); - } - [Fact] public void RoundtripList() { @@ -622,47 +585,6 @@ public void RoundtripDictionary() result.Should().Equal(obj); } - [Fact] - public void DeserializationOfGenericDictionariesHandlesForwardReferences() - { - var text = Lines( - "key1: *forward", - "*forwardKey: ForwardKeyValue", - "*forward: *forward", - "key2: &forward ForwardReference", - "key3: &forwardKey key4"); - - var result = Deserializer.Deserialize>(UsingReaderFor(text)); - - result.Should().Equal(new Dictionary { - { "ForwardReference", "ForwardReference" }, - { "key1", "ForwardReference" }, - { "key2", "ForwardReference" }, - { "key4", "ForwardKeyValue" }, - { "key3", "key4" } - }); - } - - [Fact] - public void DeserializationOfNonGenericDictionariesHandlesForwardReferences() - { - var text = Lines( - "key1: *forward", - "*forwardKey: ForwardKeyValue", - "*forward: *forward", - "key2: &forward ForwardReference", - "key3: &forwardKey key4"); - - var result = Deserializer.Deserialize(UsingReaderFor(text)); - - result.Should().BeEquivalentTo( - Entry("ForwardReference", "ForwardReference"), - Entry("key1", "ForwardReference"), - Entry("key2", "ForwardReference"), - Entry("key4", "ForwardKeyValue"), - Entry("key3", "key4")); - } - [Fact] public void DeserializeListOfDictionaries() { @@ -1591,6 +1513,38 @@ public void DeserializationOfStreamWithDuplicateAnchorsSucceeds() Assert.NotNull(deserialized); } + private sealed class AnchorPrecedence + { + internal sealed class AnchorPrecedenceNested + { + public string b1 { get; set; } + public Dictionary b2 { get; set; } + } + + public string a { get; set; } + public AnchorPrecedenceNested b { get; set; } + public string c { get; set; } + } + + [Fact] + public void DeserializationWithDuplicateAnchorsSucceeds() + { + var sut = new Deserializer(); + var deserialized = sut.Deserialize(@" +a: &anchor1 test0 +b: + b1: &anchor1 test1 + b2: + b21: &anchor1 test2 +c: *anchor1"); + + Assert.Equal("test0", deserialized.a); + Assert.Equal("test1", deserialized.b.b1); + Assert.Contains("b21", deserialized.b.b2.Keys); + Assert.Equal("test2", deserialized.b.b2["b21"]); + Assert.Equal("test2", deserialized.c); + } + [Fact] public void SerializeExceptionWithStackTrace() { @@ -1818,6 +1772,18 @@ public void AnchorNameWithTrailingColonReferencedInKeyCanBeDeserialized() Assert.Equal(@"anchor "" value """, deserialized["myvalue"]); } + [Fact] + public void AliasBeforeAnchorCannotBeDeserialized() + { + var sut = new Deserializer(); + Action action = () => sut.Deserialize>(@" +a: *anchor1 +b: &anchor1 test0 +c: *anchor1"); + + action.ShouldThrow(); + } + [Fact] public void AnchorWithAllowedCharactersCanBeDeserialized() { diff --git a/YamlDotNet/Serialization/ValueDeserializers/AliasValueDeserializer.cs b/YamlDotNet/Serialization/ValueDeserializers/AliasValueDeserializer.cs index 5cdfab3af..07b619bd1 100644 --- a/YamlDotNet/Serialization/ValueDeserializers/AliasValueDeserializer.cs +++ b/YamlDotNet/Serialization/ValueDeserializers/AliasValueDeserializer.cs @@ -104,8 +104,7 @@ public ValuePromise(object? value) var aliasState = state.Get(); if (!aliasState.TryGetValue(alias.Value, out var valuePromise)) { - valuePromise = new ValuePromise(alias); - aliasState.Add(alias.Value, valuePromise); + throw new AnchorNotFoundException(alias.Start, alias.End, $"Alias ${alias.Value} cannot precede anchor declaration"); } return valuePromise.HasValue ? valuePromise.Value : valuePromise;