Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-2187

CombinedProjectionDefinition.Render() method throws StackOverflowException

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: 2.4.4, 2.5
    • Component/s: Builders
    • Labels:
    • Fully Compatible

      CombinedProjectionDefinition.Render() method throws StackOverflowException when including a huge number of fields.

      Here is a unit test reproducing the error:

      Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      [Fact]
      public void Include_Many_Fields()
      {
          var subject = CreateSubject<Person>();
       
          var projection = subject.Include(x => x.FirstName);
          var expectedProjection = new StringBuilder("{fn: 1");
          for (int i = 0; i < 10000; i++)
          {
              var field = $"Field{i}";
              projection = projection.Include(field);
              expectedProjection.Append($", {field}: 1");
          }
          expectedProjection.Append("}");
       
          Assert(projection, expectedProjection.ToString());
      }
      

      To fix the isuue I changed the constructor of the CombinedProjectionDefinition class to "unwind" the _projections collection to avoid recursively calling the Render() method:

      Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      public CombinedProjectionDefinition(IEnumerable<ProjectionDefinition<TSource>> projections)
      {
          _projections = Ensure.IsNotNull(projections, nameof(projections))
              .SelectMany(projection => (projection as CombinedProjectionDefinition<TSource>)?._projections ?? new List<ProjectionDefinition<TSource>> { projection })
              .ToList();
      }
      

      Let me know if you need more information to fix the issue or if you want me to also create a pull request.

            Assignee:
            Unassigned Unassigned
            Reporter:
            davidst David Stanescu
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: