Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2024-05-18 17:16
CodeSOD: Strictly Speaking
I used to work in a VB.Net shop. It wasn't my favorite place, but it gave me an appreciation for modern VisualBasic, instead of old VB6 (which I also had to work on).Part of what made VB.Net better was that it had more sane defaults. By default it enabled Option Explicit (require variables to be declared before use), and Option Strict (error on any narrowing conversions between data-types). One of its biggest weaknesses, however, was that you could turn those features off, something which was frequently done to make old-style VB6 code more compatible with VB.Net. Arguably, the biggest WTF was that Microsoft promised an "easy" path to upgrade VB6 code to VB.Net, through a mix of compatibility libraries and conversion tools that didn't work.Which brings us to this VB.Net code that Stephen inherited. It's a small WTF, but so representative of the ways in which things could go very wrong.
CodeSOD: Clever And Or Not
The transition from Python 2 to Python 3 has been a long running challenge. Arguably, too long running, but those are the challenges when you introduce breaking changes into a widely used language.Now, one of those breaking changes was around string handling and encoding- Unicode versus ASCII. This meant that, if you wanted code to run on both versions of Python, you'd need to check which version you were on to handle encodings properly.Ryan J's predecessor wanted to implement logic where, on Python 2, they just handled the strings without transformation, while in Python 3, they'd force the string to be encoded in "latin1". The traditional way of writing this would be something like:
CodeSOD: Doc Block
We've all seen documentation blocks like this:
CodeSOD: Four Sellers
Andrew had to touch some Pascal code. Yes, really. He writes: "I came across this section of code today and really wanted to find out who wrote it. Then I really wanted to find out who added the comment."
Error'd: Classic Errord: Phone Pain
CodeSOD: Foreign to Administration
Doug's co-workers were creating a database to manage a set of custom application services and their associated metadata. So one of them threw together this table:
CodeSOD: Background Threads
Nyegomi supports a system with a load of actor objects tied to a bus, and supporting huge numbers of concurrent users. Once per second, the server looks at all the active objects and calls their update method, which gives them a chance to do vital housekeeping. Many of the objects may spin up background threads during that time.Like a lot of threading code, this leads to loads of problems in the wrong hands. Extra problematic in Python.
CodeSOD: Double Checking Your Validation
Let's say you wanted to express the difference between two numbers as a percentage of the first number. And then let's say that you have no idea how to properly handle a situation where that first number is zero.In that situation, you might end up with C code much like what Gaetan found.
CodeSOD: A Matter of Timing
Juan M inherited some broken code. Upon investigation, the result turned out to be caused by a mix of assumptions.The first assumption was in the way their users would interact with their scheduling system. Part of the assumption there was that they wouldn't try and schedule any events outside of the scope of a few human lifetimes. The other part of the assumption was that their serialization framework would have a consistent representation of datetimes that was reliably the number of seconds past the Unix epoch.Their serialization framework had another assumption: that any sufficiently large timestamps must be in milliseconds.
Error'd: Fire and Ice
Some say the world will end in fire, a great American poet once penned. Not wanting to run afoul of his heirs and assigns, I'll leave you to find the rest of it for yourselves.For my own two bits, let me say that while ice may suffice, nothing but nothing is quite like twice.Gordon S. writes to alert us to an unusualweather event next week. Good news, though. The boss saysyou can take the day off.
Protocol Zero
Ten years ago, James was working for a small company that made electronic components. That company got eaten by Initech, who wanted to connect all those smart electronic devices to their own products. This meant that the two companies had to agree on what that communication protocol would look like. More than that, this was on the critical path to completing the merger- Initech wouldn't go through with the purchase if they couldn't integrate with the systems they were purchasing.Negotiations were difficult. A lot of the challenge came from Initech's side, because they wanted to make the protocol a "do everything" system for managing data, which just wasn't something the embedded components were designed for. Over the course of many months, a design document gradually took shape.Since the messages passing through the protocol might be arbitrary lengths, one of the key decision points was "how do we determine the length of the message?" James's team advocated for a byte length in the header, but Initech protested: "We might not know the length of the message until after we've sent it."They couldn't explain how that could be- the protocol didn't support streaming- but Initech wasn't having any of it. The obvious other solution was to just simply ensure that the message ended with a null byte- a \0.Everyone went off to work on their implementations, and for a few months, everything seemed like it was going smooth. James and his team whipped up some testing tools, implemented the protocol, sent test messages, and everything worked great. Then it came time to integrate with Initech's implementation.And everything broke.Specifically, it looked like Initech had failed to actually terminate their messages."See, there's no termination character," James said, highlighting the hex dump which ended with 0x30. Every message ended with 0x30."I don't know what you're showing me," the Initech developer said, "because here's how I send the message." The dev highlighted the relevant section of code.
CodeSOD: An Explosion of Strings
Rich was digging through some legacy PHP code, trying to track down where some apparently magical values were coming from. This involved tracing through function after function after function.Here's a sampling of some of those functions:
CodeSOD: List All Your Arguments
Pedro inherited a PHP application, and the previous developer had some opinions about how to handle arguments to functions. This is the pattern they used everywhere:
Clbuttic Consequences
ComCorp went through a rather lengthy process to rebuild its website. One of the many changes implemented was to stop using titles as part of customer names. The lead developer on the project decided that removing the titles from all the places where they appeared was simply too much work."We'll just default to 'Mister' and then hide it wherever customer names are shown," he explained.A few months later, our brave submitter delved into the code and examined this particular function:
Error'd: Agreements and Documentation
Let's get right into it, because Mark T's day is off to a great start.Back when the COVID-19 pandemic started, a lot of folks were comparing it to the 1918 influenza epidemic. The application Abby used to document her vaccinations took that comparison somewhat literally.Dealing with credit card companies is a maze of legalistic nonsense where they redefine common words to mean something completely different and you'll get punished if you don't read the agreement very carefully. Look at what happened to Rob H, where they changed the meaning of the word "optional".Of course, Mike T ended up having an even harder time reading the agreements. This is what he saw when signing up for a new card:Joking aside: nobody actually reads those agreements. And as developers, we also never read documentation, so it's a surprise that Terry found this bit of JSON garbage in an Android documentation site. [Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
CodeSOD: Brillant Perls
Many years ago, a Paula Bean type was hired to make a Perl-based website. It became the company's flagship product, at least briefly, until a better version of the product was ready. But early adopters adopted it, and thus it had to keep operating, because you can't throw a way a 800kLOC web application just because it's fragile and unmaintainable.And then the site got hacked. So now, fixing everything becomes incredibly important, and the task fell to Erik. He needed to do a security audit and identify vulnerabilities. Alone. In a 800kLOC application of extremely questionable code quality. For bonus challenges, there is no testing environment available and no budget to stand one up- even if anyone knew exactly what actually needs to be in that environment, because there's a bunch of databases and packages and extra software and no one is entirely sure what the production environment is.Erik started by opening the first file he saw and giving it a skim. It was a small one, with only about two hundred lines in it. The first line was:
CodeSOD: Throw it $$OUT
If there's one thing worse in code than magic numbers, it's magic strings. Sean inherited an antique Visual C++ application, and the previous developers were very careful to make sure every string was a named constant.
CodeSOD: Unification of Strings
As a general rule of thumb, when you see a class called StringConverter you know something is going to be wrong in there. That's at least what Erik thought when examining a bug in a totally different section of string handling code that just happened to depend on StringConverter.StringConverter might sound like some sort of utility belt class with a huge pile of methods in it, but no- it's only got two. So we should take a look at both.Let's start with the method called Escape.
Special Validation
Ah, routers. The one piece of networking hardware that seems inescapable; even the most tech-illiterate among us needs to interface with their router at least once, to set up their home network so they can access the internet. Router technology has changed a lot over the years, including how you interface with the admin portal: instead of having to navigate to a specific IP address, some of them have you navigate to a URL that is intercepted by the router and redirected to the admin interface, making it easier for laymen to recall. But routers have their share of odd problems. I recently had to buy a new one because the one I was using was incompatible with my company's VPN for cryptic reasons even helpdesk had no real understanding of.Today's submission concerns a Vodafone router. Our submitter was setting up a network for a friend, and to make things easier, they set up a low-security password initially so they could type it repeatedly without worrying about messing it up. Once the network was set up, however, they wanted to change it to something long and cryptic to prevent against brute-force attacks. They generated a password like 6Y9^}Ky.SK50ZR84.p,5u$380(G;m;bI%NZG%zHd?lOStqRzS}Z?t;8qSg;[gy@ and plugged it in, only to be told it was a "weak" password.What? Length and variance both seem quite sufficient for the task—after all, it's not like there's roving bands of street gangs hacking into everyone's wifi routers and mucking about with the settings. There's no need for 300-character passwords.Curious, our submitter opened the Javascript source for the change password page to see what checks they failed, since the UI wasn't helping much:
Error'd: Oneth things frist
... or maybe oneth things snecod,as it turns out.This week, two unique anonymeesehave brought something to share, and our alienfriend Skippy piles on to the Lenovo laugh-in. Guten Morgen!Decisive Michael R. is flummoxed by the law of the excluded middle."YES," he assures us, "yes, those were checkboxes. And, no, not radios."
CodeSOD: The Misleading PIN
Tina needs to write some software that integrates with a hardware device. Thatdevice controls access via behind a PIN, and thus Tina's team needs to track the valid PIN, so that they can, via software, update or alter the PIN.There's just one problem. That device has some opinions about how a Personal Identification Number should be represented:
CodeSOD: Top Slots
Picking random items without repetition is its own special challenge. It's one of those things that's not actually hard, but some programmers have a difficult time coming up with solutions to the problem. Abraham has found these two examples in some code he maintains:
CodeSOD: Containerization
A large company with facilities all over the Asia-Pacific region opted to modernize. They'd just finished a pile of internal development that extended the functionality of a 3rd party package, and they wanted to containerize the whole shebang.That's where Fred came in, about 9 months into a 12 month effort. Things hadn't gone well, but a lot of the struggles were growing pains. Many of the containers were built as gigantic monoliths. A lot of the settings you might need to do a Kubernetes deployment weren't properly configured. It was a mess, but it wasn't a WTF, just a lot of work.The efforts of building the containerized, K8s deployments changed the company culture. The new rule was "container all the things", and all the things got containerized. Management was happy to be checking off new buzzwords, and the IT team was happy to have any sort of organization or process around deployments and their environment, since prior to this effort it was a lot of "copy this folder to this server, reboot, and cross your fingers".Everyone was happy, except for one team, led by Harry. "Your containers broke our software," Harry complained. Now, it wasn't "their" software- it was a purchased product. And like many enterprise software packages, it was licensed. That license was enforced via a smart card and a USB dongle.Which created a problem. Kubernetes is entirely about running your code absolutely abstracted from the physical hardware it's actually on. The USB dongle requires the code to be running on a specific physical device. The solution to the problem was obvious and simple: don't manage this one product via Kubernetes.But that wasn't an option. "We use Kubernetes to manage all of our deployments," management said. One of the managers helpfully linked to an interview in a trade magazine where the CTO cheerily shared the benefits of Kubernetes."Right, but this particular product is ill-suited to that kind of deployment," Fred and his team countered."Okay, yes, but we use Kubernetes for all of our deployments."And, as of this writing, that's where things sit. Everything must be containerized and hosted in Kubernetes. One software product doesn't play nice in that environment, but it must be wedged into that environment. Currently, the product lives on the same private server it used to live on, but this is a "stopgap" until "a solution is found". Officially it's out of compliance with company standards, and shows up as an evil red light on all the IT dashboards. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
CodeSOD: A Valid Call
"Never trust your inputs" is a generally good piece of advice for software development. We can, however, get carried away.Janice inherited a system which, among many other things, stores phone numbers. Like most such systems, the database validates phone numbers, and guarantees that numbers are stored in a canonical format, as text.For some reason, their Rails presentation layer isn't satisfied with this, and needs to validate the data coming from the database. In their specific environment, they know the database only contains canonical phone numbers, but honestly, I'm willing to forgive the belts-and-braces approach, as I've certainly used enough databases that couldn't provide those kinds of guarantees.No, the problem is the way they went about it.
Error'd: Ixnay
I know that I recently implied a fondness for cookedcorvid, but if this keeps up I'm going to turn vegan. Itwill be a sad day if I have to turn in the barnyard puns.ReaderRuthless R. goes in HAM, crowing"Daily WTF goes WTF with its RSS Feed." It's getting to be less funny.
Model Years
Caleb (previously) continues to work for a vehicle finance company. Most recnetly, he was working on a data ingestion application. Its job was to pull in a big ol' pile of CSVs from a mix of vendors and customers and feed it into a central database to keep things up to date."Application", however, is misleading. In reality, it was a suite of Access databases scattered around various network shares. Each represented a custom data loading pathway for a kind of data. It wasn't true that each was isolated from every other- frequently, the data flow would be "Open database \\fileserver\processing\vendor01.mdb, use the form to load the CSV file, then open \\fileserver\processing\process01.mdb, but only AFTER you've deleted the CSV file."Caleb's job was "easy": trawl through this thicket and figure out which parts handled just vehicle model information, sourced from vehicle manufacturers. Figure out what it did, and then reimplement in something that wasn't a fragile pile of Access databases.While working on that, a new problem appeared: manufacturers were announcing their 2023 model numbers, but the system simply couldn't ingest those. No vehicles with 2023 model numbers could be created. After searching for awhile, Caleb figured out that it went through this table, created in 2008, which hadn't had any data added/removed since:ModelYearAbbrModelYear420045200562006720078200892009102010112011122012132013142014152015162016172017182018192019202020212021Now, this isn't particularly shocking, and honestly, probably wasn't even a terrible idea. It's just that, since new years were never added, it made it impossible to add vehicles in the 2023 model year.But that still left Caleb with another question: their system had vehicles with a 2022 model year just fine. Did a bug let the data load last time? Is there another code pathway Caleb hasn't found? Is there a mystery Access database on a file share no one remembers that can handle model years more recent than 2021? No one knows, and truly, does anyone want to know? Down that path lies an eldritch madness, a cosmic horror that would cause our very souls to bleed.(Or, probably, someone just manually inputted all that data, but the eldritch thing is more fun.) [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
CodeSOD: The Base Model
Penny uses a Python ORM. Like most ORMs, it involves a lot of "inherit from a BaseModel class, and get all your database access stuff for "free". Or at least, it used to. They've released an update.
Editor's Soapbox: TODO: Post an Article
Yesterday, I briefly mentioned the "TODO" comment as part of the WTF. Anyone who develops software for long enough is going to develop some pet peeves. Lord knows, my feelings on Hungarian Notation are well established. Or ternaries, though honestly, for ternaries, I mostly am in it for the puns.But, I've got another pet peeve that's crawling up my butt far enough that I felt the need to do a soapbox about it.
CodeSOD: Bitmaps and Streams
Robert has inherited a .NET application. It's a big-ball-of-mud, full of monstrous classes of thousands of lines and no coherent purpose, complete with twenty constructors.It's ugly and messy, but it's mostly just generically bad. This method, however, is a lot of bad choices in very few lines.
Error'd: Taking the Piss
In case anyone is wondering "is there anything so lame that it's not evengood enough to get published by Error'd", the answer is yes. There is acategory of submissions that is very common, but in the completely capricious opinion of this editor, just not very funny. That category is clearly broken listings on amazon.com. We usually get two or three of theseevery week. We save them up, and maybe someday the news will be so slow that we have no choice but to run an entire column of nothing but Amazon bloopers. This week was no different from the usual, except that this timethe September stress has struck a nerve and so you get to see what the brink of madness looks like from the inside.Tippler Matthias poured one out for us. "Seems someone already tried some of the good stuff while uploading the images to Amazons catalog."
Version Numbers
Initech was the big customer for Chops's company. And like a lot of big customers, they had requests and they had the weight to throw around to get their requests fulfilled. When they wanted a new feature, they got a new feature. When they found a bug, they got the patch ASAP.No matter how special Initech thought they were, they were mostly requesting things that other customers wanted anyway, so it worked pretty well.So, one day, they submitted a pile of feature requests, the dev team got to work, and cranked out the features. They tested it, they shipped betas out to the customer, the customer liked the changes, confirmed that it passed user-acceptance, and was ready to deploy. Well, almost ready. There was one tiny little problem."So, we can't do this upgrade," said Jerry, the lead from Initech. "It violates our IT policy.""Um, how?" Chops asked."Well, the current approved version in our environment is 3.4.24. The version you're shipping us is 3.5.1. That's too big a version number change.""Oh, uh… we shipped 3.5 a few months ago…""Right, but we haven't gotten that approved. Can you add these features to the 3.4 version?"That request got escalated up to management, and since Initech was a big customer, management said, "Yes, absolutely, do it."The result was a disaster. While 3.5 and 3.4 were basically the same from the end user's perspective, a lot of internals had changed. The new features used the new internals, and when trying to backport them it was a lot of work. They started from the codebase of 3.4.30 (the last release of 3.4.x), and ended up breaking everything. Tests which passed under 3.5 started failing, tests which had been passing under 3.4 also started failing. No one was exactly sure how to backport these features to the old internals and it was eating a lot of developer cycles.Chops watched this slow motion disaster, and watched management getting increasingly upset. Initech wanted their new features, and they wanted them last week. So Chops decided to take matters into their own hands. They took the 3.5.1 build, and re-set the version numbers to be 3.4.31."Hey, Jerry," Chops said. "I've taken the latest version, 3.5.1, and I've renamed it 3.4.31. So the official version number is 3.4.31. Is that okay?""Uh, the version you're giving me is 3.4?""That's the version number on the file, yes. But the code is actually 3.5.""But the file says 3.4?""It does," Chops said. "And the 'about' information will also say 3.4.31.""Perfect, that'll do."Chops sent the file over. Jerry ran it through all their tests and confirmed it was still satisfactory. Initech's management confirmed that the version number only incremented a small amount, and it was still "officially" a 3.4 version.Everyone was happy with this outcome. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
CodeSOD: Walking is your Duty
Embedded chip documentation is sometimes very bad, and very confusing. Frequently it's difficult to really understand the ins and outs of a given chip without simply getting experience.Which is why Mr. Scrith was a bit surprised with this code, which came from someone who definitely should have known better.This code is for a "walking 1s" memory test- it simply visits every address in memory and writes a "1" and confirms that it can read back that "1". Such a test poses an interesting challenge: you can't use any variables, because they will live in RAM somewhere, so you need to limit yourself only to the registers exposed by your CPU.And that's where this developer made their odd choice. This particular CPU had plenty of general purpose registers, and a bunch of special purpose registers, like a set of registers for controlling PWM generators. The developer either couldn't find the correct way to access the general purpose registers or didn't care to try, but either way, the end result was that they used the PWM registers for everything:
CodeSOD: Up the Garden Path
Sam worked on an application which needed to parse files out of a directory. There was a ticket to change the search path for those files to search an additional directory. That didn't turn out to be terribly hard, but the existing code raised some serious eyebrows.
CodeSOD: Undefined Variable
Robert H was trawling through the JavaScript front-end for his team's ASP.NET MVC application. The goal was to prepare for a complete rewrite of the front-end, because, well, it had problems and wasn't reliable or maintainable.As an example, Robert sends this:
Error'd: Crowneisseurship
Never let it be said that we at TDWTFdon't enjoy the taste of our own medicine. Andrew I. shares with us a little taste ofhis own crow, and then we share with you a little taste of Remy's. It's not quite a full meal, but you can call it anamuse bouche.But first, Sam B. serves up some sure fled pie."This Brexit business is getting out of hand. Lenovosays even the United Kingdom has left the UK."
CodeSOD: Oh, Poop
Pearl was paying down some technical debt. She was trawling through their NodeJS application with a search for TODO and console.log. She was triaging the TODOs, and replacing the logs with a real logging framework.The application was old, had many complicated routes for requests to be handled, and buried deep in a file was this code, which was clearly testing code that was never meant to end up in production:
CodeSOD: Enumerating Your Plants
Usually, we don't pick on game code, as it's frequently bad because of the time constraints under which it's developed and because the concerns are more around "making a fun, performant game," and not "writing good reusable code".But there are some egregious exceptions, like what happened to Patrick. He was handed some C# game code, and told, "Good luck!"This particular block lived in a file called banana.cs. Does this game have anything to do with bananas? It does not! It has to do with zombies. No, it is not Plants vs. Zombies, though given the botanical flair in this code, perhaps the author was a fan?One module of the game uses integers as the ID values of enemies. One module uses strings. No one uses enums. So when you want to convert the IDs to the appropriate type, you need to call enemyIdNumToName, which I want to stress- is not the display name of the enemy.
Not-so-Simple Network Management Protocol
"Phillip, are you familiar with SNMP? Do you know Python?" asked Phillip's new boss."No.""Would you like to be?"That's how Phillip got thrown into the deep end of a conversion project that was tasked with updating their infrastructure monitoring system. It was developed by a team a few years ago, and they all quit at the same time, which made it hard to maintain.It was a homegrown set of Python scripts which polled a Prometheus service, which itself was gathering metrics from a pile of Docker containers. These scripts gathered those events and turned them into SNMP alerts for a third party receiver.The upgrade promised to be simple: take the SNMPv2c code and update it to use SNMPv3, which supports encryption. Phillip started by pulling the existing code from their repository, only to find that while there was a repository and it had a pile of branches, nothing had ever been merged into main/master/trunk. So Phillip pinged one of the other developers: "Which is the correct version of the code?"He started playing with the PySNMP library while he waited. From reading the docs, Phillip thought that it should be a very simple change- essentially a find/replace to update one class name. After a few days of poking at the library, the previous developer gave him about three candidate branches which were probably what was actually deployed. Phillip found a Docker image that seemed to have the same code as one of those branches, and was probably the one deployed- no one knew for certain- and set to work.His first attempt didn't work at all, which wasn't surprising. There was no logging, the configuration was hard-coded in half a dozen places in the code and didn't always agree with the other places, and someplace along the way it needed an SNMP command, which nothing was sending. It was mess, but eventually, Phillip got it running.For a few minutes, anyway. Then it would crash. It took Phillip two months of research and experimentation to discover that the SnmpEngine object wasn't threadsafe. It wasn't his choice to use it across multiple threads- that was the architecture that the previous developers had used.That's when it dawned on Phillip: this program had never worked. Sure enough, the deployed version crashed all the time, too. So Phillip set about refactoring and debugging it, and after two more months, he had a thing that could read the metrics and report them to SNMP.Except the third-party receiver that expected to receive those messages didn't get them. Phillip could confirm he was sending it, but it wasn't arriving. Cue another month of scrambling and head-scratching, only for Phillip to discover that the network team had blocked the routes from the server he was running on and the third-party receiver."Oh, it was sending so much traffic, we assumed it was broken," was the best explanation he could get.So the service never worked in the first place. Even if it had worked, the network team had blocked it from working. No one talked to anyone else about what was going on. And, as the cherry on top of the sundae, the main customer for this data didn't believe in "on-call rotations"- they got ahold of the developers' cellphone numbers and called them directly whenever they had an issue.All that added up to Phillip leaving the company after a very long six months. It also neatly explained why the previous dev team had all quit en masse."Still," Phillip writes, "at least I got some Python experience out of it." [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
Classic WTF: Security By Oblivity
Error'd: Pub Kick
Last week's article nearly exposed to the public the lowest-keytechreligious war that has been waging for decades. PEBKAC versus PEBCAK completely underwhelmsthe emacs vs vi war, the GUI vs CUI massacre, the tabs vsspaces schism, and even the -- + // alliance against the/* and (* comment markers. Scratch a PEBCAK partisan andall you'll find is a bit of blood and a response of "OW! Why did you do that?! There isn't any war!!" Even thepartisans deny it exists but it simmers. It's PEBKAC, Itell you. PEBKAC! Wait, I forgot. Which did I use inlast week's article?Plotzed publican Peter G. has tired of his local and decidedhe'd rather pop round todas Lokal for a schnitzel. Researchingreviews, he was surprised by an unexpected mountain PICNIC(Problem In Chair Not In Computer)."Dumont Travel seem to think the Anschluss is still in effect,or at least this is what you get when you ask for travelinfo for Austria (Österreich)."
CodeSOD: Latrinalia
My favorite bar in Pittsburgh is a bit of a dive. Like any good dive, the bathroom is covered in the incoherent scrawl of thousands of drunks. It's a mix of jokes, political flamewars, and just absolute nonsense. My favorite part about it, though, is that it just makes me think about the long history of latrinalia. For as long as there have been humans, we've been scribbling on whatever surface was at hand, and a lot of those scribbles have been made while we answer nature's call.Programmers have their own form of latrinalia: code comments. They're frequently vulgar, they're sometimes comprehensible only to the person who wrote them, and we all like to pretend that they're more meaningful than they are.So let's take a look at a few mysterious scribbles on the bathroom walls of code.We start with this one, from Johann:
CodeSOD: Observable Queries
Rachel is doing some Python/Django work on an application that, among other things, handles a pile of Internet addresses, a mix of IP addresses and domain names. Since each of those has a very different query path (domains could be filtered on the TLD or the name portion of the domain, for example), Rachel implemented some helper objects built on Django observables, the IPAddressObservable and the DomainObservable.This way, when someone wanted to search the database for an address, some code like this could run:
Internal Networking
Circa 1999, Drake C was working on a video game for a large publisher. The game in question was a flight simulator with multiplayer dogfighting capabilities. Or at least, it was supposed to have multiplayer capabilities- in Drake's case, it just had a series of ugly crashes.The networking library came from the publisher, so Drake reached out to Karl, the developer of said library. They spent some time going back and forth over the phone and email, trying to troubleshoot it. Eventually, Karl tapped out. "I'm stumped," he admitted, "but I'll tell you what, we've got another team working on Weighty Cogs II, and they've already got multiplayer working. I'll get them to send you their code, so you can take a look. Should have it to you by this afternoon.""Oh," Drake said, "that'd be great. There's no rush, I've got plenty other tasks to work on, but yeah, if you can get that to me, that'd be super helpful."Drake moved on to those other tasks, and made a note to follow up with Karl. Half an hour later, Karl sent an email. CCed was the Weighty Cogs II team lead, the WC2 product manager, a developer from WC2, and a name Drake didn't recognize. The body was brief: "Please send Drake the network code."That itself kicked off another flurry of emails- another chain of names that Drake didn't recognize picked up the thread, forwarded the email around, kept Drake CCed on it, and just generally escalated through an obscure series of other owners, with the command: "Please put this together."Days passed. Drake kept hacking away at the many other tasks he had to work on. Every once in awhile, those tasks brought him into contact with Karl again, and when he did, he'd always ask, "Hey, is there any progress on getting me that code? Still no rush, but just trying to check the status."Karl would promise a follow up, and they'd continue.The email thread continued to tick away. It got passed from hand to hand, gradually wending its way up the digestive track of the publisher, until it finally started tickling the tonsils of some VPs. The tone of the email chain went from, "we need to do this," to "why hasn't this happened yet?"Outside of the email thread, there was a separate thread, involving those VPs, management, the entire Weighty Cogs II team, yet another development studio that was also doing a multiplayer game, and a few other odd names for good measure. This particular thread was a bit more panicked in tone, and lots of the information was getting lost. Suddenly, Drake hadn't simply accepted an offer of some network code from the WC2 team, he had demanded the entirety of the WC2 codebase. That team was from a different studio, so obviously they didn't want to just hand over all their code to a competitor. The publisher, however, didn't care what they wanted, since they owned all the rights. Somehow, the VPs had decided that this was on the critical path to hitting their release dates, and that if it didn't happen, Drake's project might be a complete failure. Which didn't endear Drake's team to the WC2 team at all- why should they bail out those failures?After a lot of screaming, several contentious conference calls, and a few C-suite meetings, this panic trickled back down the organization to Drake's boss, Mikey.Mikey stopped by Drake's cube. "Hey, Drake? Did you ask for the entirety of the Weighty Cogs II source code to be drop shipped on CD to you ASAP or we'd fail to ship?""What!? No!" Drake explained his request, and Mikey nodded."Okay, that makes sense. But you need to stop asking for it, because it's blown up to a thing."Mikey and Drake chuckled about the absurdity of the situation, and Drake stopped poking Karl about the software.The source code did finally arrive, at the start of the following week. It was shipped on CD, and the networking code was spaghettified into the game logic code, which both meant that it was difficult to trace, and also not reusable for Drake's task at all. But it did offer enough of an example that Drake could tell that his understanding of the networking library was correct. With that confidence, he was able to comb through his code until finally identifying the, in his words, "boneheaded mistake" in his code which caused the crash. [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
CodeSOD: Optional Ternaround
As we frequently discuss here, many versions ago, Java added functional programming expressions, which can allow a developer to write very expressive, simple code. Of course, we don't cover any of those uses, because that's all fine.Kevin L used to work for a Fortune 500 company, and that company was full of developers who got very excited about those functional programming features in Java. Very excited. Too excited, if we're being honest.For example, if they wanted to check if an object was null, they might do this:
Error'd: Win A Few, Lose A Few
Today's amusements include a couple of twofers: one from a mouse,and two not-quite-canonical Error'ds that still manage to be pretty double you tee effy.First up, an eponymous anonymous shared what unlimited looks like."Thanks for the additional disk space," they squeaked. "That should cover me for a while." I suspect this is some kind of network drive, as I vaguely recall having seen something similar decades ago.
CodeSOD: Expanded Conditionals
A common anti-pattern is the "expanded conditional". You know the drill:
C, But Worse
Alyssa worked in a shop building small runs of custom hardware. Recently, she tackled a project that involved an Arduino talking to an LCD screen. Since several programmers had just left their jobs, she was the last programmer standing and thus on her own for this assignment. One of the engineers who'd worked there before her had really liked a particular brand of programmable displays because they came with software that allowed non-programmers to design serial-driven user interfaces, and had its own onboard processor. That was what Alyssa wound up using for this project.Alyssa first tried to control the screens using the manufacturer's own serial library. She couldn't get any of the system commands to work over that serial library, but they did work if she used the manufacturer's test programs, running on the screen's onboard processor. Those would get uploaded via Serial, and sure enough, Alyssa could send commands over serial, just not using the vendor's library.This led her to try programming the screen directly ... which turned out to be a very bad decision.The manufacturer had come up with their own language. It was almost C, except there was only one data type: 16-bit integers. Want pointers? We're running on 16-bit hardware, so just use integers. Want strings? Use arrays of ints, two chars to the int! Want structs? No, of course not, who uses those? You can just use int arrays and manual byte offsets, right? Who needs type safety?If the language was bad, the documentation that struggled to rationalize its existence was worse. Sections had been copy/pasted wholesale without anyone remembering to go back and tweak them, leading to incorrect information everywhere one looked. References to other manuals contained no links or information on how to find them other than "use the site's search function." Drawing dimensions were flat-out wrong.In desperation, Alyssa visited the user forums for help, only to find scads of people like herself begging the manufacturer to let them use C on the screens. The manufacturer refused on the grounds that their language was more "beginner friendly" and that C wasn't "portable enough."After two weeks of this agony, Alyssa recalled that sending serial commands directly had worked before. She wrote some small utilities that completely routed around the manufacturer's software and finally got everything up and running. Upon congratulating her, Alyssa's boss also suggested selling her utilities to the manufacturer, which at this point could only be an improvement. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
CodeSOD: Constantly Magic
Here's one you've seen before. Somebody Fran works with heard that magic numbers were bad, and that you should use constants, so they did this:
CodeSOD: Accessible Booleans
For twenty years, Initech didn't have any sort of internal IT or anyone doing any sort of cohesive software purchasing or internal development strategy. Of course, as the company grew, they needed customized applications. With no official approach to doing this, the users did the best they could, using the developer tool installed on nearly every corporate Windows workstation: Microsoft Access.That's when Kris got hired, along with a pile of other developers. The team had one simple mission: convert these Access applications into "real" applications.Like pretty much every one of these projects, there were no requirements, beyond, "it should do the same thing as the existing application, but not be a fragile mess of overgrown code developed by people who didn't know what they were doing beyond just making it work". This meant that for a lot of the requirements analysis, Kris and the team needed to just trace through the code and try and figure out what it was doing.By the standards of these kinds of applications, the code was better than average, but that still didn't mean it was fun reading. Since there was no source control, old versions of the code just lived on in comments, and that lead to some of these sorts of head scratchers:
Error'd: Figures Never Lie
As always, dates are hard, memory management is hard, and localization is hard, but nothing, nothing is as hard as multiplication.Sushi fanBen A. found the freshest fish in western NY."After an earlier email thanking me for a non-existentrecent order," he confides, "Beyond Menu has helpfully clarified thatthey can predict the future."
...567891011121314...