Skip to content

Commit 2acc209

Browse files
Merge pull request #1215 from microsoft/mk/fix-cloning-stackoverflow-exception
Track cloned objects to avoid StackOverflowExceptions during cloning
2 parents 020790d + 178bb46 commit 2acc209

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<Company>Microsoft</Company>
1111
<Title>Microsoft.OpenApi.Readers</Title>
1212
<PackageId>Microsoft.OpenApi.Readers</PackageId>
13-
<Version>1.6.4-preview2</Version>
13+
<Version>1.6.4-preview3</Version>
1414
<Description>OpenAPI.NET Readers for JSON and YAML documents</Description>
1515
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
1616
<PackageTags>OpenAPI .NET</PackageTags>

src/Microsoft.OpenApi/Helpers/DictionaryCloneHelper.cs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Microsoft.OpenApi.Helpers
99
/// <summary>
1010
/// Helper class for deep cloning dictionaries.
1111
/// </summary>
12-
internal class DictionaryCloneHelper
12+
internal static class DictionaryCloneHelper
1313
{
1414
/// <summary>
1515
/// Deep clone key value pairs in a dictionary.
@@ -21,14 +21,26 @@ internal class DictionaryCloneHelper
2121
internal static Dictionary<T, U> Clone<T, U>(IDictionary<T, U> dictionary)
2222
{
2323
if (dictionary is null) return null;
24+
2425
var clonedDictionary = new Dictionary<T, U>(dictionary.Keys.Count);
26+
var clonedObjects = new Dictionary<object, object>();
2527

26-
foreach (var kvp in dictionary)
28+
foreach (var keyValuePair in dictionary)
2729
{
28-
// Create instance of the specified type using the constructor matching the specified parameter types.
29-
clonedDictionary[kvp.Key] = (U)Activator.CreateInstance(kvp.Value.GetType(), kvp.Value);
30-
}
31-
30+
// If the object has already been cloned, use the cloned object instead of cloning it again
31+
if (clonedObjects.TryGetValue(keyValuePair.Value, out var clonedValue))
32+
{
33+
clonedDictionary[keyValuePair.Key] = (U)clonedValue;
34+
}
35+
else
36+
{
37+
// Create instance of the specified type using the constructor matching the specified parameter types.
38+
clonedDictionary[keyValuePair.Key] = (U)Activator.CreateInstance(keyValuePair.Value.GetType(), keyValuePair.Value);
39+
40+
// Add the cloned object to the dictionary of cloned objects
41+
clonedObjects.Add(keyValuePair.Value, clonedDictionary[keyValuePair.Key]);
42+
}
43+
}
3244

3345
return clonedDictionary;
3446
}

src/Microsoft.OpenApi/Microsoft.OpenApi.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<Company>Microsoft</Company>
1212
<Title>Microsoft.OpenApi</Title>
1313
<PackageId>Microsoft.OpenApi</PackageId>
14-
<Version>1.6.4-preview2</Version>
14+
<Version>1.6.4-preview3</Version>
1515
<Description>.NET models with JSON and YAML writers for OpenAPI specification</Description>
1616
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
1717
<PackageTags>OpenAPI .NET</PackageTags>

0 commit comments

Comments
 (0)