Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2025-10-15 18:31
CodeSOD: Titration Frustration
From submitter Christoph comes a function that makes your average regex seem not all that bad, actually:
Promising Equality
One can often hear the phrase, “modern JavaScript”. This is a fig leaf, meant to cover up a sense of shame, for JavaScript has a bit of a checkered past. It started life as a badly designed language, often delivering badly conceived features. It has a reputation for slowness, crap code, and things that make you go “wat?”Thus, “modern” JavaScript. It’s meant to be a promise that we don’t write code like that any more. We use the class keyword and transpile from TypeScript and write fluent APIs and use promises. Yes, a promise to use promises.Which brings us to Dewi W, who just received some code from contractors. It has some invocations that look like this:
Error'd: These are not the Security Questions You're Looking for
"If it didn't involve setting up my own access, I might've tried to find what would happen if I dared defy their labeling," Jameson T. wrote.
Representative Line: An Array of WHY
Reader Jeremy sends us this baffling JavaScript: "Nobody on the team knows how it came to be. We think all 'they' wanted was a sequence of numbers starting at 1, but you wouldn't really know that from the code."
The Interview Gauntlet
Natasha found a job posting for a defense contractor that was hiring for a web UI developer. She was a web UI developer, familiar with all the technologies they were asking for, and she’d worked for defense contractors before, and understood how they operated. She applied, and they invited her in for one of those day-long, marathon interviews.They told her to come prepared to present some of her recent work. Natasha and half a dozen members of the team crammed into an undersized meeting room. Irving, the director, was the last to enter, and his reaction to Natasha could best be described as “hate at first sight”.Irving sat directly across from Natasha, staring daggers at her while she pulled up some examples of her work. Picking on a recent project, she highlighted what parts she’d worked on, what techniques she’d used, and why. Aside from Irving’s glare, it played well. She got good questions, had some decent back-and-forth, and was feeling pretty confident when she said, “Now, moving onto a more recent project-”“Oh, thank god,” Irving groaned. His tone was annoyed, and possibly sarcastic. It was really impossible to tell. He let Natasha get a few sentences into talking about the next project, and then interrupted her. “This is fine. Let’s just break out into one-on-one interviews.”Jack, the junior developer, was up first. He moved down the table to be across from Natasha. “You’re really not a good fit for the position we’re hiring for,” he said, “but let’s go ahead and do this anyway.”So they did. Jack had some basic web-development questions, less on the UI side and more on the tooling side. “What’s transpiling,” and “how do ES2015 modules work”. They had a pleasant back and forth, and then Jack tagged out so that Carl could come in.Carl didn’t start by asking a question, instead he scribbled some code on the white board:
CodeSOD: ALM Tools Could Fix This
I’m old enough that, when I got into IT, we just called our organizational techniques “software engineering”. It drifted into “project management”, then the “software development life-cycle”, and lately “application life-cycle management (ALM)”.No matter what you call it, you apply these techniques so that you can at least attempt to release software that meets the requirements and is reasonably free from defects.Within the software development space, there are families of tools and software that we can use to implement some sort of ALM process… like “Harry Peckherd”’s Application Life-Cycle Management suite. By using their tool, you can release software that meets the requirements and is free from defects, right?Well, Brendan recently attempted to upgrade their suite from 12.01 to 12.53, and it blew up with a JDBC error: [Mercury][SQLServer JDBC Driver][SQLServer]Cannot find the object "T_DBMS_SQL_BIND_VARIABLE" because it does not exist or you do not have permissions. He picked through the code that it was running, and found this blob of SQL:
CodeSOD: A Type of Standard
I’ve brushed up against the automotive industry in the past, and have gained a sense about how automotive companies and their suppliers develop custom software. That is to say, they hack at it until someone from the business side says, “Yes, that’s what we wanted.” 90% of the development time is spent doing re-work (because no one, including the customer, understood the requirements) and putting out fires (because no one, including the customer, understood the requirements well enough to tell you how to test it, so things are going wrong in production).Mary is writing some software that needs to perform automated testing on automotive components. The good news is that the automotive industry has adopted a standard API for accomplishing this goal. The bad news is that the API was designed by the automotive industry. Developing standards, under ideal conditions, is hard. Developing standards in an industry that is still struggling with software quality and hasn’t quite fully adopted the idea of cross-vendor standardization in the first place?You’re gonna have problems.The specific problem that led Mary to send us this code was the way of defining data types. As you can guess, they used an XML schema to lay out the rules. That’s how enterprises do this sort of thing.There are a bunch of “primitive” data types, like UIntVariable or BoolVariable. There are also collection types, like Vector or Map or Curve (3D plot). You might be tempted to think of the collection types in terms of generics, or you might be tempted to think about how XML schemas let you define new elements, and how these make sense as elements.If you are thinking in those terms, you obviously aren’t ready for the fast-paced world of developing software for the automotive industry. The correct, enterprise-y way to define these types is just to list off combinations:
Error'd: PIck an Object, Any Object
"Who would have guessed Microsoft would have a hard time developing web apps?" writes Sam B.
Representative Line: A Case of File Handling
Tim W caught a ticket. The PHP system he inherited allowed users to upload files, and then would process those files. It worked… most of the time. It seemed like a Heisenbug. Logging was non-existent, documentation was a fantasy, and to be honest, no one was exactly 100% certain what the processing feature was supposed to do- but whatever it was doing now was the right thing, except the times that it wasn’t right.Specifically, some files got processed. Some files didn’t. They all were supposed to.But other than that, it worked.Tim worried that this was going to be difficult to replicate, especially after he tried it with a few files he had handy. Digging through the code though, made it perfectly clear what was going on. Buried on about line 1,200 in a 3,000 line file, he found this:
News Roundup: Calculated
A long time ago, in a galaxy right here, we ran a contest. The original OMGWTF contest was a challenge to build the worst calculator you possibly could. We got some real treats, like the Universal Calculator, which, instead of being a calculator, was a framework for defining your own calculator, or Rube Goldberg’s Calculator, which eschewed cryptic values like “0.109375”, and instead output “seven sixty-fourths” (using inlined assembly for performance!). Or, the champion of the contest, the Buggy Four Function Calculator, which is a perfect simulation of a rotting, aging codebase.The joke, of course, is that building a usable calculator app is easy. Why, it’s so easy, that we challenged our readers to come up with ways to make it hard. To find creative ways to fail at handling this simple task. To misinterpret and violate basic principles of how calculators should work.Well, I bring this up, because just a few days ago, iOS 11.2 left beta and went public. And finally, finally, they fixed the calculator, which has been broken since iOS 11 launched. How broken? Let's try 1+2+3+4+5+6 shall we?For those who can't, or don't wish to watch the video, according to the calculator, 1+2+3+4+5+6 is 75. I entered the values in quickly, but not super-speed.I personally discovered the bug for myself while scoring at the end of a round of board games. I just ran down the score-sheet to sum things up, tapping away like one does with a calculator, and got downright insane results.The underlying cause, near as anyone has been able to tell, is a combination of input lag and display updates, so rapidly typing “1+2+3” loses one of the “+”es and becomes “1+23”.Now Apple’s been in the news a lot recently- in addition to shipping a completely broken calculator, they messed up character encoding, causing “I” to display a placeholder character, released a macOS update which allowed anyone to log in as root with no password, patched it, but with the problem that the patch broke filesharing, and if you didn’t apply it in the “right” order, the bug could come back.The root cause of the root bug, by the way, was due to bad error handling in the login code.Now, I’ll leave it to the pundits to wring their hands over the decline of Apple’s code quality, worry that “is this the future of Apple?!?!!11?”, or claim “this never would have happened under Jobs”. I’m not interested in the broad trends here, or prognosticating, or prognostibating (where you please only yourself by imagining alternate realities where Steve Jobs still lives).What I am interested in is that calculator app. Some developer, I’m gonna assume a more junior one (right? you don’t need 15 years of experience to reimplement a calculator app), really jacked that up. And at no point in testing did anyone actually attempt to use the calculator. I’m sure they ran some automated UI tests, and when they saw odd results, they started chucking some sleep() calls in there until the errors went away.It’s just amazing to me, that we ran a contest built around designing the worst calculator you could. A decade later, Apple comes sauntering in, vying for an honorable mention, in an application they actually shipped. [Advertisement] High availability, Load-balanced or Basic – design your own Universal Package Manager, allow the enterprise to scale as you grow. Download and see for yourself!
Editor's Soapbox: Protect Yourself
CodeSOD: Pounding Away
“Hey, Herbie, we need you to add code to our e-commerce package to send an email with order details in it,” was the requirement.“You mean like a notification? Order confirmation?”“Yes!”So Herbie trotted off to write the code, only to learn that it was all wrong. They didn’t want a human-readable confirmation. The emails were going to a VB application, and they needed a machine-readable format. So Herbie revamped the email to have XML, and provided an XML schema.This was also wrong. Herbie’s boss wrangled Herbie and the VB developer together on a conference call, and they tried to hammer out some sort of contract for how the data would move from system to system.They didn’t want the data in any standard format. They had their own format. They didn’t have a clear idea about the email was supposed to contain, either, which meant Herbie got to play the game of trying his best to constantly revamp the code as they changed the requirements on the fly.In the end, he produced this monster:
Error'd: Get Inspired
"The great words of inspirationalAuthor.firstName inspirationalAuthor.lastName move me every time," wrote Geoff O.
CodeSOD: Aarb!
C++’s template system is powerful and robust enough that template metaprogramming is Turing complete. Given that kind of power, it’s no surprise that pretty much every other object-oriented language eschews templates for code generation.Java, for example, uses generics- essentially templates without the metaprogramming. What we still keep is compile-time type-safety, and all the benefits of generic programming, but without the complexity of compile-time code generation.Thierry L inherited a Java application, and the original developer seems to miss that degree of complexity.
Thanks, Google
"Dealing with real customers is a hard job," Katya declared from the safety of the employee breakroom. "Dealing with big companies is even harder!""I know what you mean," her coworker Rick replied, sipping his tiny paper cup of water. "Enterprise security requirements, arcane contract requirements, and then they're likely to have all that Oracle junk to integrate with ...""Huh? Well, that too, but I'm talking about Google.""Google? What'd they do?" Rick raised an eyebrow, leaning against the wall by the cooler, as Katya began her story.As the lead architect, Katya was responsible for keeping their customers happy—no matter what. The product was a Java application, a server that stood between legacy backends and mobile apps to push out notifications when things happened that the customer cared about. So when one of their biggest customers reported that 30% of the Google Cloud messages weren't being delivered to their devices in production, it was all hands on deck, with Katya at the helm."So I of course popped open the log right off," she said, her voice dropping lower for effect. "And what do you think I saw? CertPathValidatorExceptions.""A bad SSL certificate?" Rick asked. "From Google? Can't be.""You've done this before," Katya pouted, jokingly. "But it only happened sporadically. We even tried two concurrent calls, and got one failure, one success.""How does that even work?" Rick wondered."I know, right? So we cURL'd it, verbose, and got the certificate chain," Katya said. "There was a wildcard cert, signed by an intermediate, signed by a root. I checked the root myself, it was definitely part of the global truststore. So I tried again and again until I got a second cert chain. But it was the same thing: cert, intermediate, trusted root.""So what was the problem?" Rick asked."Get this: the newer cert's root CA was only added in Java 7 and 8, back in 2016. We were still bundling an older version of Java 7, before the update.""Ouch," sympathized Rick. "So you pushed out an updated runtime to all the customers?""What? No way!" Katya said. "They'd have each had to do a full integration test cycle. No, we delivered a shell script that added the root CA to the bundled cacerts.""Shouldn't they be worried about security updates?" wondered Rick"Sure, but are they actually going to upgrade to Java 8 on our say-so? You wanna die on that hill?"It just pissed me right off. Why didn't Google announce the change? How come they whipped through them all in two days—no canary testing or anything? I tell you, it's almost enough to make a girl quit and start an alpaca farm upstate." [Advertisement] Atalasoft’s imaging SDKs come with APIs & pre-built controls for web viewing, browser scanning, annotating, & OCR/barcode capture. Try it for 30 days with included support.
A Handful of Beans
The startup Juan worked for was going through a growth spurt. There was more work than there were people, and plenty of money, so that meant interviews. Lots, and lots of interviews.Enter Octavio. Octavio had an impressive resume, had worked for decades as a consultant, and was the project lead on an open source project called “JavaBachata”. Before the interview, Juan gave the project site a quick skim, and it looked like one of those end-to-end ORM/MVC frameworks.Juan planned to bring it up during the interview, but Octavio beat him to the punch. “You’ve probably heard of me, and my project,” he said right after shaking hands. “JavaBachata is the fastest Java framework out there. I use it on all my projects, and my customers have been very happy.”“Ah… we already have a framework,” Juan said, uncertain if this was an interview or a sales-pitch.“Oh, I know, I know. But if you’re looking for my skills, that’s the place to look. It’s open source.”While Juan pulled up the GitHub page, Octavio touted the framework’s strength. “I was doing no SQL before NoSQL was a thing,” he said. “All of our queries are executed in-memory, using TableBeans. That’s what makes it so fast.”Juan decided to start looking in the TableBean class, since Octavio brought it up. The bulk of the class looked like this:
CodeSOD: The Delivery Moose
We know stereotypes are poor placeholders for reality. Still, if we name a few nations, there are certain traits and themes that come to mind. Americans are fat, loud, gregarious, and love making pointless smalltalk. The English are reserved, love tea, and have perfected the art of queuing. The French are snobbish, the Japanese have weaponized politeness, the Finns won’t stand within ten meters of another human being at the bus stop, and so on. They can range from harmless to downright offensive and demeaning.Laurent is Canadian, working for an insurance company. Their software is Russian- in that it comes from a Russian vendor, with a support contract that gives them access to a Russian dev team to make changes. While reviewing commits, Laurent found one simply labeled: “Fix some Sonars issue”.The change?
Classic WTF: The Shadow over ShipPoint
Editor's Soapbox: Give Thanks for Well Routed Packets
It’s Thanksgiving here in the US, so we’re taking a long weekend. In lieu of a more traditional “from the archives” post, I’m going to give thanks.You know what I’m thankful for? I’m thankful that data packets on the Internet are routed and handled the same way, regardless of which network originated them, nor which network is their destination, nor what they may contain. You could say that networks are… neutral about packets.A few years ago, the FCC enshrined this common sense into its regulatory framework. We were all pretty happy about it, and were optimistic that it was done. Unfortunately, it’s never over, and the new management at the FCC wants to reverse that, and plans to vote about it in a few weeks.Remember: prior to making Network Neutrality the regulated standard, network operators largely (but not completely) followed the rule anyway. Network Neutrality was the default, and then the bean-counters recognized an unexploited revenue stream (why should Netflix get to send data to our customers without paying us for the privilege?). The Internet worked under Network Neutrality, and the FCC only needed to enforce it by rule because network operators wanted to change the playing field.In any case, if you’re thankful for an Internet that works, between gorging yourself in typical American fashion and arguing with your racist uncle, take a few minutes to do something about network neutrality.I’d be ever so thankful if you did.[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
CodeSOD: Arrject
There are some submissions that we get, and we simply sit on, because there’s nothing much to say about them. They’re awful code, but there’s no major comments to be added. It’s clear and simple in its awfulness.For example, you have some code that needs to display details about colleges around the US. Each College has a name, a full name, a short name, a state and city where it exists, and full names for those states and cities. You are likely reaching for an object to store that information, but why do that, when you can employ what I call the “Arrject Pattern”. Y’know, when instead of using objects, you use multiple arrays and store related data at the same index? Stuff like what Kevin found in his codebase:
Jumped The Gun
Sheldon was a support engineer at Generic Media Co. In his 6 years with the company, he'd enjoyed working for several great managers—but then came the reorg. Once the dust cleared, he found himself in the wrong department, reporting to one of the most loathed individuals in the entire organization.Gene was the type of manager who believed his fancy title awarded him instant respect. No engineer who spent any time working with him had anything good to say. Sheldon went in hoping for the best ... but Gene's relentless micromanaging and childish stunts quickly ground Sheldon's optimism into dust. When it came time for Sheldon to go on an extended vacation, he felt like a shell-shocked veteran limping out of the trenches.The months away were bliss, but Sheldon couldn't enjoy the last few days out of dread. To his surprise, though, Gene wasn't waiting at his cubicle with twelve urgent tasks upon his return. There hadn't been a peep from Gene all vacation long: no emails, no meeting requests. It was getting close to performance review time; nothing about that, either.As Sheldon worked through his vacation backlong, it became starkly apparent that he was being allowed to work through his vacation backlog. No panicky IMs, emails, cubicle pop-ins. The radio silence extended into days, then weeks. Sheldon began to wonder whether Gene even still worked there. Not wanting to kick a potential sleeping dragon in the nose, he asked his coworkers instead."Of course he's still here," one of them grumbled. "If they haven't canned him by now, they're not going to."Soon after, Sheldon found out he had it exactly backwards.A meeting invitation from Gene landed in his inbox. Catch-up meeting, tomorrow. No agenda, no room booked. Distracted with work, Sheldon didn't immediately accept the meeting. By the end of the day, his desk phone rang.Gene. When had Gene ever phoned his desk? Frowning, Sheldon picked up."I need you to accept the invite," Gene blurted with no preamble. It was then that Sheldon's paranoia clued him into reality. Gene still works here. I'm the one who's out. Gene's extended avoidance had been just another of his immature games. They'd never even done that performance review, had they?"I'll be there," Sheldon muttered.All that night, Sheldon tried to put a positive spin on the situation. A job he'd enjoyed had been ruined by a terrible manager, it was true. But he'd soon be free to look for a better job and a better manager.Sure enough, once the meeting began, Gene smugly informed Sheldon that his role was going offshore, making him redundant. (Sheldon later found out that the offshore bit was a lie, but you didn't hear it from us.) Sheldon hoped this would be the last of their interaction, but it wasn't to be.Fast-forward to Sheldon's second-to-last day, 4:00 PM. Sheldon was leaving to pick up his kids from school. He was on a tight schedule, as he had a train to catch. He hurried to the lobby, summoned an elevator, and darted in.Just as he turned around, he spied Gene entering the lobby from the stairwell. Gene saw Sheldon as well, and flashed him a big smile.Not to be cowed, Sheldon smiled right back.Gene frowned, confused. "Do you have a minute?""No," Sheldon answered honestly as the elevator doors began to close."I need to collect your badge!" Gene yelled.The doors shut, and the elevator began its descent. You're a day early, Sheldon thought to himself, shaking his head.He made it to his train and boarded just in time. While shuttling along, he grabbed his phone and sent Gene a quick message via Google Hangouts. I'll be in tomorrow. You can have my badge then.The message seemed to have trouble going through. A few moments later, the Hangout closed. You have been successfully logged out.Strange. Sheldon switched to Slack. You have successfully signed out."What?" Sheldon blurted aloud.It got him thinking. Gene had just seen him leaving the building in a hurry, grinning like a fool. Did he think Sheldon had planted a bomb or something? Sheldon had no bombs, but he did have admin access to plenty of important systems. Had Gene gotten his account terminated in a panic?Sheldon called the IT department and confirmed his suspicions. There was even a note attached to his account, from Gene: DO NOT RE-ENABLE."What am I supposed to do for my last day?" Sheldon asked."No worries," the tech replied. "I'll roll it back."Upon returning the next day, Sheldon learned his security badge didn't work, either. The security guard at the front desk had to call Gene for authorization. Still too much of a wimp to show his face, Gene just told him to let Sheldon through."He couldn't even get my last day right," Sheldon said with a chuckle.Gene kept his distance whole day. Sheldon left at 4:00 PM again, this time headed for the whiskey bar with a few ex-colleagues to celebrate freedom. [Advertisement] Universal Package Manager - ProGet easily integrates with your favorite Continuous Integration and Build Tools, acting as the central hub to all your essential components. Learn more today!
CodeSOD: The Generated JavaScript
Once upon a time, I discovered a bug in some JavaScript. I went off to investigate the source, only to find… the JS wasn’t coming from a file. It was being generated by a server-side method. Through string concatenation. It was a simple generation, something along the lines of:
Error'd: Never ASSume that You're Free from Errors
"This was in an email from Nest. I'm sure in some other font this shows a heartwarming image of fluffy bunnies frolicking in an energy saving Utopia, but instead, we get this," wrote Matthew W.
CodeSOD: Delebation
When faced with an API or programming paradigm that requires repetitive, boilerplate code, a developer is left with two options. They may refine or adapt the API/paradigm, using the idioms of their language to make something tedious and verbose into something elegant and clear.Or they just automate it. If you have a mile of boilerplate that’s mostly the same across the application, just generate that. It’s like copy/paste, but, y’know… automatic.Which is why Derf Skren found this pile in their codebase:
The For While Loop
Alex R. was the architect of a brand spanking new system that was to read inputs from numerous other internal systems, crunch a whole bunch of numbers, record everything in a database and spew forth a massive report file. He spent months designing the major details of the system, and more months designing the various sub-components. From all this came a variety of business-level data structures which spawned POJOs and the underlying DB tables to store assorted inputs, flags and outputs. He did a fairly thorough job of documenting all the interfaces, and provided detailed specifications for all of the next-level methods that were left as TBDs in the design.The project manager then assigned units of work to numerous offshored junior developers who managed to get virtually everything wrong. If they couldn't understand what a spec required, they changed the spec to reflect what they actually wrote. This caused Alex to start versioning the requirements document in order to catch the changes by the junior developers so that they could be rolled back.After a while, the number of junior-developer-caused issues was piling up and Alex suggested some training sessions on certain ways of doing things to reduce the chaff he had to deal with. Management turned him down because they couldn't afford to take developers off of coding tasks for purposes of training; there was a schedule to keep! The fact that oodles of time were being wasted on them building the wrong stuff only to have to have why it was wrong explained and then have them go back and re-do it - sometimes 6 or 7 times - was irrelevant.So how does one deal with idiotic management like this?Alex thought that he had found a way to expose the problem and (hopefully) force something to be done. He would put in something (that any experienced developer should be able to spot as a simple code formatting issue) that the junior developers would never spot. The code would work correctly, but it would stymie them so that they had to first understand it before they could change it. He used the following coding style in a variety of locations throughout the codebase and waited:
CodeSOD: One's Company
The more you learn about something, the less confident you often become in making statements about it, because you understand the complexities of the matter. If, for example, I asked you to help me refine my definition of how dates and times work, you know that many assumptions are wrong. Or if we tried to define what makes a string a person’s name, we’ll run into similar problems. This is even true for a value we’ve all probably seen implemented as a boolean value: gender. The more you learn about these subjects, the more complex and nuanced your understanding of them becomes. More and more, your answers start with, “It’s complicated…”.Eugene was going through some code at a customer’s site, and he found that their business logic depended heavily on a flag ISCOMAPNY (sic), but there was no ISCOMPANY field anywhere in the database. There was, however, a SEX field on the customer records, implemented as an integer.Digging through the queries, Eugene found a new approach to defining a company:
Representative Line: An Exceptional Contract
The life of a contractor can be precarious. Contracts end- sometimes suddenly, and you rarely know what the organization you’re working for is actually like until it’s too late.Ian S, for example, was contracting for a platform-as-a-service (PAAS) company, adding new features to their existing infrastructure automation system. It was the kind of place that had two copies of the same code-base, maintained side-by-side, just so that a single customer could use a script they’d written eight years prior.That wasn’t too much of a challenge. The real challenge was that when things went wrong, there was almost no logging, and what little logging they got contained helpful, “[10:14:17] An error occurred” messages.It wasn’t hard to see why that happened:
Error'd: It Doesn't Mean What You Think it Means
"TRWTF here is I can't believe they shorted me on my change!" writes Diane B.
Theory Versus Reality
I went to college at the State University of New York at Albany, where back then, most of the Computer Science curriculum courses were entitled Theory of xxx. The programming assignments were the usual small-scope demonstrations of some feature of programming, typically something an experienced developer would code in 15-20 LOC.My Masters project was to modify the TeX typesetting system (by Knuth) to leverage the more advanced features of a new typesetting system. It took me about two months to reverse engineer it only to find that the entire required modification amounted to a single character change.The theory sunk in, but there was no practical application of it to reality.Fast forward to my first programming job, where one of my tasks was to write a stand alone program that would read connection names from a file, verify that they were valid, and use them for something. There were about 350 different connection names, but they didn't follow any discernible pattern. There were a variety of letters and numbers in no particular ordering. However, there was a lot of substring duplication within the names.Being a clueless but diligent noob, it dawned on me that I could leverage those semi-duplications so I wrote a huge progressive if-then-else statement to determine whether a name was valid.For example, the list contained names like:
CodeSOD: Lowest-Bidder Conversion
Circa 2003, or so, Annie’s employer contracted a lowest-bidder to produce a relatively massive .NET Web Forms project. The code was built, signed off, and chucked into production without any of the in-house developers being involved, despite being the team that would support it in the long term. There was no documentation, no knowledge transfer, and no code review.Over the next few years, there was a rush of feature requests as gaps in functionality were found. A series of in-house developers passed through, doing their best to patch them in, but the original project’s code quality didn’t exactly make it maintainable, and since they were operating in a rush, they weren’t exactly improving the code quality.Fast forward to 2017, and the code is finally unmaintainable enough that someone put together the budget for a ground-up rewrite in .NET MVC, and once again shopped it around to a different lowest-bidder, who would do the conversion. This time, at least, Annie gets to review the code before they accept it. It isn’t going well.
Replacement Trainwreck
There's an old saying about experience in IT: Some people have 10 years of experience, and some have 1 year 10 times. Every day, someone learns the hard way how true this statement really is.Raquel returned from holiday, only to get a call from above saying her contract would not be renewed, giving her 2 weeks' notice to find a new placement. The boss explained it was a budget thing, since contractors are often more expensive than salaried employees, especially ones working remotely in the Asia-Pacific region. C'est la vie.Raquel's big project was a perl module to talk to a high-end but aging storage system. The hardware had no API, and the CLI was arcane, with wildly inconsistent formats in the command output. Raquel abstracted that all away to give a programmatic interface for the other developers. The downside of this approach was that every time they put out a firmware update, she had to modify the perl script to match the changes. The module had grown to 1600 lines of code through 400+ commits in the 3 years she'd been working there. The other developers would include this as a git submodule so they could pull in changes in an automated way and re-release their tooling.Raquel was asked to hand off the module to John, who assured her he knew git really well and enough perl to figure things out. It seemed reasonable ... at first. She got John set up with another, smaller tool she'd written: a plugin for a popular monitoring system to read the storage drives. It used the library she'd written as a backend, so she figured it'd give him some understanding of the functionality. Since some of their customers used Windows, she taught him how to compile to an executable. Once John was compiled and running, Raquel sent him to their lab environment to test the plugin.A few hours later, she got her first bit of bad news: the plugin was failing, and John didn't know why. He attached the error message:
CodeSOD: The Distract Factory Pattern
The Gang-of-Four design patterns have an entire category of creational patterns, to handle the complexities of creating objects. And yes, it can get complicated, especially when we think in terms of the single-responsibility principle. Often, creating an instance of an class is itself so complex that we need a new class to do it.Thus, we have the Factory pattern. And the Abstract Factory Pattern. And the Abstract Factory Factory Abstract Provider Bean pattern, if you’re using Spring. The purpose of these patterns is to add indirection between the client, calling code, and the creation of the objects- different concrete implementations can be instantiated, without the client code needing to worry about what actual type it received. Polymorphism wins the day. Code is more loosely coupled, because the client code never needs to name the concrete type it uses.Unless you want to do it wrong, in which case Jen M found this particular solution:
Error'd: Going for the Gold!
"Starting from one star, I'm almost at that gold five-star rating," writes Sam K.
CodeSOD: Switching the Search
We return to Virginia N’s refactoring efforts (previously: here, and here).This code is elegant in its stupidity, combining two anti-patterns in one glorious, “No, don’t do that, whyyyyyyyyyy!”. To wit, the for-switch, and the “build SQL statements through string concatenation”:
CodeSOD: An Academic Consideration
Becky is not a programmer, but a physicist. She works in academia, alongside other scientists. Modern science generally requires some sort of heavy computation, which means scientists write code. It’s often not very good code, but that’s just the nature of the beast. The code exists to provide an analysis, not to be deployed as an app to the masses.Most of the time. A few civil engineers were working on a brand new Android app for traffic analysis, with plans to distribute it. Unfortunately, they had some problems, and wanted more experienced eyes. Becky set aside the Fortran77 she was working on to trace through their Java code, and found this:
With the Router, In the Conference Room
This is a follow-up to With the Router, In the Conference Room, revealing the… STUNNING CONCLUSION!How It Really EndedDarren took the case up to his boss, and then to their boss, up the management chain. No one was particularly happy with Cathy’s tone, and there was a great deal of tut-tutting and finger-wagging about professional conduct.But she was right. It was Mr. Green who failed to follow instructions, it was Mr. Green who cost the company thousands, along with the customer relationship problems caused by Cathy’s sudden emergency trip back to the home office.In what can only be considered a twist ending by the standards of this site, it was Mr. Green who was escorted out of the building by security.The killer was Cathy, in the issue tracking system, with the snarky bug report. [Advertisement] Universal Package Manager – store all your Maven, NuGet, Chocolatey, npm, Bower, TFS, TeamCity, Jenkins packages in one central location. Learn more today!
With the Router, In the Conference Room
One of the most important aspects of software QA is establishing a good working relationship with developers. If you want to get them to take your bug reports seriously, you have to approach them with the right attitude. If your bugs imply that their work is shoddy, they are likely to fight back on anything you submit. If you continuously submit trivial “bugs”, they will probably be returned right away with a “not an issue” or “works as designed” status. If you treat any bug like it’s a critical showstopper, they will think you’re crying wolf and not immediately jump on issues that actually are critical.Then there’s people like Mr. Green, a former coworker of submitter Darren A., that give QA a bad name. The Mr. Greens of the QA world are so incompetent that their stupidity can cause project delays, rack up thousands of dollars in support costs, and cause a crapstorm between managers. Mr. Green once ran afoul of Darren’s subordinate Cathy, lead developer on the project Mr. Green was testing.Cathy was en route to the United States from London for a customer visit when her phone exploded with voicemail notifications immediately upon disabling airplane mode. There were messages from Darren, Mr. Green, and anyone else remotely involved with the project. It seemed there was a crippling issue with the latest build that was preventing any further testing during an already tight timeline.Instead of trying to determine the cause, Mr. Green just told everyone “Cathy must have checked something in without telling us.” The situation was dire enough that Cathy, lacking the ability to remotely debug anything, had to immediately return to London. Mr. Green submitted a critical bug report and waited for her to cross the Atlantic.What happened next is perfectly preserved in the following actual bug report from this incident. Some developers are known for their rude and/or snarky responses to bug reports that offend them. What Cathy did here takes that above and beyond to a legendary level.
CodeSOD: Drain the Swamp
You may remember Virginia N from An Extinction Event, where she struggles to refactor a legacy project with some… unusual design principles. ReSharper still continues to choke to death on their codebase, but her management has let her know, this won’t be a problem going forward.“You see,” her boss explained, “we’re going to move the logic into stored procedures. That way, we can more easily re-use the logic between the Windows Forms client and the Web app.”“Oh, there’s going to be a web app, now?” Virginia asked.“Yes! They’re going to use best practices, like unit testing, so that they don’t end up with the same kind of mess we have,” her boss said.Virginia was halfway to filing a request for a transfer when she heard more about the web project. Then she heard about their plan. They weren’t going to simply build a web-client for their backend, but instead were going to build an inner platform. The page logic would be a simple template, and all of the rules, styling, data and display logic would be stored as data in the database. “It’s gonna be really flexible!”Virginia decided to stick with the fetid field she knew, instead of the “green field” which was going to be a fetid swamp in a matter of weeks.In Virginia’s swamp, she has many, many 40,000 line classes. That much code means the code has no real cohesion, so it leads to Virginia finding variables named thus:
Error'd: Trick or Treat? Smell My Feet
"Sorry, but 4.2 billion Microsoft points sounds like 'all tricks' to me," writes Ergin S.
CodeSOD: 10001 Problems
Our Anonymous submitter's first job was helping to support a distributed system running in a low-energy embedded platform. Interesting on its face, the platform was actually a bloated, outdated monstrosity made worse by the decision to use C++ in conjunction with a homemade (read: unsafe) binary data format.The platform had one mysterious, catastrophic flaw in particular: once a cluster was up and running for a few weeks, it would sometimes fail with a series of random segfaults, with several nodes crashing at once. Serial port debugging showed that many of these failures were proceeded by an ominous log message, a single line with the number 10001 and nothing else.After pondering the mystery for some time, someone thought to search for the number 10000 within the code base. Thus they found their culprit within the very core of their application: the code that read each record stored in their homemade binary files and copied it to memory.
Re-Authenticated
Sometime back, our friend Fred told us about his experiences with homegrown PK/FK relationships. Today, he regales us with a tale of trying to get users to use their new-and-improved sso mechanism, even if they don't want to.His company currently runs a legacy reporting portal service that has an old-school sso which is used by several third party systems. This mechanism stores user names and passwords as clear text in the DB. It also passes them in clear text in a hidden HTML form. The third party code would create the hidden form with the user name and password in clear text and JavaScript-submit it to the login page - without HTTPS. OK, it was the way things were set up way back then.Nowadays, his employer knows better and has created a new and improved system with slightly more sophisticated security. They encourage their end users to make the switch and use the shiny new platform. Unfortunately, the third party systems still have hard-coded embedded links to the old system, and although switching to use the new system would improve security, the users are in no rush to make changes to their software.When you have lemons, make lemonade.Fred was unwilling to succumb to the laissez-faire attitude of lazy customers, and so wrote a URL-rewrite rule for the IIS server that was running their old VB6-era system. It redirected posts to login.asp to /hijack/login.aspx. The new page contains logic to check if the user is configured on the new platform. This magic was accomplished by using the 307 Temporary Redirect, which maintains the POSTed payload; something which is not done by a standard 302 (perhaps this is a Dark Secretâ„¢ of IIS - who can say?) If the user was found in the new application, an access token was fetched from IdentityServer3 and the incoming user was redirected to the new platform. Otherwise, /hijack/login.aspx output the same old fool-proof hidden HTML form with clear text user name and password and JavaScript-submitted it - without SSL - to the renamed login2.asp page of the old system.Upon pondering his creation, Fred winced at the plethora of Biblical-Level WTF in this set up, but in some curious way the solution is kind of cool and he thought the world should know about it.[Advertisement] Release!is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
CodeSOD: The Key to Lookups
After some “miscommunications about coding standards”, Nicolas’s company decided that they should have one of their internal developers do code reviews on anything that came from their external, third-party developers. Nicolas drew the short straw on the most recent project.The specific problem in play is that they had config-data, structured as nested dictionaries. You know the kind of data-structure- something like:
Representative Line: Secure Login
“I logged into the admin app.”Julie’s boss had the username and password for the admin app, so that wasn’t too surprising.“With my regular username and password,” her boss added.That was a bit more of a problem. The app in question was an internal, home-grown CMS. The admin portion of it was secured by a single username/password combo, controlled by a config file. It wasn’t the most secure thing on Earth, but it should at least be secure enough that you needed to supply the correct values.Julie checked the code, and found that wasn’t the case:
Error'd: Legitimate Links
"Swedish...Russian...English....same difference!" wrote Fred.
CodeSOD: Abstract Test Case
A great many breakfast cereals promise some sort of health benefit. This brand is good for your heart, that brand has 11 essential vitamins and minerals. This one’s got bran! Just because there’s a promise of health benefits doesn’t mean they actually exist- most of these cereals are lightly fluffed sugar held together with a smidge of starch.Object-oriented languages promise a lot of code-health benefits, and used properly, they can certainly deliver. In this somewhat tortured metaphor, the Lucky Charms marshmallow of OO features is Inheritance. It’s tasty, it’s easy to explain, but it’s not really good for your code. A little bit, here-and-there, from time-to-time is great. But some folks buy the three pound bag and that’s just not good for anybody.Daniel took over some code left behind by a retiring co-worker. The code was seeded through with abstract classes- though, because this was Python, “abstract” was more of a convention than a statement of fact. This predecessor took abstraction to its “logical” conclusion, and when testing abstract classes, they wrote abstract tests:
The Official Software
At the very beginning of my career, I was a junior programmer on a team that developed software to control an electronics test station, used to diagnose problems with assorted components of jet fighters. Part of my job was the requisite grunt work of doing the build, which entailed a compile-script, and the very manual procedure of putting all the necessary stuff onto a boot-loader tape to be used to build the 24 inch distribution disk arrays.sourceThis procedure ran painfully slowly; it took about 11 hours to dump a little more than 2 MB from the tape onto the target disk, and nobody could tell me why. All they knew was that the official software had to be used to load the bootstrap routine, and then the file dumps.After killing 11 hour days with the machine for several months, I had had it; I didn't get my MS to babysit some machine. I tracked down the source to the boot loader software, learned the assembly language in which it was written and slogged through it to find the problem.The cause was that it was checking for 13 devices that could theoretically be hooked up to the system, only one of which could actually be plugged in at any given time. The remaining checks simply timed out. Compounding that was the code that copied the files from the tape to the disk. It was your basic poorly written file copy routine that we all learn not to do in CS-102:
CodeSOD: Too Salty
The first rule of building your own password storage mechanisms is don’t. Like most other highly-specialized wheels, you aren’t going to do as good a job as someone who specializes in it. It’s bad enough when you write your own date mangling code, but for security-critical features, like passwords or encryption, you’re begging for trouble.Joni spotted some trouble: many of the users in the database had the same password hash. This, of course, should never happen- the password should be combined with a user-specific salt as part of the hashing, so that even if two users had the same password, they’d have different hashes.Joni investigated, and found the code used:
CodeSOD: RAM On Through
The company Tomasz worked for launched a new device line with more RAM than the previous generation. This was supposed to put an end to the sort of memory shortages common to embedded systems. However, it wasn't long before they began hearing from clients whose systems crashed whenever they attempted to upgrade the accompanying software package.The initial reports were met with surprise and skepticism, but the investigation soon led Tomasz and his cohorts to—you guessed it—a reproducible out-of-memory error.With RAM not an issue, they took a deeper look at the upgrade process itself. The 50MB upgrade package was supposed to be copied to a special directory so the OS could install it. In C++ on linux, this is a simple task. You could use splice() on a newer linux kernel, or sendfile() on an older one. You could also read and write one buffer at a time. Inefficient, but effective.As you may already suspect, the developers who'd written the library for handling upgrades had taken a more brillant approach, shown below. readFile() stores the entire file in a string in memory, and writeFile() places it in the desired directory. With this implementation, any device could be brought to its knees with a large-enough upgrade file.
Error'd: Nothing Ventured, Nothing Gained
"After trying to close my steam support ticket, I got this," writes Joe, "Now, I'm not entirely sure."
Representative Line: Refactoring the Conditional
Virginia N was trying to refactor some code, and that meant understanding where the value m_PSOC_SIG was used, and why. So, she did some searching, and found this line, which doesn’t contain our value:
...38394041424344454647...