Skip to content

Commit 54fdcf7

Browse files
authored
CSHARP-5493: Fix stackoverflow in EnumRepresentationConvention (#1616)
1 parent bfc43d6 commit 54fdcf7

File tree

4 files changed

+41
-0
lines changed

4 files changed

+41
-0
lines changed

Diff for: src/MongoDB.Bson/Serialization/Conventions/EnumRepresentationConvention.cs

+8
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
using System;
17+
using System.Collections;
1718

1819
namespace MongoDB.Bson.Serialization.Conventions
1920
{
@@ -67,6 +68,13 @@ public EnumRepresentationConvention(BsonType representation, bool topLevelOnly)
6768
/// <param name="memberMap">The member map.</param>
6869
public void Apply(BsonMemberMap memberMap)
6970
{
71+
var memberType = memberMap.MemberType;
72+
73+
if (!(memberType.IsEnum || memberType.IsNullableEnum() || memberType.IsArray || typeof(IEnumerable).IsAssignableFrom(memberType)))
74+
{
75+
return;
76+
}
77+
7078
var serializer = memberMap.GetSerializer();
7179
var reconfiguredSerializer = _topLevelOnly && !serializer.ValueType.IsNullableEnum() ?
7280
Reconfigure(serializer) :

Diff for: src/MongoDB.Bson/Serialization/Conventions/ObjectSerializerAllowedTypesConvention.cs

+9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
using System;
17+
using System.Collections;
1718
using System.Collections.Generic;
1819
using System.Linq;
1920
using System.Reflection;
@@ -152,6 +153,14 @@ public bool AllowDefaultFrameworkTypes
152153
/// <param name="memberMap">The member map.</param>
153154
public void Apply(BsonMemberMap memberMap)
154155
{
156+
var memberType = memberMap.MemberType;
157+
158+
if (memberType != typeof(object) && Nullable.GetUnderlyingType(memberType) == null && !memberType.IsArray &&
159+
!typeof(IEnumerable).IsAssignableFrom(memberType))
160+
{
161+
return;
162+
}
163+
155164
var serializer = memberMap.GetSerializer();
156165

157166
var reconfiguredSerializer = Reconfigure(serializer);

Diff for: tests/MongoDB.Bson.Tests/Serialization/Conventions/EnumRepresentationConventionTests.cs

+12
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class C
4141
public int I { get; set; }
4242
public int NI { get; set; }
4343
public int[] ArrayInt { get; set; }
44+
public C RecursiveProp { get; set; }
4445
}
4546

4647
[Theory]
@@ -204,6 +205,17 @@ public void Apply_should_do_nothing_when_member_is_not_an_enum_collection()
204205
memberMap.GetSerializer().Should().BeSameAs(serializer);
205206
}
206207

208+
[Fact]
209+
public void Convention_should_work_with_recursive_type()
210+
{
211+
var pack = new ConventionPack { new EnumRepresentationConvention(BsonType.String) };
212+
ConventionRegistry.Register("enumRecursive", pack, t => t == typeof(C));
213+
214+
_ = new BsonClassMap<C>(cm => cm.AutoMap()).Freeze();
215+
216+
ConventionRegistry.Remove("enumRecursive");
217+
}
218+
207219
[Theory]
208220
[InlineData((BsonType)0)]
209221
[InlineData(BsonType.Int32)]

Diff for: tests/MongoDB.Bson.Tests/Serialization/Conventions/ObjectSerializerAllowedTypesConventionTests.cs

+12
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ private class TestClass
3131
public object ObjectProp { get; set; }
3232
public object[] ArrayOfObjectProp { get; set; }
3333
public object[][] ArrayOfArrayOfObjectProp { get; set; }
34+
public TestClass RecursiveProp { get; set; }
3435
}
3536

3637
[Fact]
@@ -344,6 +345,17 @@ public void Convention_should_be_applied_during_automapping()
344345
ConventionRegistry.Remove(conventionName);
345346
}
346347

348+
[Fact]
349+
public void Convention_should_work_with_recursive_type()
350+
{
351+
var pack = new ConventionPack { new ObjectSerializerAllowedTypesConvention() };
352+
ConventionRegistry.Register("objectRecursive", pack, t => t == typeof(TestClass));
353+
354+
_ = new BsonClassMap<TestClass>(cm => cm.AutoMap()).Freeze();
355+
356+
ConventionRegistry.Remove("enumRecursive");
357+
}
358+
347359
// private methods
348360
private static BsonMemberMap CreateMemberMap<TMember>(Expression<Func<TestClass, TMember>> member)
349361
{

0 commit comments

Comments
 (0)