bounding brokenness

The sheer pain of platform-specific code

So I submitted a patch to bug 436880, with some innocuous-looking tests. There were a couple of fixes needed to make the test work (and in general), but nothing major. All the tests passed on my Windows build like a charm. All was well, until Standard8 tried out the test on his Mac and found that it failed with:
###!!! ASSERTION: You can't dereference a NULL nsCOMPtr with operator->()
Yes, a null pointer. After some initial shots in the dark (Time gaps before the next test? Line endings?), it was time for some debugging. It later turned out that when an instruction was given for multiple messages to be moved or copied, only the first one was actually being copied. As any further messages were not copied at all, we got a null pointer when we tried to retrieve them. It was utterly surprising for me to see
  1. such a problem being platform dependent.
  2. such a basic operation having trouble – except for the fact that this only happened in tests. (Don’t worry Mac Thunderbird users – your messages are safe ;) )
  3. the problem happening only when multiple messages were moved or copied in one go.
I filed bug 439925 regarding this. One major problem was that I don’t have a Mac to test on – so all I could do was ask Mac users to run different tests with debugging information. (Thank you once again, Jeff and Standard8, for your valuable time.) Finally, this Monday, David Bienvenu had some time to debug this on his Mac. He found that while copying messages from data files into a mail folder, the “folder” of the message object wasn’t being set properly on OS X. (It was, on Windows). When multiple copies were done, we were sending the first message’s source folder ourselves, but subsequent copies were using the “folder” set in the message object. Now, why exactly wasn’t the folder being set properly? David explains it best. Lesson: Bad things can happen with non-normalized paths. (Non-normalized paths are paths that are something like foo/bar/baz/../../quux. Ideally, this path should have simply been foo/quux. Most of the time, both are equivalent. When they are not, as in this case on OS X, bad things happen.) The fix was simple, just one line long. All’s (finally) well again with the world. It isn’t. Again, this happens on OS X but not on Windows. Bah. Seems like I’ll go through this all over again. :(