EnumRepresentationConvention.CouldApply causes StackOverflowException on self-referencing IEnumerable<T> types (e.g. JToken)

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Critical - P2
    • None
    • Affects Version/s: 3.8.0, 3.7.1, 3.8.1
    • Component/s: None
    • None
    • None
    • Dotnet Drivers
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      After upgrading from MongoDB.Driver 3.7.0 to 3.7.1+, applications that register an EnumRepresentationConvention and serialize types containing JToken (or any self-referencing IEnumerable<T>) crash with a StackOverflowException during convention application.

      Affects Version/s: 3.7.1, 3.8.0

      Component: BSON

      How to Reproduce

      1. Register a convention pack containing EnumRepresentationConvention:

      var conventionPack = new ConventionPack
      {
          new EnumRepresentationConvention(BsonType.String)
      };
      ConventionRegistry.Register("conventions", conventionPack, _ => true);
      
      

      2. Have a document class with a JObject or JToken property:

      public class MyDocument
      {
          public string Id { get; set; }
          public JObject Manifest { get; set; }
      }
      

      3. Perform any MongoDB operation that triggers class map auto-mapping for MyDocument.
      4. The process crashes with exit code 134 (SIGABRT) due to a StackOverflowException.

      Root Cause

      EnumRepresentationConvention.CouldApply (introduced by the fix for CSHARP-5905) recursively walks the generic arguments of IEnumerable<T> to check whether any nested type is an enum. JToken implements IEnumerable<JToken>, creating a cycle: JToken → IEnumerable<JToken> → JToken → … — infinite recursion with no visited-type guard.

      Stack trace (repeating segment):

      at MongoDB.Bson.Serialization.Conventions.EnumRepresentationConvention.CouldApply(System.Type)
      at MongoDB.Bson.Serialization.Conventions.EnumRepresentationConvention.CouldApply(System.Type)
      at MongoDB.Bson.Serialization.Conventions.EnumRepresentationConvention.CouldApply(System.Type)
      ...
      

      Expected Behavior

      CouldApply should track visited types (e.g. via a HashSet<Type>) to detect cycles and return false when encountering a previously seen type.

      Workaround

      Pin MongoDB.Driver to 3.7.0 and remove EnumRepresentationConvention from the convention pack, registering explicit EnumSerializer<T>(BsonType.String) for each enum type instead.

      Related Issues

      • CSHARP-5493 — Same StackOverflow bug in 3.2.0, fixed in 3.2.1 (the fix was reverted/regressed)
      • CSHARP-5905 — The fix that introduced CouldApply, which caused this regression
      • CSHARP-5508 — "Revisit Conventions.Apply" (BACKLOG)

            Assignee:
            Unassigned
            Reporter:
            William Tremblay
            None
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: