[CSHARP-1170] When GetHashCode() is called from BsonElement with circular reference - overflow exception is thrown Created: 25/Jan/15  Updated: 30/Aug/16  Resolved: 30/Aug/16

Status: Closed
Project: C# Driver
Component/s: BSON
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor - P4
Reporter: Shay Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Please consider the following code:

var item1 = new BsonDocument();
var item2 = new BsonDocument();
item1.Add(new BsonElement("cycle_1", item2));
item2.Add(new BsonElement("cycle_2", item1));

Now, If I call item1.GetHashCode(), the application will terminate due to stack overflow exception (in my case I tried to add item1 to HashSet).
Sure an exception should be thrown, but stackoverflow exception terminates a .NET application. I looked in the source code, and saw that BsonDocument.GetHashCode also calls GetHashCode of inner elements, which in this case cause the infinite loop.
Is this considered a bug, or should the programmer know he should avoid such scenarios?



 Comments   
Comment by Robert Stam [ 30/Aug/16 ]

Checking for circular references would be expensive because we would have to track which nodes we have already visited.

If we do that with a bit we have to make sure to clear that bit after the hash code is computed, requiring a second pass over the object graph. Also, this would not be multi thread safe.

If we do that with a Dictionary we have the extra expense of looking up every node in the dictionary as we traverse the object graph.

Since we don't intend to support circular references in the first place it seems unnecessary to slow down normal operations just to detect circular references.

I'm closing this as won't fix.

Comment by Dana Groff [ 30/Aug/16 ]

rstamAny further comments or interest? Should we just close this as won't fix?

Comment by Shay [ 26/Jan/15 ]

Hi Robert,

Thank you for your answer.
Why would checking for circular reference would be so expensive? We could mark visited nodes, and throw an exception when we visit the same node twice. For that matter we could use pointers hash set.
I'm new here, so if I'm talking nonsense please be kind

Comment by Robert Stam [ 25/Jan/15 ]

The BsonDocument object model is not intended to be used with circular references, and they are not supported.

While getting a StackOverflowException when calling GetHashCode is unfortunate, it would be rather expensive to check for circular references every time GetHashCode is called, so we just assume that our users have not created circular references.

Technically this could be called a bug (because GetHashcode is never supposed to throw an exception), but given the obstacles in avoiding this StackOverflowException it is unlikely we will attempt to detect circular references to avoid this.

I'm going to leave the ticket open for further comments before a final decision is made.

Generated at Wed Feb 07 21:38:51 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.