<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Wed Feb 07 21:39:12 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[CSHARP-1296] StackOverflowException when serializing a class C that implements IEnumerable&lt;C&gt;</title>
                <link>https://jira.mongodb.org/browse/CSHARP-1296</link>
                <project id="10041" key="CSHARP">C# Driver</project>
                    <description>&lt;p&gt;If the object that is being inserted has a dynamic type with a JObject type in it (this is the default type used by JSON.NET for deserialize the JSON), then the InsertOneAsync method throws the StackOverflowException.&lt;/p&gt;

&lt;p&gt;It would be OK if driver does not support JObject and throws an appropriate exception, but since the StackOverflowException crashes the application and is very hard to debug, at very least the driver should not cause this type of exception.&lt;/p&gt;

&lt;p&gt;This is the code to replicate it:&lt;/p&gt;

&lt;p&gt;async Task Main()&lt;br/&gt;
{&lt;br/&gt;
    string msg = @&quot;&lt;/p&gt;
{ &quot;&quot;PayrollId&quot;&quot;:463236,&quot;&quot;Message&quot;&quot;:&quot;&quot;Fine&quot;&quot;,&quot;&quot;Success&quot;&quot;:true,&quot;&quot;MessageCode&quot;&quot;:200,&quot;&quot;IsError&quot;&quot;:false }
&lt;p&gt;&quot;;&lt;br/&gt;
    dynamic details = Newtonsoft.Json.JsonConvert.DeserializeObject(msg);&lt;/p&gt;

&lt;p&gt;    var data = new DomainEventData()&lt;br/&gt;
    &lt;/p&gt;
{
        AggregateId = Guid.NewGuid(),
        TenantId = Guid.NewGuid(),
        AggregateName = &quot;Just a test&quot;,
        EventName = &quot;payrollunit-schedule-missed&quot;,
        Details = details
    }
&lt;p&gt;;&lt;/p&gt;

&lt;p&gt;	MongoClient client = new MongoClient(&quot;mongodb://localhost/tests&quot;);&lt;br/&gt;
	IMongoDatabase mongo = client.GetDatabase(&quot;tests&quot;);&lt;br/&gt;
	IMongoCollection&amp;lt;DomainEventData&amp;gt; items = mongo.GetCollection&amp;lt;DomainEventData&amp;gt;(&quot;entries&quot;);&lt;/p&gt;

&lt;p&gt;    await items.InsertOneAsync(data);&lt;br/&gt;
}&lt;/p&gt;

&lt;p&gt;// Define other methods and classes here&lt;br/&gt;
    &lt;span class=&quot;error&quot;&gt;&amp;#91;Serializable&amp;#93;&lt;/span&gt;&lt;br/&gt;
    public class DomainEventData&lt;br/&gt;
    {&lt;br/&gt;
        public Guid Id &lt;/p&gt;
{ get; set; }&lt;br/&gt;
        &lt;span class=&quot;error&quot;&gt;&amp;#91;BsonElement(&amp;quot;eventName&amp;quot;)&amp;#93;&lt;/span&gt;&lt;br/&gt;
        public string EventName { get; set; }
&lt;p&gt;        &lt;span class=&quot;error&quot;&gt;&amp;#91;BsonElement(&amp;quot;tenantId&amp;quot;)&amp;#93;&lt;/span&gt;&lt;br/&gt;
        public Guid TenantId &lt;/p&gt;
{ get; set; }&lt;br/&gt;
        &lt;span class=&quot;error&quot;&gt;&amp;#91;BsonElement(&amp;quot;aggregateId&amp;quot;)&amp;#93;&lt;/span&gt;&lt;br/&gt;
        public Guid AggregateId { get; set; }
&lt;p&gt;        &lt;span class=&quot;error&quot;&gt;&amp;#91;BsonElement(&amp;quot;aggregateName&amp;quot;)&amp;#93;&lt;/span&gt;&lt;br/&gt;
        public string AggregateName &lt;/p&gt;
{ get; set; }&lt;br/&gt;
        &lt;span class=&quot;error&quot;&gt;&amp;#91;BsonElement(&amp;quot;details&amp;quot;)&amp;#93;&lt;/span&gt;&lt;br/&gt;
        public dynamic Details { get; set; }
&lt;p&gt;        &lt;span class=&quot;error&quot;&gt;&amp;#91;BsonElement(&amp;quot;utcTimestamp&amp;quot;)&amp;#93;&lt;/span&gt;&lt;br/&gt;
        &lt;span class=&quot;error&quot;&gt;&amp;#91;BsonDateTimeOptions(Kind = DateTimeKind.Utc)&amp;#93;&lt;/span&gt;&lt;br/&gt;
        public DateTime UtcTimestamp &lt;/p&gt;
{ get; set; }

&lt;p&gt;        public DomainEventData()&lt;/p&gt;
        {
            this.Id = Guid.NewGuid();
            this.TenantId = Guid.Empty;
            this.AggregateId = Guid.Empty;
            this.EventName = string.Empty;
            this.UtcTimestamp = DateTime.UtcNow;
            this.AggregateName = string.Empty;
        }
&lt;p&gt;    }&lt;/p&gt;

&lt;p&gt;BTW, changing the:&lt;br/&gt;
dynamic details = Newtonsoft.Json.JsonConvert.DeserializeObject(msg);&lt;br/&gt;
to:&lt;br/&gt;
dynamic details = Newtonsoft.Json.JsonConvert.DeserializeObject&amp;lt;ExpandoObject&amp;gt;(msg);&lt;br/&gt;
solves the issue, but if application is dealing with unknown data coming in, this might not be an option.&lt;/p&gt;</description>
                <environment></environment>
        <key id="206181">CSHARP-1296</key>
            <summary>StackOverflowException when serializing a class C that implements IEnumerable&lt;C&gt;</summary>
                <type id="1" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14703&amp;avatarType=issuetype">Bug</type>
                                            <priority id="4" iconUrl="https://jira.mongodb.org/images/icons/priorities/minor.svg">Minor - P4</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="9">Done</resolution>
                                        <assignee username="robert@mongodb.com">Robert Stam</assignee>
                                    <reporter username="lennygran">Lenny Granovsky</reporter>
                        <labels>
                    </labels>
                <created>Sat, 23 May 2015 13:59:05 +0000</created>
                <updated>Wed, 13 Apr 2016 21:04:20 +0000</updated>
                            <resolved>Tue, 26 May 2015 19:15:42 +0000</resolved>
                                                    <fixVersion>2.1</fixVersion>
                                    <component>Serialization</component>
                                        <votes>0</votes>
                                    <watches>2</watches>
                                                                                                                <comments>
                            <comment id="923796" author="xgen-internal-githook" created="Tue, 26 May 2015 19:11:30 +0000"  >&lt;p&gt;Author:&lt;/p&gt;
{u&apos;username&apos;: u&apos;rstam&apos;, u&apos;name&apos;: u&apos;rstam&apos;, u&apos;email&apos;: u&apos;robert@robertstam.org&apos;}
&lt;p&gt;Message: &lt;a href=&quot;https://jira.mongodb.org/browse/CSHARP-1296&quot; title=&quot;StackOverflowException when serializing a class C that implements IEnumerable&amp;lt;C&amp;gt;&quot; class=&quot;issue-link&quot; data-issue-key=&quot;CSHARP-1296&quot;&gt;&lt;del&gt;CSHARP-1296&lt;/del&gt;&lt;/a&gt;: Delay more serializer lookups to avoid stack overflows.&lt;br/&gt;
Branch: master&lt;br/&gt;
&lt;a href=&quot;https://github.com/mongodb/mongo-csharp-driver/commit/c6ebb182517e128d1bd37da8a6970f3c7d4f6168&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo-csharp-driver/commit/c6ebb182517e128d1bd37da8a6970f3c7d4f6168&lt;/a&gt;&lt;/p&gt;</comment>
                            <comment id="923257" author="xgen-internal-githook" created="Tue, 26 May 2015 13:47:18 +0000"  >&lt;p&gt;Author:&lt;/p&gt;
{u&apos;username&apos;: u&apos;rstam&apos;, u&apos;name&apos;: u&apos;rstam&apos;, u&apos;email&apos;: u&apos;robert@robertstam.org&apos;}
&lt;p&gt;Message: &lt;a href=&quot;https://jira.mongodb.org/browse/CSHARP-1296&quot; title=&quot;StackOverflowException when serializing a class C that implements IEnumerable&amp;lt;C&amp;gt;&quot; class=&quot;issue-link&quot; data-issue-key=&quot;CSHARP-1296&quot;&gt;&lt;del&gt;CSHARP-1296&lt;/del&gt;&lt;/a&gt;: Add delayed lookup of child serializers to prevent stack overflows when there are cyclic types.&lt;br/&gt;
Branch: master&lt;br/&gt;
&lt;a href=&quot;https://github.com/mongodb/mongo-csharp-driver/commit/51587ec74f50e80578d4575735a4f2f3e73f76f0&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo-csharp-driver/commit/51587ec74f50e80578d4575735a4f2f3e73f76f0&lt;/a&gt;&lt;/p&gt;</comment>
                            <comment id="922355" author="lennygran" created="Sat, 23 May 2015 17:03:29 +0000"  >&lt;p&gt;Thank you for the explanation. It is good to know the actual reason. I don&apos;t see any problem with not supporting JObject by default. The only issue is the StackOverflow by itself. Maybe going into limited number of loops and throwing an exception upon that limit has more advantage. Based on documentation, the MongoDB document supports up to 100 nested levels, therefore it seems like a natural limit to stop and throw an exception after 100 recursive iterations.&lt;/p&gt;

&lt;p&gt;I&apos;m sure you&apos;ll find the best option, I appreciate fixing the bug itself.&lt;/p&gt;</comment>
                            <comment id="922350" author="rstam" created="Sat, 23 May 2015 16:49:17 +0000"  >&lt;p&gt;The problematic type for us is JToken, which is declared as:&lt;/p&gt;

&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;public abstract class JToken : IEnumerable&amp;lt;JToken&amp;gt;, ...&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;

&lt;p&gt;The problem can be reproduced with any type that implements IEnumerable of itself:&lt;/p&gt;

&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;public class C: IEnumerable&amp;lt;C&amp;gt;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;

&lt;p&gt;In the process of constructing a serializer for C we recursively create a serializer for the IEnumerable&apos;s items. But when the items are of the same type we get stuck in an infinite recursion loop.&lt;/p&gt;</comment>
                            <comment id="922338" author="craiggwilson" created="Sat, 23 May 2015 15:29:23 +0000"  >&lt;p&gt;Thanks Lenny. Yes, a stackoverflow is not good. We&apos;ll figure it out. However, we can&apos;t support just any dynamic type because we don&apos;t know that the callsite will be in C#. However, a serializer can be registered for JObject. As part of &lt;a href=&quot;https://jira.mongodb.org/browse/CSHARP-1281&quot; title=&quot;Integrate with Json.NET&quot; class=&quot;issue-link&quot; data-issue-key=&quot;CSHARP-1281&quot;&gt;&lt;del&gt;CSHARP-1281&lt;/del&gt;&lt;/a&gt;, we&apos;ll be including a Json.NET serializer to handle this.&lt;/p&gt;

&lt;p&gt;For this ticket, I&apos;ll make sure we fix the stackoverflow problem. Thanks for the report,&lt;br/&gt;
Craig&lt;/p&gt;</comment>
                            <comment id="922333" author="lennygran" created="Sat, 23 May 2015 14:27:02 +0000"  >&lt;p&gt;The file with code attached&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10011">
                    <name>Depends</name>
                                                                <inwardlinks description="is depended on by">
                                                        </inwardlinks>
                                    </issuelinktype>
                            <issuelinktype id="10012">
                    <name>Related</name>
                                                                <inwardlinks description="is related to">
                                        <issuelink>
            <issuekey id="226718">CSHARP-1385</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="204373">CSHARP-1281</issuekey>
        </issuelink>
                            </inwardlinks>
                                    </issuelinktype>
                    </issuelinks>
                <attachments>
                            <attachment id="75489" name="JObject_bug.linq" size="2525" author="lennygran" created="Sat, 23 May 2015 14:27:02 +0000"/>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hs9mzr:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                    <customfield id="customfield_10557" key="com.pyxis.greenhopper.jira:gh-sprint">
                        <customfieldname>Sprint</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue id="549">C# Sprint 20</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>