a crazy bug

Yesterday I was working on a bug that was kind of interesting. Since my friend Tony was talking about writing an article for his blog, I thought I would write down what I've been doing here.

I was told about a bug in LibreJS – you couldn't load reddit.com when using the LibreJS add-on with GNU IceCat and Trisquel. Wow.... I need to fix this immediately.

The symptom of the problem was that the browser froze. Each voting arrow on reddit has an attribute that looks like this:

onclick="click_thing(this)"
Each of these scripts needs to be processed by LibreJS. The first time it's processed, it computes a hash of the script so the results can be saved for subsequent identical scripts.

Then I saw something suspicious in the debug log. I've linked to it here because there's a lot of text. Immediately at the top it says "too much recursion". If you scroll all the way to the right, you can see the call stack repeating itself many times, confirming the runtime's complaint.

I thought, "Great.. I've found the problem. I've seen this before it must be an infinite loop." I spent a few hours trying to fit the recursive loop into my head – what is it actually doing, and what special if statement should I enter to just break out of it, in this specific case? All these strange onclick scripts must be triggering an unhandled case in LibreJS.

But reddit was loading fine in Mac OS. That was an important point that I had forgotten about. Maybe "Too much recursion" just meant too much recursion for this specific system, and the loop wasn't actually infinite. After reading more about this JavaScript error, I found that using setTimeout can reset the call stack. I tried this out, and it worked.

And now you can read reddit.com when you're using LibreJS with GNU IceCat on Trisquel Linux.