CodeSOD: Living Fossil

Checking browser compatibility is less of a thing these days than it once was. In an ideal world, we check for the specific features we want to use, and fallback to a different approach, or fail gracefully if they don't exist. We use shims and polyfills and pile on all sorts of logic to navigate this mess.

What we hopefully don't do is use user-agent sniffing. The user-agent string is, honestly, one of the kludgiest, messiest, and just generally offensive ways to divine browser behavior. It was, however, once the standard, and thus there is still plenty of code, usually older code, which does use user-agent sniffing.

Which brings us to this code, from Megan. It comes from the admin application for a major logistics company for a European nation. This logistics company handles 90% of deliveries for books within that nation's borders, and is notorious for its buggy software, its habit of just dropping orders with no explanation, and generally being an unstable mess where you may have to try six times before your order goes through.

function init() { printed = "no"; if (window.print) { nCanPrint = "yes"; } else { nCanPrint = "no"; } var agt=navigator.userAgent.toLowerCase() nVersion = parseInt(navigator.appVersion); nIE = (agt.indexOf("msie") != -1); nWin = ( (agt.indexOf("win")!=-1) || (agt.indexOf("16bit")!=-1) ); nMac = (agt.indexOf("mac") != -1); nIE4Win = (nIE && (nVersion == 4) && nWin); doPrint(); }

Now, this code doesn't start with user-agent sniffing, and instead checks to see if window.print, the method which pops up a print dialog exists. Now, for as far back as CanIUse's data reaches, every browser supports window.print with the notable exception of Firefox for Android. So, if they are targeting the 0.28% of the global browser market running that, then I guess they need to do this check.

But they probably don't need to store the results as strings inside of a global variable.

But it's what we sniff for in the user-agent that is the real icing on this cake. They sniff for IE4, which last saw a release in 1999. They also consider the machine a nWin machine if the user-agent contains "win" or contains "16bit", which implies that they're checking for a 16-bit CPU, aka a 286, for some real legacy compatibility.

This code is the JavaScript equivalent of a coelacanth: something we thought we only knew from fossils, but still lives on, to this day, in the deep waters of a logistics company moving books.

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

This post originally appeared on The Daily WTF.

Leave a Reply

Your email address will not be published. Required fields are marked *