Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2024-04-28 07:02
CodeSOD: A Bit of Javascript
We've recently discussed how bit masks can confuse people. Argle's in a position to inherit some of that confused code.In this case, Argle's company inherited some NodeJS code from a customer who was very upset with the previous development team they had hired. It was a mix of NodeJS with some custom hardware involved.Like many of us, the first thing Argle's team did was just pull up the code and skim the documentation. It seemed thorough and complete. But it wasn't until they started looking at the implementation that they started to see the true horrors.Someone had reimplemented all of the bitwise functions as methods. And the core pattern revolved around the bitTest function:
CodeSOD: Holiday Sample Pack
Today, let's whip up a holiday sampler of some short snippets. We start with this anonymously supplied ternary from a C program, which certainly terned my head:
CodeSOD: Very Productive Code
Today's anonymous submitter sends us a pile of code that exists to flummox us. It's consfuing, weird, and I don't understand it, even as I understand it. So we're going to walk through this packet of Python in steps, to see if we can understand what's going on.First is this handy helper function, to turn a value into a number:
CodeSOD: Enabled and Disabled
A large part of programming is about communicating intent. The code you write needs to communicate your intent for what the code is supposed to do, both to the computer itself but also to all of the humans which come after you. So much of what we mean when we talk about code style and "clear names" is really about making your intent comprehensible to anyone else who looks at the code.When the intent of the code isn't clear, we often rely on comments to describe that intent.Which brings us to this comment that Noreen found.
Error'd: SOL
This column is experimenting with AI editing. Please provide feedback in the comments if youthink the AIs should continue to edit this columnor should be replaced by Genuine People Personalities.Dashing off a quick submission, the self-styled The Beast in Back quips"Breaking Ubuntu's snap is apparently a snap. It's quitea dashed annoyance, actually, since it dies if youprecede any argument string with dashes. Go figure."
CodeSOD: An XML Parser
Since we were discussing XML earlier this week, it's a good time to take a peek at this submission from Mark.Before we get into it, though, we need to talk briefly about some different XML parsing philosophies. XML documents are frequently large and deeply nested trees, and once loaded into memory, consume a lot of it. So there are two methods we might use to parse XML. We might parse and load the entire DOM- having all of that expensive processing and memory usage. The advantage is that we have the whole structure in memory, and can quickly and efficiently navigate through it. The other option is to read it as a stream, and process it one node at a time. This is both faster and a lot gentler on memory, but it means you have forward-only access to the contents.Or, you can just do what Mark's co-worker did:
CodeSOD: Counting on Switching
Frequent contributor Argle found some code written at his current company a "long time ago", but unfortunately in a galaxy far too close to our own.
CodeSOD: A Bit of a Misunderstanding
Mark B sends us another sample from a big-ball-o-wtf.Let's take a look at two variables. One variable is named taskDetail. The other variable is named binaryTaskDetail. You might ask yourself: what are the differences between these two?Well, one of them is a C# int- 32-bit integer. The other is a C# long- a 64-bit integer. And, as the name implies, binaryTaskDetail is meant to be a binary representation of the number."Wait," you might ask, "aren't all integers just binary representations under the hood? Can't you just bitshift or mask or whatever you need to do? Do you mean they want to output binary data? Like as a print statement? Now I'm confused."I'm sorry I confused you. Let's take a look at the code, and everything will be clear.
CodeSOD: Shipping a Gallon of Soap
While JSON's strength is its (relative) simplicity, XML's strength was always its power. Combined with an XML schema, you can create strongly typed documents with arbitrary data-types. For example, it's easy to define, oh, I don't know, a date time field in a way that isn't stringly typed.Of course, that's what also creates its complexity. XML is big, and bloated, and expensive to parse. Which brings us back to the old days of SOAP- the Simple Object Access Protocol, essentially an XML remote procedure call. It was powerful, but complex, with lots of interlocking standards. With its Web Service Description Language (WSDL), the service could even be self documenting, laying out all the objects and fields you could interact with.With all that web service tooling, it's trivial to expose core elements in your object model as web service end points, which is great if your object model is clean and easy to understand. It sorta sucks if you're the vendor Paul C ends up needing to work with.This is an API exposed by a shipping service, and it's clear that "consistency" wasn't part of its original goal. So they have fields like <strAccountNumber> and <strAccountNo>. That gives you the hope that maybe at least they standardized on Hungarian notation, but don't worry, in other places it's just called AccountNumber. Similarly, there's <strUserName> and <strUsername>, which caused no end of confusion, especially as the WSDL wasn't always accurate.But the sample Paul wanted us to look at was this one:
Error'd: Classic Errord: Having Fun With Words
CodeSOD: Common Variables
It's important to be prepared- but not too prepared. A common trap developers fall into is "premature abstraction"- trying to solve the general case of a problem when you only need to solve a very specific case.Frequent contributor Argle sends us some very old BASIC code. The task was to convert this ancient language into C#.Someone decided that, instead of waiting to learn specifically what variables they'd eventually need, they'd just declare all the variables they could ever want right at the top.Which gives us this block, included in its entirety.
CodeSOD: Years of Success
Way back in late 2006, Cody inherited a Java application. Since launching in 2001, the application had been running in production without any notable problems. And then, one day, it suddenly started throwing out errors on some orders. And then, a little later, any time someone tried to place an order. This constituted a rather large issue, since processing new orders was vitally important for keeping the lights on.The errors were validation errors, so Cody started by going to the line where the validation happened, and the exception was thrown:
CodeSOD: Check Out This Legacy App
VisualBasic was… an interesting beast. The language wasn't great, and because object orientation was awkwardly bolted onto it, but it also was heavily integrated into Microsoft's ActiveX libraries (heavily object oriented), there were all sorts of interesting ways to break your program with it. Even better: it was designed to be easy so that "anyone" could use it.Which leads to some of this code, from Dave. A number of years back, Dave was asked to try and convert an ancient VB6 application into something modern. Like all such conversions, the brief was: "make a new application that does exactly what the old application does, but nobody actually knows what the old application does because we never documented any requirements, just read the code".Reading the code had some "fun" moments, like this one:
CodeSOD: Unit Test Coverage
One of the fastest ways to get promoted in certain environments is through attrition. When a key player leaves, someone needs to step up and take over their work, somehow.Well, at Antonio's workplace, the tech lead on several projects abruptly quit. This sent the Project Management Office into a spiral, as that one developer's tasks were on every critical path on their Gannt chart. This four-alarm panic escalated all the way up to the C-suite.And that's how Antonio and a bunch of other developers got pulled into a series of meetings to turn them into "bug hunter-killers". Garth, the head of the PMO, laid out their mission."The root cause of the bugs are architectural flaws which have not yet been addressed. So we need a team that's going to go in, and salvage this project.""Are there any unit tests?" Antonio asked. "Before we go on a big refactoring push, we should make sure we're not introducing regressions.""Oh, don't worry about that. Our CI system is configured to reject builds under certain levels of coverage."So Antonio dug into the code. The project was in Java, and pretty much every class was built using Lombok- a library that handles a bunch of boring stuff, like implementing constructors, toString and equals methods. With that in mind, let's look at their expansive code coverage in their unit tests:
Error'd: Thanks
We got several submissions this week related to Steam'swebsite. Apparently it's popular with TDWTF readers. Is all of this a genuine indication of careless webdevs, or is Steam marketing just so fiendishly clever that they'retricking us into amplifying their presence? Feel free tospeculate; I'm going with a corollary to Hanlon's razor. Never attribute to malice that which can adequatelybe explained by awarding every job to the lowest bidder.First, Brad K. declared"I was surprised to see an email from Steam about a summer sale this late in the year. Then I saw, they gotit right at the same time they got it wrong,"
Classic WTF: Insecurity Doors
CodeSOD: Enterprise Streaming
Enterprise software development gets a bad rap, especially here, because "good code" isn't really a goal of an enterprise. Solving business problems is. And no enterprise is more enterprise than a government, and no government is more government than the US Federal government.Which brings us to today's anonymous submitter, who wanted to keep up on current events in US politics. While watching some recent videos of Senate proceedings, our submitter got bored watching (as one would), they pulled up the browser tools. And that's where our WTF comes from.So, in this code sample, each Senate committee has a different Akamai URL and ID for its videos. This is how the developer chose to represent that:
CodeSOD: SQL with no Equal
Relational Databases and No-SQL Databases take two key different philosophies, by and large. No-SQL is hard to talk about in broad terms, as it's mostly a set of unrelated technologies all solving the data storage problem in different ways. But we can still make some broad generalizations.In No-SQL-land, we mostly store data the way we plan to query it. Ad-hoc queries are likely a bad choice, if they're even allowed. In RDBMSes, we store data according to a platonic ideal of normal forms, driven by the data in our domain. We can query the data however we like, using a language that only declares the data we want, not how to get it. Indexes and views and other behind-the-scenes structures make the query efficient.Neither approach is wrong or bad or better, they are tuned to different ways of thinking about the problem. But the "invisible performance" of RDBMSes means that developers can invent new footguns without even knowing it.Dotan had a database query that went from "performing fine" to "performing poorly" in the space of a few hours. This was the query:
CodeSOD: It's Not That Different
We recently discussed the challenges of testing legacy code. Willy sent us some code from tests for a newer Java application.Now, one of the main advantages, in my opinion, about unit-tests is that they serve as documentation. They tell you what the method does, and how it expects to be called. A good unit test is far better than a large pile of comments.A bad unit test (or function supporting a unit test, as in this example) has the opposite effect.
Error'd: Monday Monday
Joshua O. repeats"Looks like this week will really be a case of the Mondays!"
CodeSOD: Switching Your Test Cases
Chris was given a program and told to improve it by adding tests. That was a good start to a terrible experience. Just getting it to build was a chore, as the build files had absolute paths hard-coded into them.But the real problem Chris ran in to is that it's hard to write tests for something if no one knows what it does or why it does it. The application had no documentation. No comments, aside from commented out blocks of dead code. But comments aside, there was no other documentation. Which left Chris with methods like this to work with:
CodeSOD: D'Tables
Wim works on a web app with a problem. Specifically, the error log is the fastest growing file on the system. Well, perhaps that's not the problem, but actually a symptom. Like so many applications, it's a PHP web app with a MySQL backend, and the previous developer made… choices.
CodeSOD: Hungry For an Education
An anonymous submitter from Hungary reached out with both some bad code, and a story behind it.Hungary's school system runs on a software package called KRÉTA. The Sawarim$ hacker group felt that the software was badly designed and left millions of students personal information unprotected- so they hacked in to prove it. The company running the software responded in the worst possible way- by attempting to cover up the breach and pretending nothing ever happened. It's quite the news story.The hacking group, not interested in releasing any students' private information, instead released the C# source code. Our Anonymous submitter reviewed some of that code, and sends us one method from it.
CodeSOD: The Parameters
As we frequently observe, code in scientific applications tends not to have the best code quality. And it's not hard to understand why: a researcher is frequently trying to take a wholistic understanding of a complicated problem domain and turn it into code. Software engineering, on the other hand, teaches us to break that wholistic picture up into little parts that we glue back together. The latter approach produces better code, but requires a lot of thinking about the structure of code, which is a whole layer on top of that wholistic understanding.Which brings us to Plink, a C program Oliver R has had to work with. It analyzes genetic variance data. It also has a method with this signature:
Error'd: Quantum Ferment
With a minimum of curated snark this week, you get only the freshest goods.Unpreserved jeffphi reports"My friend Jason mentioned this to me. I assume if you selectthese options, your pickle state will collapse only afterobserving your delivered goods."
CodeSOD: A Null Mystery
The saying goes that debugging is like solving a murder mystery, where you are both the victim and the killer. This, of course, is a bit inaccurate, since we rarely are the only programmer working on a project.Cole Tobin brings us a small mystery in C# today, though in this case, the mystery is- how does this even work?
Fixed the Bug
2020 was a rough year for everyone. Eventually, it will end, but as we drag through to the end of 2020.2, it's sometimes hard to remember the beforetimes.Sometime in that long era before 2020, Marc's team patched a bug in their software. Like good developers, the patch included a unit test. They could prove that the test failed before the fix, passed after the fix, and happily closed the ticket and went on to different things.In early 2020, Chris, one of the members of the team went on to a position elsewhere. A few months after that- the bug reappeared.But how? All the tests were showing green. Marc pulled up the code and found that the test had been disabled by Chris shortly before quitting. The commit message was simply: "Fixed?".It was easy to re-enable the test, but a bit harder to track down the regression. The even harder conversation was amending their processes to make sure a commit like that never got merged ever again. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
CodeSOD: What are you, Chicken?
My Steam profile doesn't represent the most active gamer on Earth, but in my time I put some pretty serious hours into the recent XCOM games. Each mission your squad goes on gets a procedurally generated name, and that can lead to some funny results just by itself (like "Avenging Avenger"). But, if you've put too many hours into the game, you might notice that every once in awhile, you see a mission with "Chicken" in its name.Now, it's obvious that this is just a joke. Clearly an Easter Egg hidden in the code by a programmer. But Rich D picked through the UnrealScript which powers the game, finding the code responsible.
CodeSOD: The Falling Dates
In the US, we "fell back"- that is to say we abandoned Daylight Saving Time and moved back to Standard Time, and I think the general consensus is that time changes are the real WTF.So let's use this as a moment to look at some bad date handling code, an evergreen topic.First, we turn to Adam, who's doing some minor work on an old PHP application.
Error'd: Foreign Keys
Amateur mathematician Chris F. thoughtfully sums up this screencap."Although Numberblocks is a brilliant show forkids learning to count, I can't help but feel the BBCperhaps need to watch it themselves when it comes tothe order of the series (or 'seasons' as many of yourreaders may know them) in the show..."
CodeSOD: Nothing Wagered, Nothing Errored
Cassi continues the fight against ancient, creaky PHP code.Today, it's particularly ancient- according to source control, it predates PHP 5.0 (and thus structured exceptions, and in this case may predate the current century). So the fact that this sets a pass-by-reference $errMsg variable and returns false on an error isn't the WTF in the code.
CodeSOD: On SSL
Mark was trawling through the WordPress code, tracking down a bug in an extension, when he noticed this particular method for deciding whether or not WordPress is served via HTTPS or not.
CodeSOD: Not a WTF
Sometimes, I have to wonder if I'm the dummy. Today I want to take a look at two examples from readers that are pretty close to code I've written, and I'm left wondering: am I the real WTF?meowcow moocat writes:
CodeSOD: The Bad Batch
Ashton works for a large bank, on an application that handles millions of dollars of transactions. The previous developer left this behind, which has everyone on the team scratching their heads.
Error'd: Paint it Black
Prescriptivist Phil pronounces"Alas, I've been saying these wrong my whole life.But at least my way I can say it in one breath."At least your way I can say it within my remaining lifespan, Phil!
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.
...45678910111213...