Recent Articles

Jan 2023

How To Ruin a Long Weekend

by in CodeSOD on

GRH inherited an application written by someone who is no longer employed with the company, as part of a project managed by someone who is no longer at the company, requested by an executive who is also no longer at the company. There are no documented requirements, very few tests, and a lot of "don't touch this, it works".

Well, it worked until it didn't. On a Friday before a long weekend, the application broke. As you might expect, it has a relatively small user pool, but is absolutely vital to the company's operations- if it fails, widgets don't get shipped and invoices don't get paid. So GRH got to spend that long weekend fixing the application.

Height of the Accordion

by in CodeSOD on

In the bad old days of web development, you had to deal with the fact that there weren't really any standards, and you had to customize your code for different browsers. The "right" way was to sniff for which features were available, but the most commonly used way was to check the user-agent string and guess based on the browser name. Because of this, browsers started to keyword spam their user-agent, to pass these checks, which is why my browser reports as Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Safari/537.36. My browser of choice is a Chrome fork, and I'm running on an M1 Mac, so basically none of those things are true.

But let's look back at some code Lucas found, still lingering in a web app he maintains.

Or Else

by in Error'd on

This week I read an article which asserted that the AI singularity is still several years away. Maybe they should wait until then before they start threatening us?

The first of the last of the humans, Greg took the time to wonder about the meaning of this warning. Or is it a threat? "One of our in-house web applications implements an automatic logout, but also lets you get a warning when you have a few minutes left before it does this. Their warning leaves me a bit puzzled, though, since it seems to imply that it's a manual session timeout, and perhaps if I don't close the session in 5 minutes, I'll stay logged in? Or will the world just end?" Run, Greg. Run.

Literal Type Checking

by in CodeSOD on

Validating your inputs is important, even when the sender is an API- in the land of JSON-based data exchange, we can't guarantee which keys exist without checking.

Philipp's team uses the "Runtypes" library to solve this problem. It lets them write code like this:

Magic Math

by in CodeSOD on

LK was browsing a local job site for a new position. The site was flaky, which lead LK to look into the code, and it looks like if anything, this job site should be hiring a new web developer.

function startSWBanner()
   browserType = "new";

   timenow = new Date();
   secs = timenow.getTime () / 1000;
   modnum = 2 * 10;
   range = secs % modnum;
   n = Math.floor(range / 10);
   urlArray = new Array(2);
   banArray = new Array(2);
   altArray = new Array(2);
   popupArray = new Array(2);
   urlArray[0] = '/cgi-bin/banner_track.cgi?banner_id=2627';
   banArray[0] = '/rot_ban/v2lbanner.gif';
   urlArray[1] = '/cgi-bin/banner_track.cgi?banner_id=4245';
   banArray[1] = '/rot_ban/ir35_banner.gif';

   if (browserType == "new")
        document.swbanner.src = banArray[n];

      startThread = setTimeout("rotateSWBanner()", 10000);

Multiline Properties

by in CodeSOD on

If you want to configure a Java application, the standard way to do it is to use the Java Properties class. This class wraps around a simple, text-based file format (or an XML file, if you're into that) that allows you to store key/value pairs. It helpfully inherits from the HashMap class, letting you interact with those key/value pairs using a well understood API. The file format handles all the details of encoding and managing things like multiline strings.

So you could just do that. Or, you could do what this senior dev with over a decade of experience did.

The 13 Month Bughunt

by in CodeSOD on

Code reviews are an important part of development processes, but sometimes, some developers manage to sneak around the process. That was the case with Orien's team, where most of the team were constantly checking in with each other, doing peer reviews, and trying to collaborate on a rather gigantic Perl codebase. One team member, on the other hand… didn't. Management wasn't interested in pushing the issue, so this developer got to do their own thing.

And then the developer left. Over the next thirteen months, bug after bug started cropping up. Minor changes that should have been easy would unleash a ball of spaghettified nonsense that was impossible to debug but also emphatically didn't work. Things got so bad that the entire team needed to stop doing any new development for three months, and just fix bugs and refactor.

Pure Poetry

by in Error'd on

Abandoning alliteration, the column this week is experimenting with consonance. Next week, perhaps we'll see how everyone feels about assonance.

Job-hunter Despreately Looking for Internship shared this job posting, writing "AMD Job Lsiting forgot to add in the deatils". Seems like a pretty easy job to perform; Mx. Des should apply.

Advanced Programming Resources

by in CodeSOD on

Denilson was doing some appliance shopping, and upon submitting a form, it errored out. Denilson was sure the form was correct, and did what any of us would do: pop open the developer console and check the code.

The console dumped out a huge number of errors. And to no one's shock, the code had all sorts of home-made validation methods, like validateNumber. And, much to my surprise, they found new ways to make the simple task of validating a number horrible.

Rounding Percentages

by in CodeSOD on

These days, every language in wide use has support for unicode characters, at least in strings. This is excellent, because it means we can program like the kids these days, with loads of emojis. I'm cool. This is what cool looks like: 😎.

You know what else is cool? National ID systems. One particular European country has rolled out a new software backend for their national ID system. Dimitry has the privilege to see the code. This is how they show the user how complete something is, as a percentage:

The Email Process

by in CodeSOD on

Today's submission comes from Florian, and it starts with "this app processes important business transaction by email", which is always a good way to start a WTF. I've seen a depressing number of applications in my life that use email as a means of data exchange. It's common enough that even the industry standard EDI protocol supports email as one of its transports, but hoo boy is that a terrible abuse of email systems.

Let's start in HtmlResponseParser.cs, which reads in HTML and "parses" it for certain structures so it can extract data.

No Percentage In It

by in CodeSOD on

James was asked to investigate some legacy code for the sole purpose of figuring out how to replace it. There were all sorts of bad blocks in there, but this one caught James's eye as being notable.

And it is. This code has a simple job: given an old value and a new value, tell us the difference as a percentage of the old value. You or I might write this as a one-liner, but this clever developer is on an entirely different level:

Speedy Delivery

by in Error'd on

Boxing Day was weeks ago, but the packages are still coming.

Before Enterprise, Captain John Archer had a brief career in body-snatching. Here we see him possessing the person of a housewife, delivering a succinct eulogy for a parrot named Earl. A surprised David K. exclaims "I didn't see this plot twist coming!"

Else To

by in CodeSOD on

David inherited a codebase that's a few decades old. As each developer has taken it over, they've done their best to follow the code standards that the previous developers used, to at least keep the codebase consistent. A few rebels may have gone a different route, like the right one, but too many just followed the patterns that were already there.

This means that there are a lot of variables named things like a and aa and aaa. There are 4,000 line functions and loads of copy/pasted code.

Catch By Yourself

by in CodeSOD on

We've all seen the empty catch block, the "swallow errors and ignore them". David sends us a "superior" example of that anti-pattern, with several bonuses to make it even more of a WTF.

 * Insert the method's description here.
 * @param bean java.lang.Object
 * @param bean_template java.lang.StringBuffer
 * @param bufXML java.lang.StringBuffer
protected static void appendBeanTemplate(Object bean, StringBuffer bufXML) {

      int                                            iEndTag;
     StringBuffer  xmlTemplate = new StringBuffer();
 try {
               iEndTag = bufXML.toString().lastIndexOf("</" + getClassName(bean) + ">");
           writeChildBeanDescription(bean, xmlTemplate);
         bufXML.insert(iEndTag, xmlTemplate.toString());     
      catch (Exception e) {
                try {
                      throw new Exception("Error creating xml bean description.");
               catch (Exception ex) {

String Formatting

by in CodeSOD on

There are certain things I can't remember for the life of me. For example, as per yesterday, the number of nanoseconds in a millisecond.

One of the other is the specific little formatting tokens for printf. I use it all the time, but the various riffs on %d escape my brain faster than I can put them in. Even just getting the hex values dumped for debugging requires a search. But I at least do that search, unlike Mike's co-worker.

Yesterday and Today

by in CodeSOD on

There's bad date handling, which frequently involves reinventing date handling yourself, frequently using strings or integers along the way. Then there's the bad date handling which uses the date handling framework, and still manages to be bad.

This C# comes from TheColonial.

Quel pénible

by in Error'd on

I have been collecting submissions for a set of themed columns to appear later. This week we received several submissions that will fit nicely in those themes and have been placed into stasis pending $whenIfeellikeit. If you haven't seen your submission appear, be strong; it may show up eventually. What remains here are entries that don't fit the available themes. Enjoy.

Number-loving Rick was counting on better sense at the census. "I went to check out recent data, and ran into this site where the main statistic is only available with lexical sorting! I looked at the downloadable csv and json, and sure enough, even there it is quoted text."

Exclusive Threads

by in CodeSOD on

When looking at code which juggles threads, there are definitely a few red flags. sleeps spammed through the code is an obvious one- either wait on a shared resource or block on another thread or something, but spurious sleeps are suspicious.

Until today, I would not have included "atomic operations" as a code smell in multi-threaded code, but we all learn new things.

Customer Needs

by in CodeSOD on

Code changes over time. As business requirements change, you need to update your code to reflect that, and the best way to do that is to structure your code and plan for changes before you even know what changes you need to make. Making your code flexible and changeable without making it meaninglessly abstract is the real art of software development.

Unless you're the document management provider that Daef works with. They have a very different approach for how they integrate new features and custom code paths.

Testing Your Date

by in CodeSOD on

"Don't unit test the library/framework code," is a good piece of advice. And yet, it's so often ignored.

Kaylee's co-worker certainly ignored it. They also ignored the basic principle of "ensure the test will work tomorrow."


by in CodeSOD on

Good commit messages make a codebase a lot easier to understand. In fact, maybe writing good commit messages could be everyone's New Year's Resolution. You can imagine that Kleyguerth was annoyed when browsing recent changes and saw a pair of commits: "do some stuff", followed by "fixed automated tests".

The "do some stuff" commit looked like this: