Running with Code

Like scissors, only more dangerous

  Home  |   Contact  |   Syndication    |   Login
  67 Posts | 0 Stories | 84 Comments | 22 Trackbacks

News



Archives

Post Categories

All Terralever

ASP.NET

Misc

Tonight I was made aware of a bug in a library that I wrote that implements the cryptographic authentication sequences used by Blizzard Entertainment's Battle.net gaming service.  The user reported that his code simply stopped executing; it never occurred to me that he might just be swallowing an exception (particularly if his code was running on a secondary thread).  But when I reviewed my code, I saw that all of my loops were deterministic, and although I had a couple lock { } blocks throughout the code path, none of them were in places that I would be blocking.

Frustrated, I pulled out the code and wrote a test project using his input data to call the function.  I generated a NullReferenceException when I called the function he labeled suspect, so then I integrated the actual project into my solution.  I found the source of the problem immediately: it was a third-party BigInteger class I'd gotten from CodeProject.  This wasn't a *major* surprise - I'd had a few issues with this BigInteger class on another project that dealt with cryptographic calculations.  The big one was where the error was being raised:

   1:        public static bool operator ==(BigInteger bi1, BigInteger bi2)
   2:        {
   3:           return bi1.Equals(bi2);
   4:        }

So at this point I'm somewhat puzzled, except when I check the values of bi1 and bi2 in the debugger: they're both null!  I step back one level in the call stack and find:

   1:           if (verifier == null)
   2:              CalculateVerifier(salt);

At this point I'm not entirely sure what I can do.  If I modify the operator == to check bi1 and bi2 as == null, won't it result in a circular loop?  Then it occurs to me that I should modify the calling code:

 

   1:           if (object.ReferenceEquals(verifier, null))
   2:              CalculateVerifier(salt);

System.Object.ReferenceEquals(objA, objB) returns true if the object references are identical, or if both object references are null.

This is a good lesson to me: don't overload operator == on reference types. 

posted on Thursday, May 03, 2007 3:04 AM

Feedback

# re: Beware overloaded operator == 5/4/2007 11:59 AM James Curran
You're very close -- now, just put the pieces together.

The if (object.ReferenceEquals call should be the first step in the operator==


public static bool operator ==(BigInteger bi1, BigInteger bi2)
{
if (object.ReferenceEquals(bi1, b2))
return true;

if (object.ReferenceEquals(bi1, null))
return false;

return bi1.Equals(bi2);
}

(That's is essentially what System.String does in it's oper==.)


# re: Beware overloaded operator == 5/18/2007 12:27 PM Eber Irigoyen
this is weird, I added your blog to my google reader, and this particular post did not make it

Post Feedback

Title:
Name:
Email: (never displayed)
Url:
Comments: 
Please add 8 and 1 and type the answer here: