Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2025-07-15 22:30
Enterprising Messages
Percy's employer is an "enterprise vendor". They have a variety of products all within the "enterprise" space. Like most enterprise products, they're sold on the strength of the marketing team's ability to claim with a straight face that they're secure, robust, reliable, and performant.While the company offered a "cloud" solution for their enterprise suite, the real money was in the on premises version. With on-prem, any updates or upgrades were almost guaranteed to break the entire environment unless the customer shoveled huge piles of cash at the company to get a specialist to come out and do the upgrades.That was good for the company, but wasn't so great for the specialists. Simple patches could take weeks to perform, not because of any trickiness or difficulty, but because each upgrade step could take days to run.Percy found out about this when sitting in on a project review meeting."For our instant messaging engine," one of his peers, Elizabeth, explained, "just handling the room policy records can take upwards of ten hours at some sites. That's one SQL statement. God forbid the transaction fails for some reason.""How could it be that bad? How many records is it?" Percy asked."Only about 100,000. The problem is the way the data is structured." Elizabeth pulled up the schema.As an enterprise product, the messaging system prizes configurability and customizability over utility, performance, and common sense. It's not designed to solve a problem, but instead to allow customers to solve problems they didn't know they even had, mostly by inventing them. As a messaging/chat system, they had a concept of "rooms", and the "rooms" could have every aspect about them customized. From how usernames display in the chat, to whether files can be sent, to even whether or not copy-paste is permitted. Of course, the same interface which configured those cosmetic flags also configured role-based permissions, transport layer settings, and whether the messages were compressed before sending to the server.And with each version of the product, the specific set of fields could change.Those of you who work in RDBMSes are likely imagining a vast field of relations bound together by foreign keys and indexed to optimize likely query paths. Those of you who are more on the NoSQL side of things are likely imagining a sparse JSON/BSON document, possibly a heavily denormalized representation of the dataset.Those of you who know enterprise products, or who have read this site before, know what it actually was: gigantic XML documents stored as CLOBs in the database. To add insult to injury, they used SQL Server on the backend, which has had a native XML type with optimized query operations since the mid-2000s.Percy pulled up the schema on his own machine to explore it. At the center of the schema was a ChatRoomPolicy table. This table had three fields- a PolicyId and the RoomPolicy, which was the main gigantic XML document. In addition to that XML pile, you also had a Visibility column, which contained an XML document which contained ChatRoomVisibility elements- essentially little things, like whether attempting to send a message included a "Cancel" button, or if users could see a "Mute" button to silence the notifications.Then, of course, you had the ChatRoom table, which had a foreign key reference to the policy which controlled the chat room."So, yeah, when we do an upgrade which alters the schema of the RoomPolicy documents," Elizabeth explained, "we have to read every row, parse the XML in our upgrade script, generate the new XML, and then store it. That's if the XML changes- sometimes an upgrade only renames one key, and not every document contains that key."Percy had seen some pretty horrible things in his section of the product, but nothing quite like this. "Well, at least you can just map the XML document to a class, and mostly automate the changes, right?"Elizabeth laughed at him. "If we did that, then our customers couldn't make up their own XML keys, and then add their own procedures in our proprietary scripting language which reads them, and then I wouldn't constantly get tickets because some PM at a three-branch bank in East Pilsbury decided they wanted a new field in their chatroom and it happens to collide with one of the fields we already use."More specifically, the XML didn't have an associated schema. The upgrade script had to be able to handle any arbitrary XML document, identify the parts that the script cared about, if they existed, modify them, if necessary, hopefully without breaking anything the customer had customized, and then actually do the update.The resulting upgrades could, on a good day, get about 3 records processed every second. With some organizations, the pile of policies applied to chat rooms could extend into the hundreds of thousands (as "private chats" also counted as chat rooms and had policy documents attached). Thus, ten hours just to upgrade a single module of a single service in their enterprise software portfolio. And that's just the upgrade task."Wow, I can't imagine how long testing must take," Percy said.Elizabeth laughed, again. "That's up to the client to schedule. They usually don't." [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Success Despite Management
In our industry, we all know that managers cause problems when they try to, well, manage. This invariably causes us to get frustrated. Sometimes when we rebel and try to force them to do the right thing, we are the ones that pay for it with our jobs. Sometimes, they get impatient at our mortal lack of $Deity-level skills to make the magic happen fast enough for them, and we pay for that with our jobs as well.Occasionally, even though it seems as though managers never pay for their mistakes, Codethulu smiles upon us and gives us a glimpse of a Utopian world...Back in the mid 1990s, Dennis worked for privately-held Web Accessible Network Kernal, Inc. (WANKCO), a small manufacturer of large automated network test equipment. WANKCO had a couple dozen employees and had not yet developed any big-company policies. Specifically, they did not have the one where you have to use your vacation time or else lose most of it at the end of the fiscal year.Dennis was very busy as the lead engineer for a very important and very late product that was forecast to make bundles of money for WANKCO. He had been working evenings and weekends designing hardware and firmware and hadn't had a vacation for well over a year. He had lots of vacation time accrued and planned to take a nice long trip after the product was released and seen through its inevitable birthing pains.One day, WANKCO was purchased by publicly-held Initech. WANKCO quickly inherited a small herd of PHBs, and the alpha PHB informed the minions that, among other PHB things: 1) Vacation carryovers at the end of the fiscal year would be capped according to Initech policy, and 2) Dennis's project was a Critical Corporate Priority and must be finished at the earliest possible date or dire consequences would result for the non-pointy-haired among them. Development staff were to be put on a mandatory fifty-hour work week until the project was complete. A sign-in sheet was provided so they could log their arrival and quitting times each day. Several of the developers happily complied by cutting their work week down to the mandated fifty hours. Apparently, pointiness keeps some people from picking up on the obvious.The end of the fiscal year was already near when these announcements were made, and the Critical Corporate Priority was within mere weeks of completion. Dennis asked the PHBs for a one-time exception to the vacation carryover policy so that he could see the project across the finish line without sacrificing most of his accrued vacation time. They refused. Thus, with PHB-blessings, Dennis took off on a five-week vacation. With nobody else being qualified to take over his part of the work, the Critical Corporate Priority was delayed by another five weeks. The PHBs couldn't understand why the mandated fifty-hour work weeks did not advance the completion date by a single minute, although Dennis was sure that it made the PHBs appear more pointy than usual.In spite of finger pointing, insinuating emails and general PHB-isms, Initech and its WANKCO subsidiary survived the delay and the product was eventually shipped.A parade of PHBs regularly cycled through WANKCO on rotation. After ten years and several changes of ownership, WANKCO went private again. In the process the PHBs were jettisoned, illustrating that not all tales of managerial WTF have an unhappy ending.Sometimes you just have to wait 'em out. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
Error'd: Investigation of Satisfaction
"There are premium translation services, and then, well, there are the rest," Dave P. writes.
CodeSOD: For a Long While
Here’s a philosophical question. Let’s say you’re searching an array. Is it clearer to use a for loop and break when you find the element, or is it better to use a while loop and break if you hit the end of the array?Most of us would likely use the for loop, but it wouldn’t be wrong to use the while- maybe just unexpected.But what if you had forgotten that while loops even exist? An anonymous submitter found this, and distilled its essence for us:
Paper (Size), Please
Terje worked for an IT firm that serviced the purchasing department of a global corporation. To manage purchases, the department used an enterprise shipping and warehousing system that shall be called BLA to protect the guilty. The system ran on a Citrix farm in Norway with all the most impressive resources at its command.Just after a major upgrade of BLA, sporadic performance issues began cropping up in the Brazil and Perth offices. When users tried to generate new reports, BLA would hang for several minutes. In Norway, Terje and his colleagues couldn't reproduce the problem. They went through every reasonable troubleshooting step, but failed to isolate the root cause of the issue. The vendor of BLA, also based in Norway, couldn't duplicate the issue, either. Months passed with no resolution in sight.Lest one should think that everything was sunshine and roses in Norway, the users there ran into their share of quirky issues as well. A common one was the "Printer not found" error message when a user tried to generate a report. Usually, this happened whenever a user removed or inserted their laptop into a docking station while logged into BLA. Simply rebooting Windows while the laptop was docked fixed the issue. The vendor explained that BLA had to have a default printer set within the local Windows environment so it could find out how big a piece of A4 paper was. This would ensure that BLA would always use the correct paper size for reports. This behavior seemed odd to Terje, but he kept it in mind.One day, when he was fielding yet another performance issue from Brazil, the above tidbit occurred to Terje and bestowed a spark of inspiration."Try this for me," he told the user on the phone, sitting up straighter in his chair. "Log out of Citrix, then set your default printer to a PDF creator.""What?" the user asked. "What does that have to do with anything?""I know it sounds weird, but can you just give it a try?" Terje pleaded. "If it doesn't help, you can change the setting right back.""OK ..." the user replied, skeptical.Sure enough, once the user made the change and logged back in to Citrix, he was able to generate a report almost instantly."How did that work?!" he asked."You're connecting to our Citrix server in Norway, opening BLA, and attempting to generate a report," Terje replied. "When you do that, BLA goes, 'How big is size A4 paper? I'd better ask the default printer.' In your case, the default printer was pointing to a device in your office in Brazil. So BLA was connecting from Norway to that printer halfway around the world, and was waiting for it to tell it how big A4 is. That's why everything was so slow!" Terje slapped a hand against his desk in triumph."How odd!" the user said. "I'm glad it works now, though!"Terje was even happier to have cracked that enduring mystery. He got to work assembling a knowledge base document and compiling the evidence needed to file a change request with BLA's vendor. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
It's a Little Stale
Megan K’s organization does the sane and reasonable thing: they cache all of their dependencies locally, and their CI/CD process pulls from the local cache. Since they’re in the Python world, this means pulling from PyPI using Bandersnatch.Someone set up the Bandersnatch job. Someone linked it into their CI/CD process. No one wanted to claim credit when it started failing. Every five minutes, Bandersnatch tried to contact PyPI. Every five minutes, it got a StalePage error, specifically complaining about a “stale serial”, and sent an alert email to the entire dev team. Every five minutes, the entire dev team ignored the error. For ten days.The office turned into a tense standoff. No one wanted to talk about the errors, since the first one to bring it up was going to be the one who had to fix it. Each day could be underscored by Ennio Morricone.Megan caved first. Instead of using rules to filter her inbox, she manually deleted each message. Eventually, sick of getting spammed, she did some research, and shared her findings with the developers.Megan started where anyone would start debugging HTTP requests: with curl. The curled the failing URL, first from her machine, and when that worked, from the Bandersnatch machine. That also worked. Even as a Python script, running on the same machine, sending a very similar request, failed.Megan fired up a Python REPL and imported the requests library, which is used for sending HTTP requests. She sent a request, and that failed. curl always got a fresh serial, requests always got a stale serial. Obviously, there was something different about the requests.Megan checked the headers, and found two key differences: the User-Agent and the Accept-Encoding headers. Thinking the obvious, she tried setting curl to use the same User-Agent as requests- and it kept working. Changing the User-Agent in requests didn’t fix the problem.But changing the Accept-Encoding did. If Megan sent a request with Accept-Encoding: gzip, deflate, the PyPI loadbalancer routed her to a stale cache server, every time. Accept-Encoding: '', on the other hand, always got a fresh server. By default, requests used gzip, deflate. Bandersnatch, in turn, used the default settings for requests.That of course, wasn’t enough. Eventually, the cache server that Bandersnatch was getting routed to would also become stale, so Megan had to add an arbitrary (and highly variable) parameter to her requests- specifically, a URL parameter called cache-bust which was always set to the current timestamp.An issue was raised with PyPI, which is still open at the time of this writing. Obviously, it’s some simple misconfiguration in the load balancing and caching, or perhaps an intentional configuration based on bad assumptions, but the moral of the story: Megan was glad they were caching all of their dependencies locally, just in case PyPI ever went really wrong. [Advertisement] Ensure your software is built only once and then deployed consistently across environments, by packaging your applications and components. Learn how today!
CodeSOD: A Tern at the Build Process
Justin Self inherited an internal build tool. Rome may not have been built in a day, but this tool was. It “simplifies” provisioning development environments, claiming machines in the environment for certain tasks, and so on.
Error'd: We Need a Windows Install CD in Aisle 7
"Encountered this one while attempting to weigh some vegetables and well...the scale crashed?" writes Sam.
Representative Line: Created Equal
Let's say you have an enum. You have an array of objects, where one of the fields is of that enum type. You want to filter the array of objects where the value of the enum is PAYMENTMETHOD.You also hate equals signs.Jacqueline found IntelliJ screaming out a litany of warnings, and while tracking down the reasons, she found this bit of Java:
The Hardcode to Success
Rodrigo was but a simple software development intern eager to prove himself. He would always volunteer for the menial tasks that nobody else wanted to do. "Nobody else" mainly consisted of Justin, Rodrigo's supervisor. Justin wasn't a big fan of doing stuff so he was glad to have an intern that was ready and willing.Justin got a request from the network administrators to create a system status application to interface with their servers. They wanted to receive alert emails every hour on the hour if anything on the servers had a conniption. If everything was ok, maintain radio silence. To do this, a simple app would need to be created to pass system health check results to Pushbullet, which would take care of sending the alerts. Rodrigo didn't even wait for Justin to finish. "I'll do it!"Rodrigo was excited to get his development environment set up with an instance of Pushbullet so he could start slinging emails. He spent the week coding and extensively testing his app and by Friday, his phone buzzed with an alert. Something about having his code send something out to his phone seemed super cool and futuristic.Rodrigo wasn't exactly sure how to simulate a system failure so his phone only got emails saying everything was hunky-dory. All he had left to do was to add a condition to not actually send the hunky-dory alerts since the network admins didn't want their phones going off every hour.Ready to proudly show off his handiwork, Rodrigo called Justin over for a demo. The demo consisted of Justin half paying attention, half texting on his phone, and saying "Yeah, ok" every couple minutes. When Rodrigo was done, Justin nonchalantly said, "Go ahead and throw it out on the production server whenever". Rodrigo wasn't expecting that but he was glad to finally have an app of his go to production.He threw the code out on the production server, fired it up, sent an email letting the admins know to expect an alert in case of trouble, then checked out for the weekend. He bragged to his friends over several beers about how his code was working all weekend while he got to have fun.Rodrigo strolled in Monday morning to find a red-faced Justin standing at his desk, arms crossed. "Rodrigo! We had a major system failure over the weekend!"Confused, Rodrigo played an optimistic card, "So when that happened, my app notified everyone... right?""No, it didn't!" Justin shouted, banging his hands down on the desk. "Your app didn't do jack squat to alert anyone, now we've lost nearly 30 hours of production data! Have a seat and think about how we're going to fix this while I review your code."Justin opened Rodrigo's source code at his computer and began scrolling through it. It didn't take long for him to find the offending line -
CodeSOD: We Tried Nothing
Initrode bought a UI widget library from Initech. Years passed, and eventually Initech went under. Initrode kept on keeping on, and kept using the library. Management shuffles happened, IT got downsized, and new development got outsourced.Merlin B worked for the company that got the contract. Somehow, someone got the source code from Initech's GUI library.
CodeSOD: Longer Isn't Better
Andrew H writes “this is an interface for one of our Spring Data repositories”. If you’ve ever looked at Spring’s documentation, you know the punchline. Spring has certain naming conventions that have become a notorious.Spring Data is an ORM, and among other things, it allows you to design interfaces which are translated into a series of queries based on the naming conventions. So, for example, a method named findDistinctByTenantId would turn into a query in the database. It’s a useful convenience for simple CRUD operations, but for more complex queries, you’re still better off writing your SQL in an @Query annotation. SQL is still the best way to build complicated RDBMS queries.That doesn’t mean you have to use SQL. Andrew’s co-worker provided this method:
Error'd: Real Formatting Advice
"VMware Team decided to send me some useful advice via e-mail," writes Antti T.
The Theater of the Mind
Hamza has some friends in the theater business. These friends had an in-house developed Java application to manage seating arrangements, and they had some problems with it. They had lots of problems with it. So Hamza cut them a deal and agreed to take a look.There were the usual litany of problems: performance was garbage, features bugged out if you didn’t precisely follow a certain path, it crashed all the time, etc. There was also an important missing feature.Seats in a theater section lay out roughly in a grid. Roughly- not every row has exactly the same number of seats, sometimes there are gaps in the middle of the row to make way for the requirements of the theater itself, and the application could handle that- for one arrangement. Seats could be removed to create standing-room sections, seats could be added to rows, seats could be reserved for various purposes, and so on. None of this was supported by the application.Hamza dug into the code which rendered the seating arrangements. Did it read from a database? Did it read from a config file? Did it have a hard-coded array?
CodeSOD: A Load of ProductCodes
“Hey, Kim H, can you sit in on a tech-screen for a new hire?”The Big Boss had a candidate they wanted hired, but before the hiring could actually happen, a token screening process needed to happen. Kim and a few other staffers were pulled in to screen the candidate, and the screen turned into a Blue Screen, because the candidate crashed hard. Everyone in the room gave them a thumbs down, and passed their report up the chain to the Big Boss.The Big Boss ignored their comments and hired the candidate anyway. A week later, this ended up in source control:
CodeSOD: My Condition is Complicated
Anneke’s organization is the sort of company where “working” takes precedence over “working well”. Under-staffed, under-budgeted, and under unrealistic deadlines, there simply isn’t any emphasis on code quality. The result is your pretty standard pile of badness: no tests, miles of spaghetti code, fragile features and difficult to modify implementations.Recently, the powers that be discovered that they could hire half a dozen fresh-out-of-school developers on the cheap, and threw a bunch of fresh-faced kids into that mountain of garbage with no supervision. And that’s how this happened.
CodeSOD: Eine Kleine ProductListItems
Art received a job offer that had some generous terms, and during the interview process, there was an ominous sense that the hiring team was absolutely desperate for someone who had done anything software related.Upon joining the team, Art found out why. Two years ago, someone had decided they needed to create a web-based storefront, and in a fit of NIH syndrome, it needed to be built from scratch. Unfortunately, they didn't have anyone working at the company with a web development background or even a software development background, so they just threw a book on JavaScript at the network admin and hoped for the best.Two years on, and they didn't have a working storefront. But they did have code like this:
Error'd: Latin is Making a Comeback?
"Well, if I need an email template, lucky me, I now have one handy," writes Paul C.
CodeSOD: Boldly Leaping Over the Span
No one writes HTML anymore. We haven’t for years. These days, your HTML is snippets and components, templates and widgets. Someplace in your application chain, whether server-side or client-side, or even as part of a deployment step, if you’re using a static site generator, some code mashes those templates together and you get some output.This has some side effects, like div abuse. Each component needs its own container tag, but we often nest components inside each other. Maybe there’s a span in there. If the application is suitably HTML5-y, maybe it’s sections instead.Andy stumbled across a site which was blocking right clicking, so Andy did what any of us would do: pulled up the debugging tools and started exploring the DOM tree.
CodeSOD: Round Two
John works for a manufacturing company which has accrued a large portfolio of C++ code. Developed over the course of decades, by many people, there’s more than a little legacy cruft and coding horrors mixed in. Frustrated with the ongoing maintenance, and in the interests of “modernization”, John was tasked with converting the legacy C++ into C#.Which meant he had to read through the legacy C++.In the section for creating TPS reports, there were two functions, TpsRound and TpsRound2. The code between the two of them was nearly identical- someone had clearly copy/pasted and made minor tweaks.
CodeSOD: Tern The Bool Around
Some say that the only reason I like ternary code snippets is that it gives me an opportunity to make the title a “tern” pun.…They’re not wrong.I’m actually a defender of ternaries. Just last week, I wrote this line of C++ code:
A Floating Date
Enterprise integration is its own torturous brand of software development. Imagine all the pain of inheriting someone else's code, but now that code is proprietary, you can't modify it, poorly documented, and exposes an API that might solve somebody's problem, but none of the problems you have, and did I say poorly documented? I meant "the documentation is completely inaccurate and it's possible that this was intentional".Michael was working on getting SAP integrated to their existing legacy systems. This meant huge piles of bulk data loading, which wasn't so bad- they had a third party module which promised to glue all this stuff together. And in early testing phases, everything went perfectly smooth.Of course, this was a massive enterprise integration project for a massive company. That guaranteed a few problems that were unavoidable. First, there were little teams within business units who weren't using the documented processes in the first place, but had their own home-grown process, usually implemented in an Excel file on a network drive, to do their work. Tracking these down, prying the Excel sheet out of their hands, and then dealing with the fallout of "corporate coming in and changing our processes for no reason" extended the project timeline.Well, it extended how much time the project actually needed, which brings us to the second guaranteed problem: the timeline was set based on what management wanted to have happen, not based on what was actually possible or practical. No one on the technical side of things was consulted to give an estimate about required effort. A go-live date of October 8th was set, and everything was going to happen on October 8th- or else.The project was, against all odds, on track to hit the ridiculous target. Until it went into UAT- and that's when Michael started catching issues from users. Dates were shifting. In the source system, the date might be November 21st, but in SAP it was November 20th. The 23rd turned into the 24th. The 25th also turned into the 24th.Michael was under a time crunch, and trapped between a rock (the obtuse legacy system), a hard place (SAP), and a hydraulic press (the third-party data import module). There was a pattern to the errors, though, and that pattern pointed to a rounding error."Wait, a rounding error?" Michael wondered aloud. Now, they did use numbers to represent dates. The "Japanese" notation, which allowed them to store "November 21st, 2018" as 20181121. That's a super common approach to encoding a date as a 32-bit integer. As integers, of course, there was no rounding. They were integers on the legacy side, they were integers on the SAP side- but what about in the middle? What was the third party import module doing?As a test, Michael whipped up a little two-line program to test:
Error'd: Let's Hope it's Only a Test
"When the notification system about the broken NYC MTA is broken, does that make the MTA meta-broken?" writes T.S.
CodeSOD: Break Out of your Parents
When I first glanced at this submission from Thomas, I almost just scrolled right by. “Oh, it’s just another case where they put the same code in both branches of the conditional,” I said. Then I looked again.
Blind Leading the Blind
Corporate Standards. You know, all those rules created over time by bureaucrats who think that they're making things better by mandating consistency. The ones that force you to take time to change an otherwise properly-functioning system to comply with rules that don't really apply in the context of the application, but need to be blindly followed anyway. Here are a couple of good examples.Kevin L. worked on an application that provides driving directions via device-hosted map application. The device was designed to be bolted to the handlebars of a motorcycle. Based upon your destination and current coordinates, it would display your location and the marked route, noting things like distance to destination, turns, traffic circles and exit ramps. A great deal of effort was put into the visual design, because even though the device *could* provide audio feedback, on a motorcycle, it was impossible to hear.One day, his boss, John, called him into a meeting. "I was just read the riot-act by HR. It seems that our application doesn't comply with corporate Accessibility Standards, specifically the standard regarding Braille Literature In Need of Description. You need to add screenreader support to the motorcycle map application. I estimate that it will take a few months of effort. We don't really have the time to spare, but we have to do it!"Kevin thought about it for a bit and asked his boss if the company really wanted him to spend time to create functionality to provide verbal driving directions for blind motorcycle drivers.That head-desk moment you're imagining really happened.Of course, common sense had no bearing on the outcome, and poor Kevin had to do the work anyway.While self-driving cars will eventually be commonplace, and no one will need directions, audible or otherwise. For now, though, Kevin at least knows that all the visually impaired motorcycle drivers can get to where they're going. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
CodeSOD: An Error on Logging
The beauty of a good logging system is that it allows you to spam logging messages all through your code, but then set the logging level at runtime, so that you have fine grained control over how much logging there is. You can turn the dial from, “things are running smooth in production, so be quiet,” to “WTF THINGS ARE ON FIRE GODS HELP US WHAT IS GOING ON CAN I LAUNCH A DEBUGGER ON THE PRODUCTION ENVIRONMENT PLEASE GOD”.You might write something like this, for example:
CodeSOD: Pointed Array Access
I've spent the past week doing a lot of embedded programming, and for me, this has mostly been handling having full-duplex communication between twenty devices on the same serial bus. It also means getting raw bytes and doing the memcpy(&myMessageStructVariable, buffer, sizeof(MessageStruct)). Yes, that's not the best way, and certainly isn't how I'd build it if I didn't have full control over both ends of the network.Of course, even with that, serial networks can have some noise and errors. That means sometimes I get a packet that isn't the right size, and memcpy will happily read past the end of the buffer, because my const uint8_t * buffer pointer is just a pointer, after all. It's on me to access memory safely. Errors result when I'm incautious.Which brings us to Krzysztof`s submission. This code is deep inside of a device that's been on the market for twenty years, and has undergone many revisions, both hardware and software, over that time.
Error'd: Full Price not Allowed
"When registering for KubeCon and CloudNativeCon, it's like they're saying: Pay full price? Oh no, we insist you use a discount code. No really. It's mandatory," writes Andy B.
CodeSOD: Off by Dumb Error
“We’re bringing on my nephew, he’s super smart with computers, so you make sure he is successful!”That was the long and short of how Reagan got introduced to the new hire, Dewey. Dewey’s keyboard only really needed three keys: CTRL, C, and V. They couldn’t write a line of code to save their life. Once, when trying to fumble through a FizzBuzz as a simple practice exercise, Dewey took to Google to find a solution. Because Dewey couldn’t quite understand how Google worked, instead of copy/pasting out of StackOverflow, they went to r/ProgrammerHumor and copied code out of a meme image instead. Reagan couldn’t even just try and shove Dewey off on a hunt for a left-handed packet shifter in the supply closet, because Dewey’s patron was watching source control, and wanted to see Dewey’s brilliant commits showing up. Even if Reagan didn’t give Dewey any tasks, Dewey’s uncle did.That’s how Dewey got stumped trying to fetch data from a database. They simply needed to read one column and present it as a series of HTML list items, using PHP.This was their approach.
CodeSOD: Ten Times as Unique
James works with a financial services company. As part of their security model, they send out verification codes for certain account operations, and these have to be unique.So you know what happens. Someone wrote their own random string generator, then wrapped it up into a for loop and calls it until they get a random string which is unique:
CodeSOD: The UI Annoyance
Daniel has a bit of a story. The story starts many months ago, on the very first day of the month.Angular 1.x has something called a filter as a key concept. This is a delightfully misleading name, as it's more meant to be used as a formatting function, but because it takes any arbitrary input and converts it to any arbitrary output, people did use it to filter, which had all sorts of delightful performance problems in practice.Well, Daniel found this perfectly sensible formatting filter. It's well documented. It's also wrong.
CodeSOD: Shell Out
Developers sometimes fail to appreciate how difficult a job Operations really is. In companies that don't hold with newfangled DevOps, the division of labor often comes with a division of reputation as well. After all, developers do the hard work of making software. What are Ops guys even for? They don't make software. They don't generate leads or fix your desktop PC. Why bother paying for talented senior Ops professionals?Spend a few days with the Ops team, however, and you start to see why you should pay them a little more than your average garbageman. The Ops lifecycle is a daily grind of deployments, patching, and sticking fingers in dykes, trying to keep that expensive cesspit the devs call "software" running. Simple tasks such as spinning up new infrastructure in AWS often get pushed to the back burner behind putting out fires and making sure critical maintenance tasks that didn't get done last year don't explode into flames.Still, companies like to cut corners. Often, Ops folks have very little programming expertise and no training budget, meaning repetitive tasks are automated using cobbled-together bits of shell script found via Google. In the Ops world, a bit of Perl or Python is worth its weight in gold.Today's snippet, as you can probably guess, is not in Perl or Python. It is instead in a common paradigm: Bash embedded in Perl. Likely, the original script was written by a senior who knows Perl, and this chunk was written by a strapped-for-time medior who didn't:
Error'd: This Movie is Rated S for Safe for SQL
"Clearly the Light Cinema decided to ban unsafe sql characters from the cinema," wrote Simon, "Let's hope no one makes a film called 'Drop Table'."
CodeSOD: Flip to a Blank Page
You have a web application, written in Spring. Some pages live at endpoints where they’re accessible to the world. Other pages require authentication, and yet others require users belong to specific roles. Fortunately for you, Spring has features and mechanisms to handle all of those details, down to making it extremely easy to return the appropriate HTTP error.Unfortunately for you, one of the developers on your team is a Rockstar™ who is Officially Very Smart and absolutely refuses to use the tools your platform provides. When that Certified Super Genius leaves the organization, you inherit their code.That’s what happened to Emmer. And that’s how they found this:
Westward Ho!
Roman K. once helped to maintain a company website that served a large customer base mainly within the United Kingdom. Each customer was itself a business offering a range of services. The website displayed these businesses on a map so that potential customers could find them. This was done by geocoding the business' addresses to get their longitude and latitude coordinates, then creating points on the map at those locations.Simple enough—except that over time, some of the businesses began creeping west through the Atlantic Ocean, toward the east coast of North America.Roman had no idea where to start with troubleshooting. It was only happening with a subset of businesses, and only intermittently. He was certain the initial geocoded coordinates were correct. Those longitude and latitude values were stored in a database table of customer data with strict permissions in place. Even if he wanted to change them himself, he couldn't. Whatever the problem was, it was powerful, and oddly selective: it only ever changed longitude values. Latitude values were never touched.Were they being hacked by their competitors? Were their customers migrating west en masse? Were goblins messing with the database every night when no one was looking?Roman dug through reams of code and log files, searching desperately for any whiff of "longitude." He questioned his fellow developers. He blamed his fellow developers. It was all for naught, for the problem was no bug or hack. The problem was a "feature" of the database access layer. Roman discovered that the user class had a simple destructor method that saved all the currently loaded data back to the database:
CodeSOD: Switch On Suppression
Krista noticed our article explaining that switches were replacements for ifs. She sent in a version she found in her codebase, around the same idea:
CodeSOD: The Secure Cloud API
Melinda's organization has purchased a cloud-based storage system. Like any such system, it has a lovely API which lets you manage quotas and login tokens. It also had a lovely CLI, which was helpful for administrators to modify the cloud environment. Melinda's team built a PHP front-end that could not only manage files, but also allowed administrators to manage those quotas.Melinda was managing those quotas, and when she clicked the link to view the quotas, she noticed the URL contained ?token=RO-cmV1c2luZyBrZXlzIGlzIFRSV1RG. When she went to modify the quota, the URL parameter became ?token=RW-cmV1c2luZyBrZXlzIGlzIFRSV1RG. That looked like a security key for their cloud API, transmitted in the open. The RW and RO looked like they had something to do with readwrite and readonly, but that wasn't the security model their storage provider used. When Melinda had another co-worker log in, they saw the same tokens. What was going on?Melinda took a look at the authorization code.
Error'd: Stay Away From California
"Deep down, I knew this was one of the most honest labels I've ever seen," wrote Bob E.
Crazy Like a Fox(Pro)
“Database portability” is one of the key things that modern data access frameworks try and ensure for your application. If you’re using an RDBMS, the same data access layer can hopefully work across any RDBMS. Of course, since every RDBMS has its own slightly different idiom of SQL, and since you might depend on stored procedures, triggers, or views, you’re often tied to a specific database vendor, and sometimes a version.And really, for your enterprise applications, how often do you really change out your underlying database layer?Well, for Eion Robb, it’s a pretty common occurrence. Their software, even their SaaS offering of it, allows their customers a great deal of flexibility in choosing a database. As a result, their PHP-based data access layer tries to abstract out the ugly details, they restrict themselves to a subset of SQL, and have a lot of late nights fighting through the surprising bugs.The databases they support are the big ones- Oracle, SQL Server, MySQL, and FoxPro. Oh, there are others that Eion’s team supports, but it’s FoxPro that’s the big one. Visual FoxPro’s last version was released in 2004, and the last service pack it received was in 2007. Not many vendors support FoxPro, and that’s one of Eion’s company’s selling points to their customers.The system worked, mostly. Until one day, when it absolutely didn’t. Their hosted SaaS offering crashed hard. So hard that the webserver spinlocked and nothing got logged. Eion had another late night, trying to trace through and figure out: which customer was causing the crash, and what were they doing?Many hours of debugging and crying later, Eion tracked down the problem to some code which tracked sales or exchanges of product- transactions which might not have a price when they occur.
CodeSOD: Padding Your Time
Today will be a simple one, and it’s arguably low-hanging fruit, because once again, it’s date handling code. But it’s not handling dates where it falls down. It falls down on something much more advanced: conditionals. Supplied by “_ek1n”.
CodeSOD: Wear a Dunder Cap
In the Python community, one buzzword you’ll find thrown around is whether or not an approach is “pythonic”. It’s a flexible term, and something you can just throw out in code reviews, even if you’ve never written a line of Python in your life: “Is that Pythonic?”The general rubric for what truly is “pythonic” is generally code that is simple and code that operates explicitly. There shouldn’t be any “magic”. But Python doesn’t force you to write “pythonic” code, and it provides loads of tools like decorators and metaclasses that let you get as complex and implicit as you like.One bit of magic is the “dunder” methods, which are Python’s vague approach to operator overloading. If you want your class to support the [] operator, implement __getitem__. If you want your class to support the + operator, implement __add__. If you want your class to support access to any arbitrary property, implement __getattr__.Yes, __getattr__ allows you to execute code on any property access, so a simple statement like this…
CodeSOD: Legacy Switchout
About a decade ago, I attended a talk. The speaker made the argument that "legacy code" may have many possible interpretations, but the practical view was to simply think of legacy code as "code without unit tests". Thus, the solution to modernizing your legacy code was to simply write unit tests. Refactoring the code to make it testable would have the side effect of modernizing the code base, and writing tests would act as documentation. It's that easy.Andrew is struggling with some legacy code right now. Worse, they're trying to integrate a large mountain of legacy code into a custom, in-house CI/CD pipeline. This particular pile of legacy code dates back to the mid-2000s, so everything in it is glued together via XML. It was some of that XML code which started failing when Andrew threw some unit tests at it.It doesn't start that bad:
Error'd: An Unfortunate Sign
"Found this in the School of IT. 404: Women not found. Fairly accurate," wrote Maddie J.
CodeSOD: Not a Not Bad Approach
In terms of elegance, I think the bitmask has a unique beauty. The compactness of your expression, the simple power of bitwise operators, and the way you can see the underlying implementation of numbers laid bare just speaks to me. Of course, bitmasks can be a bit opaque, and you may have to spend some time thinking about what foo &= 0xFF0000 is actually doing, but there’s also something alluring about it.Of course, bitmasks are surprisingly hard. For example, let’s look at some code submitted anonymously. This code is meant to run on a line of coin-operated dryers. Depending on the particular install, how many coins a patron puts in, what modes have been enabled by the owner, and so on, different “extra” features might be disabled or not disabled.Since bitmasks are hard, we’re not going to use one. Instead, let’s have a pile of constants, like so:
CodeSOD: Caught Up in the Captcha
Gregor needed to download a network driver. Upon clicking the link, a "captcha" appeared, presumably to prevent hotlinking to the driver files. It wasn't a real, image-based captcha, but a simple "here's some characters, type them into the box".The code which popped up was "S i u x q F b j NaN 4". He hit the "new code" button, and got "T o A 0 J V s L NaN a". In fact, "NaN" showed up in the penultimate position in every code.Curious, Gregor pulled up the debugger to see how the captcha was generated.
SLA-p the Salesman
A Service-Level Agreement (SLA) is meant to ensure customer issues receive the attention they deserve based on severity. It also protects the support company from having customers breathing down their neck for frivolous issues. All of the parameters are agreed upon in writing ahead of time and both sides know the expectations. That is, until a salesman starts to meddle and mess things up, as happened at the place Dominick worked for.Dominick was a simple remote support tech who fixed things for clients well ahead of the SLA. On the rare occasion there was a priority 1 issue - something stopping anyone in the company from doing work - they had 24 hours to fix it before large monetary penalties would start to rack up. One Friday a priority 4 issue (5 business day SLA) came in from the CFO of a new client. The ticket was assigned to Dominick, who had higher priority work to do for other clients, so he decided it could wait until the following week.Dominick came in Monday morning to find Benjamin, a senior salesman who happened to be a personal friend of the CFO, sitting on his desk with his huge arms crossed. Benjamin glanced at his watch to see it was 7:59 AM. "About time you showed up, Dom. I found out you didn't do the ticket that came in Friday and I want an explanation!"Still in a pre-coffee Monday morning haze, Dominick had to think for a second to figure out what he was talking about. "Oh... that thing about ordering a new printer? That was only priority 4 and it literally said 'no rush' in it. I have 4 more days to get it done."Benjamin sprang up off Dom's desk and used his beefy arms to forcefully shove an index finger into his chest. "You don't get it do you, bro?? When I made this deal with them, I assured them anything would be treated with the highest priority!" Ben shouted while spraying an unsanitary amount of saliva droplets. "I don't care what your silly numbering system says, it needs to get done today!"Ok... well let me sit down and look at it," Dominick said timidly while rubbing the spot on his chest that received a mean poking. Benjamin stormed off to presumably consume another protein shake. He pulled up the ticket about ordering a new printer for the CFO's office. It seemed he'd read about this top of the line printer in some tech magazine and really wanted it. The problem was the printer wasn't even on the market yet - it would be released at the end of the month. Since there was literally nothing Dominick could do to get the printer, he closed the ticket and asked that a new one be submitted when the printer was available.Later that afternoon, Dominick heard stomping behind him and before he could turn around, Benjamin spun him around in his chair and got in his face. "Hey there, bro. Where is my guy's printer?? He told me you closed his submission without ordering it!"Dominick stood up to defend himself and weakly poked Ben in the chest. "Listen, bro! He wants a printer that isn't out yet. The best I can do is pre-order it and have it shipped to him in a couple weeks. I closed the ticket so we don't get dinged on the SLA to get this done in 5 days."Benjamin furrowed his brow and got back within saliva-spraying distance, "You'll have to do better than that, Dom! While you were screwing around not resolving this I made an addendum to their SLA. Any ticket submitted by a CxO level executive will be treated as priority 1 by us. So you better pull whatever techie nerd strings you have to get that printer ordered in the next 24 hours!"After Benjamin stormed off yet again, the reality of what he had done set in. Since the SLA for the printer was now 24 hours, they would start getting charged penalties by tomorrow. Dominick quickly began crafting an email to senior management to explain the situation and how the request wasn't able to be met. He wasn't sure what sort of "techie nerd" resources Benjamin thought he had, but it wasn't going to happen.Predictably, the situation didn't end well. The financial penalties started adding up the following day, and the next day, and so on. It became so expensive that it was more cost-effective to pay the client to modify the addendum to the SLA that Benjamin made (they couldn't be compelled to do so otherwise) than to continue to rack up fines.The end of the month came and the world's most expensive printer finally shipped, which was a relief to everyone. But that also meant the end-of-month financial statements showed the huge deficit caused by it. To compensate, the company decided to lay off 20% of the support staff including Dominick. Benjamin, of course, got to keep his job where he always put customer needs first. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Classic WTF: Security By Letterhead
CodeSOD: Why I Hate Conference Swag (and What can be Done About it)
Hey everyone - I'm at a conference this week I'd like to cover a WTF that I've been seeing this week - VENDOR SWAG.Ok, if you are one of those poor souls who are always heads down in code and never attend workshops or conferences, this won't make much sense to you, but here's the deal - companies will set up a booth or a table and will pass out swag in exchange for your contact info and (possibly) a lead. To me, this is easily the dirtiest transaction one can make and rife with inequalities. Your information is super valuable - as in possibly generating thousands or millions of sales dollars. The 'gift' will be SUPER cheap by comparison.How cheap? WELL, here are some examples:
Keeping Up Appearances
Just because a tool is available doesn't mean people will use it correctly. People have abusedbooleans,dates,enums,databases,Go-To's,PHP,reinventing the wheel and even Excel to the point that this forum will never run out of material!Bug and issue trackers are Good Thingsâ„¢. They let you keep track of multiple projects, feature requests, and open and closed problems. They let you classify the issues by severity/urgency. They let you specify which items are going into which release. They even let you track who did the work, as well as all sorts of additional information.Every project, no matter how big or small, should make use of them.Ideally, they would be used correctly.Ideally.Matt had just released the project that he'd been working on for the past few years. As always happens, some "issues" cropped up. Some were genuine defects. Some were sort-of-enhancements based on the fact that a particular input screen was unwieldy and needed to be improved. At least one was a major restructuring of a part of the project that did not flow too well. In all, Matt had seven issues that needed to be addressed. Before he could deliver them, he needed defect tickets in the bug tracking system. He wasn't authorized to raise such tickets; only the Test team could do that.It took a while, but he finally received a ticket to do the work to... but everything had been bundled up into one ticket. This made it very difficult to work with, because now he couldn't just clear each issue as he went. Instead, he had to package them up in abeyance, so to speak, and only release them when they were all complete. This also meant that the test documentation, providing instructions to the Test team as to how to ensure that the fix was working as required, all had to be bundled up into one big messy document, making it more difficult for Testers to do their job as well.So he questioned them: If we can raise a single defect ticket, then what stops us from raising all 7 needed tickets so that the issues can be addressed separately? The answer was: Because these defects appear post-release, it is clear that they weren't caught at the pre-release stage, which means that Somebody Wasn't Doing Their Job Properly in the Test team, which makes them Look Bad; it brings their failure to catch the issues to the attention of Management.In other words, in order to keep the Test team from looking bad, they would only ever raise a single ticket (encompassing all detected issues) for any given release.Imagine if all of the bugs from your last major release were assigned to you personally, in a single ticket. Good luck estimating, scheduling, coding, debugging and documenting how to test the single logical bug!Matt raised this bad practice with management, and explained that while the reason for why they do this is to hide their inadequacy, it also prevents any meaningful way to control work distribution, changes and subsequent testing. It also obscures the actual number of issues (Why is it taking you seven weeks to fix one issue?).Management was not amused at having been misled. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
CodeSOD: Rectangle Marks The Spot
If you need your user's country of origin, there are many ways you can go about obtaining it programmatically. Some may opt for a simple drop-down that prompts the user to specify his/her country. If you don't want to burden your user this way, you might look at their session data and return their country of origin, time zone, or some other useful information. If you have fancy enough APIs at your disposal, you could even reverse geocode the user's longitude/latitude position and obtain an address.Or, you can start with their location and perform the code equivalent of throwing a dart at a map littered with creepy-looking post-it notes:
...32333435363738394041...