Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2025-07-09 14:31
The New Guy (Part II): Database Boogaloo
When we last left our hero Jesse, he was wading through a quagmire of undocumented bad systems while trying to solve an FTP issue. Several months later, Jesse had things figured out a little better and was starting to feel comfortable in his "System Admin" role. He helped the company join the rest of the world by dumping Windows NT 4.0 and XP. The users whose DNS settings he bungled were now happily utilizing Windows 10 workstations. His web servers were running Windows Server 2016, and the SQL boxes were up to SQL 2016. Plus his nemesis Ralph had since retired. Or died. Nobody knew for sure. But things were good.Despite all these efforts, there were still several systems that relied on Access 97 haunting him every day. Jesse spent tens of dollars of his own money on well-worn Access 97 programming books to help plug holes in the leaky dike. The A97 Finance system in particular was a complete mess to deal with. There were no clear naming guidelines and table locations were haphazard at best. Stored procedures and functions were scattered between the A97 VBS and the SQL DB. Many views/functions were nested with some going as far as eight layers while others would form temporary tables in A97 then continue to nest.One of Jesse's small wins involved improving performance of some financial reporting queries that took minutes to run before but now took seconds. A few of these sped-up reports happened to be ones that Shane, the owner of the company, used frequently. The sudden time-savings got his attention to the point of calling Jesse in to his office to meet."Jesse! Good to see you!" Shane said in an overly cheerful manner. "I'm glad to talk to the guy who has saved me a few hours a week with his programmering fixes." Jesse downplayed the praise before Shane got to the point. "I'd like to find out from you how we can make further improvements to our Finance program. You seem to have a real knack for this."Jesse, without thinking about it, blurted, "This here system is a pile of shit." Shane stared at him blankly, so he continued, "It should be rebuilt from the ground up by experienced software development professionals. That's how we make further improvements.""Great idea! Out with the old, in with the new! You seem pretty well-versed in this stuff, when can you start on it?" Shane said with growing excitement. Jesse soon realized his response had backfired and he was now on the hook to the owner for a complete system rewrite. He took a couple classes on C# and ASP.NET during his time at Totally Legit Technical Institute so it was time to put that valuable knowledge to use.Shane didn't just let Jesse loose on redoing the Finance program though. He insisted Jesse work closely with Linda, their CFO who used it the most. Linda proved to be very resistant to any kind of change Jesse proposed. She had mastered the painstaking nuances of A97 and didn't seem to mind fixing large amounts of bad data by hand. "It makes me feel in control, you know," Linda told him once after Jesse tried to explain the benefits of the rewrite.While Jesse pecked away at his prototype, Linda would relentlessly nitpick any UI ideas he came up with. If she had it her way, the new system would only be usable by someone as braindead as her. "I don't need all these fancy menus and buttons! Just make it look and work like it does in the current system," she would say at least once a week. "And don't you dare take my manual controls away! I don't trust your automated robotics to get these numbers right!" In the times it wasn't possible to make something work like Access 97, she would run to Shane, who would have to talk her down off the ledge.Even though Linda opposed Jesse at every turn, the new system was faster and very expandable. Using C# .NET 4.7.1 with WPF, it was much less of an eyesore. The database was also clearly defined with full documentation, both on the tables and in the stored procedures. The database size managed to go from 8 GB to .8 GB with no loss in data.The time came at last for go-live of Finance 2.0. The thing Jesse was most excited about was shutting down the A97 system and feeling Linda die a little bit inside. He sent out an email to the Finance department with instructions for how to use it. The system was well-received by everyone except Linda. But that still led to more headaches for Jesse.With Finance 2.0 in their hands, the rest of the users noticed the capabilities modern technology brought. The feature requests began pouring in with no way to funnel them. Linda refused to participate in feature reviews because she still hated the new system, so they all went to Shane, who greenlighted everything. Jesse soon found himself buried in the throes of the monster he created with no end in sight. To this day, he toils at his computer cranking out features while Linda sits and reminisces about the good old days of Access 97. [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
The Manager Who Knew Everything
Have you ever worked for/with a manager that knows everything about everything? You know the sort; no matter what the issue, they stubbornly have an answer. It might be wrong, but they have an answer, and no amount of reason, intelligent thought, common sense or hand puppets will make them understand. For those occasions, you need to resort to a metaphorical clue-bat.A few decades ago, I worked for a place that had a chief security officer who knew everything there was to know about securing their systems. Nothing could get past the policies she had put in place. Nobody could ever come up with any mechanism that could bypass her concrete walls, blockades and insurmountable defenses.One day, she held an interdepartmental meeting to announce her brand spanking shiny new policies regarding this new-fangled email that everyone seemed to want to use. It would prevent unauthorized access, so only official emails sent by official individuals could be sent through her now-secured email servers.I pointed out that email servers could only be secured to a point, because they had to have an open port to which email clients running on any internal computer could connect. As long as the port was open, anyone with internal access and nefarious intent could spoof a legitimate authorized email address and send a spoofed email.She was incensed and informed me (and the group) that she knew more than all of us (together) about security, and that there was absolutely no way that could ever happen. I told her that I had some background in militarysecurity, and that I might know something that she didn't.At this point, if she was smart, she would have asked me to explain. If she already handled the case, then I'd have to shut up. If she didn't handle the case, then she'd learn something, AND the system could be made more secure. She was not smart; she publicly called my bluff.I announced that I accepted the challenge, and that I was going to use my work PC to send an email - from her - to the entire firm (using the restricted blast-to-all email address, which I would not normally be able to access as myself). In the email, I would explain that it was a spoof, and if they were seeing it, then the so-called impenetrable security might be somewhat less secure than she proselytized. In fact, I would do it in such a way that there would be absolutely no way to prove that I did it (other than my admission in the email).She said that if I did that, that I'd be fired. I responded that 1) if the system was as secure as she thought, that there'd be nothing to fire me for, and 2) if they could prove that it was me, and tell me how I did it (aside from my admission that I had done it), that I would resign. But if not, then she had to stop the holier-than-thou act.Fifteen minutes later, I went back to my desk, logged into my work PC using the guest account, wrote a 20 line Cold Fusion script to attach to the email server on port 25, and filled out the fields as though it was coming from her email client. Since she had legitimate access to the firm-wide email blast address, the email server allowed it. Then I sent it. Then I secure-erased the local system event and assorted other logs, as well as editor/browser/Cold Fusion/server caches, etc. that would show what I did. Finally, I did a cold boot to ensure that even the RAM was wiped out.Not long after that, her minions the SA's showed up at my desk joking that they couldn't believe that I had actually done it. I told them that I had wiped out all the logs where they'd look, the actual script that did it, and the disk space that all of the above had occupied. Although they knew the IP address of the PC from which the request came, they agreed that without those files, there was no way they could prove that it was me. Then they checked everything and verified what I told them.This info made its way back up the chain until the SAs, me and my boss got called into her office, along with a C-level manager. Everything was explained to the C-manager. She was expecting him to fire me.He simply looked at me and raised an eyebrow. I responded that I spent all of ten minutes doing it in direct response to her assertion that it was un-doable, and that I had announced my intentions to expose the vulnerability - to her - in front of everyone - in advance.He chose to tell her that maybe she needed to accept that she doesn't know quite as much about everything as she thinks, and that she might want to listen to people a little more. She then pointed out that I had proven that email was totally insecure and that it should be banned completely (this was at the point where the business had mostly moved to email). I pointed out that I had worked there for many years, had no destructive tendencies, that I was only exposing a potential gap in security, and would not do it again. The SAs also pointed out that the stunt, though it proved the point, was harmless. They also mentioned that nobody else at the firm had access to Cold Fusion. I didn't think it helpful to mention that not just Cold Fusion, but any programming language could be used to connect to port 25 and do the same thing, and so didn't. She huffed and puffed, but had no credibility at that point.After that, my boss and I bought the SAs burgers and beer. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
CodeSOD: Maximum Performance
There is some code, that at first glance, doesn’t seem great, but doesn’t leap out as a WTF. Stephe sends one such block.
CodeSOD: The Enabler
Shaneka works on software for an embedded device for a very demanding client. In previous iterations of the software, the client had made their own modifications to the device's code, and demanded they be incorporated. Over the years, more and more of the code came from the client, until the day when the client decided it was too much effort to maintain the ball of mud and just started demanding features.One specific feature was a new requirement for turning the display on and off. Shaneka attempted to implement the feature, and it didn't work. No matter what she did, once they turned the display off, they simply couldn't turn it back on without restarting the whole system.She dug into the code, and found the method to enable the display was implemented like this:
Error'd: Try Again (but with More Errors)
"Sorry, Walgreens, in the future, I'll try to make an error next time," Greg L. writes.
Improv for Programmers: The Internet of Really Bad Things
Things might get a little dark in the season (series?) finale of Improv for Programmers, brought to you by Raygun. Remy, Erin, Ciarán and Josh are back, and not only is everything you're about to hear entirely made up on the spot: everything you hear will be a plot point in the next season of Mr. Robot.Raygun provides a window into how users are really experiencing your software applications.Unlike traditional logging, Raygun silently monitors applications for issues affecting end users in production, then allows teams to pinpoint the root cause behind a problem with greater speed and accuracy by providing detailed diagnostic information for developers. Raygun makes fixing issues 1000x faster than traditional debugging methods using logs and incomplete information.Now’s the time to sign up. In a few minutes, you can have a build of your app with Raygun integrated, and you’ll be surprised at how many issues it can identify. There’s nothing to lose with a 14-day free trial, and there are pricing options available that fit any team size. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Sponsor Post: Six Months of Free Monitoring at Panopta for TDWTF Readers
You may not have noticed, but in the footer of the site, there is a little banner that says:
CodeSOD: Many Happy Returns
We've all encountered a situation where changing requirements caused some function that had a single native return type to need to return a second value. One possible solution is to put the two return values in some wrapper class as follows:
Representative Line: A Test Configuration
Tyler Zale's organization is a automation success story of configuration-as-code. Any infrastructure change is scripted, those scripts are tested, and deployments happen at the push of a button.They'd been running so smoothly that Tyler was shocked when his latest automated pull request for changes to their HAProxy load balancer config triggered a stack of errors long enough to circle the moon and back.The offending line in the test:
CodeSOD: A/F Testing
A/B testing is a strange beast, to me. I understand the motivations, but to me, it smacks of "I don't know what the requirements should be, so I'll just randomly show users different versions of my software until something 'sticks'". Still, it's a standard practice in modern UI design.What isn't standard is this little blob of code sent to us anonymously. It was found in a bit of code responsible for A/B testing.
Error'd: I Beg Your Entschuldigung?
"Delta does not seem to be so sure of what language to address me in," writes Pat.
Improv for Programmers: When Harddrives Attack
Put on some comfy pants, we're back again with a little something different, brought to you by Raygun. This week's installment starts with exploding hard drives, and only Steve Buscemi can save us. Today's episode contains small quantities of profanity.Raygun provides a window into how users are really experiencing your software applications.Unlike traditional logging, Raygun silently monitors applications for issues affecting end users in production, then allows teams to pinpoint the root cause behind a problem with greater speed and accuracy by providing detailed diagnostic information for developers. Raygun makes fixing issues 1000x faster than traditional debugging methods using logs and incomplete information.Now’s the time to sign up. In a few minutes, you can have a build of your app with Raygun integrated, and you’ll be surprised at how many issues it can identify. There’s nothing to lose with a 14-day free trial, and there are pricing options available that fit any team size. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
Passing Messages
About 15 years a go, I had this job where I was requested to set up and administer an MQ connection from our company to the Depository Trust & Clearing Corporation (DTCC). Since I had no prior experience with MQ, I picked up the manual, learned a few commands, and in a day or so, had a script to create queue managers, queues, disk backing stores, etc. I got the system analysts (SA's) at both ends on the phone and in ten minutes had connectivity to their test and production environments. Access was applied for and granted to relevant individuals and applications, and application coding could begin.
CodeSOD: Modern Art: The Funnel
They say a picture is worth a thousand words, and when it's a picture of code, you could say that it contains a thousand words, too. Especially when it's bad code.Here we have a work of true art. The symmetry hearkens back to the composition of a frame of a Wes Anderson film, and the fact that this snippet starts on line 418 tells us that there's more to this story, something exotic happening just outside of frame. The artist is actively asking questions about what we know is true, with the method calls? &emdash;I think they're method calls&emdash; which take too many parameters, most of which are false. There are hints of an Inner Platform, but they're left for the viewer to discover. And holding it all together are the funnel-like lines which pull the viewer's eyes, straight through the midline, all the way down to the final DataType.STRING, which really says it all, doesn't it? DataType.STRING indeed.If I ran an art gallery, I would hang this on a wall.If I ran a programming team, I'd hang the developer instead. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
CodeSOD: Classic WTF: Quantum Computering
Error'd: Go Home Google News, You're Drunk
"Well, it looks like Google News was inebriated as well!" Daniel wrote.
Improv for Programmers: Just for Transformers
We're back again with a little something different, brought to you by Raygun. Once again, the cast of "Improv for Programmers" is going to create some comedy on the fly for you, and this time… you could say it's… transformative. Today's episode contains small quantities of profanity.Raygun provides a window into how users are really experiencing your software applications.Unlike traditional logging, Raygun silently monitors applications for issues affecting end users in production, then allows teams to pinpoint the root cause behind a problem with greater speed and accuracy by providing detailed diagnostic information for developers. Raygun makes fixing issues 1000x faster than traditional debugging methods using logs and incomplete information.Now’s the time to sign up. In a few minutes, you can have a build of your app with Raygun integrated, and you’ll be surprised at how many issues it can identify. There’s nothing to lose with a 14-day free trial, and there are pricing options available that fit any team size. [Advertisement] ProGet can centralize your organization's software applications and components to provide uniform access to developers and servers. Check it out!
Business Driven Development
Every now and then, you come across a special project. You know the sort, where some business user decides that they know exactly what they need and exactly how it should be built. They get the buy-in of some C-level shmoe by making sure that their lips have intimate knowledge of said C-level butt. Once they have funding, they have people hired and begin to bark orders.About 8 years ago, I had the privilege experience of being on such a project. When we were given the phase-I specs, all the senior tech people immediately said that there was no way to perform a sane daily backup and data-roll for the next day. The response was "We're not going to worry about backups and daily book-rolls until later". We all just cringed, made like good little HPCs and followed our orders to march onward.Fast forward about 10 months and the project had a sufficient amount of infrastructure that the business user had no choice but to start thinking about how to close the books each day, and roll things forward for the next day. The solution he came up with was as follows:
Representative Line: Aggregation of Concatenation
A few years back, JSON crossed the “really good hammer” threshold. It has a good balance of being human readable, relatively compact, and simple to parse. It thus has become the go-to format for everything. “KoHHeKT” inherited a service which generates some JSON from an in-memory tree structure. This is exactly the kind of situation where JSON shines, and it would be trivial to employ one of the many JSON serialization libraries available for C# to generate JSON on demand.Orrrrr… you could use LINQ aggregations, string formatting and trims…
The New Guy (Part I)
After working mind-numbing warehouse jobs for several years, Jesse was ready for a fresh start in Information Technology. The year 2015 brought him a newly-minted Computer and Networking Systems degree from Totally Legit Technical Institute. It would surely help him find gainful employment, all he had to do was find the right opportunity.Seeking the right opportunity soon turned in to any opportunity. Jesse came across a posting for an IT Systems Administrator that piqued his interest but the requirements and responsibilities left a lot to be desired. They sought someone with C++ and Microsoft Office experience who would perform "General IT Admin Work" and "Other Duties as assigned". None of those things seemed to fit together, but he applied anyway.During the interview, it became clear that Jesse and this small company were essentially in the same boat. While he was seeking any IT employment, they were seeking any IT Systems admin. Their lone admin recently departed unexpectedly and barely left any documentation of what he actually did. Despite several red flags about the position, he decided to accept anyway. Jesse was assured of little oversight and freedom to do things his way - an extreme rarity for a young IT professional.Jesse got to work on his first day determined to map out the minefield he was walking in to. The notepad with all the admin passwords his predecessor left behind was useful for logging in to things. Over the next few days, he prodded through the network topology to uncover all the horrors that lie within. Among them:
Error'd: Perfectly Technical Difficulties
David G. wrote, "For once, I'm glad to see technical issues being presented in a technical way."
Improv for Programmers: Inventing the Toaster
We always like to change things up a little bit here at TDWTF, and thanks to our sponsor Raygun, we've got a chance to bring you a little treat, or at least something a little different.We're back with a new podcast, but this one isn't a talk show or storytelling format, or even a radio play. Remy rounded up some of the best comedians in Pittsburgh who were also in IT, and bundled them up to do some improv, using articles from our site and real-world IT news as inspiration. It's… it's gonna get weird.Thanks to Erin Ross, Ciarán Ó Conaire, and Josh Cox for lending their time and voices to this project.Music: "Happy Happy Game Show" Kevin MacLeod (incompetech.com)Licensed under Creative Commons: By Attribution 3.0 Licensehttp://creativecommons.org/licenses/by/3.0/Raygun gives you a window into the real user-experience for your software. With a few minutes of setup, all the errors, crashes, and performance issues will be identified for you, all in one tool. Not only does it make your applications better, with Raygun APM, it proactively identifies performance issues and builds a workflow for solving them. Raygun APM sorts through the mountains of data for you, surfacing the most important issues so they can be prioritized, triaged and acted on, cutting your Mean Time to Resolution (MTTR) and keeping your users happy.Now’s the time to sign up. In a few minutes, you can have a build of your app with Raygun integration, and you’ll be surprised at how many issues it can identify. There’s nothing to lose with a 14-day free trial, and there are pricing options available that fit any team size. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
CodeSOD: Return of the Mask
Sometimes, you learn something new, and you suddenly start seeing it show up anywhere. The Baader-Meinhof Phenomenon is the name for that. Sometimes, you see one kind of bad code, and the same kind of bad code starts showing up everywhere. Yesterday we saw a nasty attempt to use bitmasks in a loop.Today, we have Michele’s contribution, of a strange way of interacting with bitmasks. The culprit behind this code was a previous PLC programmer, even if this code wasn’t running straight on the PLC.
CodeSOD: A Bit Masked
The “for-case” or “loop-switch” anti-pattern creates some hard to maintain code. You know the drill: the first time through the loop, do one step, the next time through the loop, do a different step. It’s known as the “Anti-Duff’s Device”, which is a good contrast: Duff’s Device is a clever way to unroll a loop and turn it into a sequential process, while the “loop-switch” takes a sequential process and turns it into a loop.Ashlea inherited an MFC application. It was worked on by a number of developers in Germany, some of which used English to name identifiers, some which used German, creating a new language called “Deunglish”. Or “Engleutch”? Whatever you call it, Ashlea has helpfully translated all the identifiers into English for us.Buried deep in a thousand-line “do everything” method, there’s this block:
CodeSOD: CONDITION_FAILURE
Oliver Smith sends this representative line:
Error'd: Kind of...but not really
"On occasion, SQL Server Management Studio's estimates can be just a little bit off," writes Warrent B.
CodeSOD: A Quick Replacement
Lucio Crusca was doing a bit of security auditing when he found this pile of code, and it is indeed a pile. It is PHP, which doesn’t automatically make it bad, but it makes use of a feature of PHP so bad that they’ve deprecated it in recent versions: the create_function method.Before we even dig into this code, the create_function method takes a string, runs eval on it, and returns the name of the newly created anonymous function. Prior to PHP 5.3.0 this was their method of doing lambdas. And while the function is officially deprecated as of PHP 7.2.0… it’s not removed. You can still use it. And I’m sure a lot of code probably still does. Like this block…
Exponential Backup
The first day of a new job is always an adjustment. There's a fine line between explaining that you're unused to a procedure and constantly saying "At my old company...". After all, nobody wants to be that guy, right? So you proceed with caution, trying to learn before giving advice.But some things warrant the extra mile. When Samantha started her tenure at a mid-sized firm, it all started out fine. She got a computer right away, which is a nice plus. She met the team, got settled into a desk, and was given a list of passwords and important URLs to get situated. The usual stuff.After changing her Windows password, she decided to start by browsing the source code repository. This company used Subversion, so she went and downloaded the whole repo so she could see the structure. It took a while, so she got up and got some coffee; when she got back, it had finished, and she was able to see the total size: 300 GB. That's... weird. Really weird. Weirder still, when she glanced over the commit history, it only dated back a year or so.What could be taking so much space? Were they storing some huge binaries tucked away someplace that the code depended on? She didn't want to make waves, but this just seemed so... inefficiently huge. Now curious, she opened the repo, browsing the folder structure.Subversion bases everything on folder structure; there is only really one "branch" in Git's thinking, but you can check out any subfolder without taking the whole repository. Inside of each project directory was a layout that is common to SVN repos: a folder called "branches", a folder called "tags", and a folder called "trunk" (Subversion's primary branch). In the branches directory there were folders called "fix" and "feature", and in each of those there were copies of the source code stored under the names of the branches. Under normal work, she'd start her checkout from one of those branch folders, thus only pulling down the code for her branch, and merge into the "trunk" copy when she was all done.But there was one folder she didn't anticipate: "backups". Backups? But... this is version control. We can revert to an earlier version any time we want. What are the backups for? I must be misunderstanding. She opened one and was promptly horrified to find a series of zip files, dated monthly, all at revision 1.Now morbidly curious, Samantha opened one of these zips. The top level folder inside the zip was the name of the project; under that, she found branches, tags, trunk. No way. They can't have-- She clicked in, and there it was, plain as day: another backups folder. And inside? Every backup older than the one she'd clicked. Each backup included, presumably, every backup prior to that, meaning that in the backup for October, the backup from January was included nine times, the backup from February eight times, and so on and so forth. Within two years, a floppy disk worth of code would fill a terabyte drive.Samantha asked her boss, "What will you do when the repo gets too big to be downloaded onto your hard drive?His response was quick and entirely serious: "Well, we back it up, then we make a new one." [Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!
Yes == No
For decades, I worked in an industry where you were never allowed to say no to a user, no matter how ridiculous the request. You had to suck it up and figure out a way to deliver on insane requests, regardless of the technical debt they inflicted.Users are a funny breed. They say things like I don't care if the input dialog you have works; the last place I worked had a different dialog to do the same thing, and I want that dialog here! With only one user saying stuff like that, it's semi-tolerable. When you have 700+ users and each of them wants a different dialog to do the same thing, and nobody in management will say no, you need to start creating table-driven dialogs (x-y coordinates, width, height, label phrasing, field layout within the dialog, different input formats, fonts, colors and so forth). Multiply that by the number of dialogs in your application and it becomes needlessly pointlessly impossibly difficult.But it never stops there. Often, one user will request that you move a field from another dialog onto their dialog - just for them. This creates all sorts of havoc with validation logic. Multiply it by hundreds of users and you're basically creating a different application for each of them - each with its own validation logic, all in the same application.After just a single handful of users demanding changes like this, it can quickly become a nightmare. Worse, once it starts, the next user to whom you say no tells you that you did it for the other guy and so you have to do it for them too! After all, each user is the most important user, right?It doesn't matter that saying no is the right thing to do. It doesn't matter that it will put a zero-value load on development and debugging time. It doesn't matter that sucking up development time to do it means there are less development hours for bug fixes or actual features.When management refuses to say no, it can turn your code into a Pandora's-Box-o-WTFâ„¢However, there is hope. There is a way to tell the users no without actually sayingno. It's by getting them to say it for you and then withdrawing their urgent, can't-live-without-it, must-have-or-the-world-will-end request.You may ask how?The trick is to make them see the actual cost of implementing their teeny tiny little feature.
CodeSOD: CHashMap
There’s a phenomenon I think of as the “evolution of objects” and it impacts novice programmers. They start by having piles of variables named things like userName0, userName1, accountNum0, accountNum1, etc. This is awkward and cumbersome, and then they discover arrays. string* userNames, int[] accountNums. This is also awkward and cumbersome, and then they discover hash maps, and can do something like Map<string, string>* users. Most programmers go on to discover “wait, objects do that!”Not so Brian’s co-worker, Dagny. Dagny wanted to write some C++, but didn’t want to learn that pesky STL or have to master templates. Dagny also considered themselves a “performance junkie”, so they didn’t want to bloat their codebase with peer-reviewed and optimized code, and instead decided to invent that wheel themselves.Thus was born CHashMap. Now, Brian didn’t do us the favor of including any of the implementation of CHashMap, claiming he doesn’t want to “subject the readers to the nightmares that would inevitably arise from viewing this horror directly”. Important note for submitters: we want those nightmares.Instead, Brian shares with us how the CHashMap is used, and from that we can infer a great deal about how it was implemented. First, let’s simply look at some declarations:
Error'd: Version-itis
"No thanks, I'm holding out for version greater than or equal to 3.6 before upgrading," writes Geoff G.
CodeSOD: The Same Date
Oh, dates. Oh, dates in Java. They’re a bit of a dangerous mess, at least prior to Java 8. That’s why Java 8 created its own date-time libraries, and why JodaTime was the gold standard in Java date handling for many years.But it doesn’t really matter what date handling you do if you’re TRWTF. An Anonymous submitter passed along this method, which is meant to set the start and end date of a search range, based on a number of days:
CodeSOD: A Password Generator
Every programming language has a *bias* which informs their solutions. Object-oriented languages are biased towards objects, and all the things which follow on. Clojure is all about function application. Haskell is all about type algebra. Ruby is all about monkey-patching existing objects.In any language, these things can be taken too far. Java's infamous Spring framework leaps to mind. Perl, being biased towards regular expressions, has earned its reputation as being "write only" thanks to regex abuse.Gert sent us along some Perl code, and I was expecting to see regexes taken too far. To my shock, there weren't any regexes.Gert's co-worker needed to generate a random 6-digit PIN for a voicemail system. It didn't need to be cryptographically secure, repeats and zeros are allowed (they exist on a keypad, after all!). The Perl-approach for doing this would normally be something like:
An Obvious Requirement
Requirements. That magical set of instructions that tell you specifically what you need to build and test. Users can't be bothered to write them, and even if they could, they have no idea how to tell you what they want. It doesn't help that many developers are incapable of following instructions since they rarely exist, and when they do, they usually aren't worth the coffee-stained napkin upon which they're scribbled.That said, we try our best to build what we think our users need. We attempt to make it fairly straightforward to use what we build. The button marked Reports most likely leads to something to do with generating/reading/whatever-ing reports. Of course, sometimes a particular feature is buried several layers deep and requires multiple levels of ribbons, menus, sub-menus, dialogs, sub-dialogs and tabs before you find the checkbox you want. Since us developers as a group are, by nature, somewhat anal retentive, we try to keep related features grouped so that you can generally guess what path to try to find something. And we often supply a Help feature to tell you how to find it when you can't.Of course, some people simply cannot figure out how to use the software we build, no matter how sensibly it's laid out and organized, or how many hints and help features we provide. And there is nothing in the history of computer science that addresses how to change this. Nothing!Dimitri C. had a user who wanted a screen that performed several actions. The user provided requirements in the form of a printout of a similar dialog he had used in a previous application, along with a list of changes/colors/etc. They also provided some "helpful" suggestions, along the lines of, "It should be totally different, but exactly the same as the current application." Dimitri took pains to organize the actions and information in appropriate hierarchical groups. He laid out appropriate controls in a sensible way on the screen. He provided a tooltip for each control and a Help button.Shortly after delivery, a user called to complain that he couldn't find a particular feature. Dimitri asked "Have you tried using the Help button?" The user said that "I can't be bothered to read the instructions in the help tool because accessing this function should be obvious".Dimitri asked him "Have you looked on the screen for a control with the relevant name?" The user complained that "There are too many controls, and this function should be obvious". Dimitri asked "Did you try to hover your mouse over the controls to read the tooltips?" The user complained that "I don't have the time to do that because it would take too long!" (yet he had the time to complain).Frustrated, Dimitri replied "To make that more obvious, should I make these things less obvious?". The user complained that "Everything should be obvious". Dimitri asked how that could possibly be done, to which the user replied "I don't know, that's your job".When he realized that this user had no clue how to ask for what he wanted, he asked how this feature worked in previous programs, to which the user replied "I clicked this, then this, then this, then this, then this, then restarted the program".Dimitri responded that "That's six steps instead of the two in my program, and that would require you to reenter some of the data".The user responded "Yes, but it's obvious".So is the need to introduce that type of user to the business end of a clue-bat. [Advertisement] Ensure your software is built only once and then deployed consistently across environments, by packaging your applications and components. Learn how today!
CodeSOD: Philegex
Last week, I was doing some graphics programming without a graphics card. It was low resolution, so I went ahead and re-implemented a few key methods from the Open GL Shader Language in a fashion which was compatible with NumPy arrays. Lucky for me, I was able to draw off many years of experience, I understood both technologies, and they both have excellent documentation which made it easy. After dozens of lines of code, I was able to whip up some pretty flexible image generator functions. I knew the tools I needed, I understood how they worked, and while I was reinventing a wheel, I had a very specific reason.Philemon Eichin sends us some code from a point in his career where none of these things were true.Philemon was building a changelog editor. As such, he wanted an easy, flexible way to identify patterns in the text. Philemon knew that there was something that could do that job, but he didn’t know what it was called or how it was supposed to work. So, like all good programmers, Philemon went ahead and coded up what he needed- he invented his own regular expression language, and built his own parser for it.Thus was born Philegex. Philemon knew that regexes involved slashes, so in his language you needed to put a slash in front of every character you wanted to match exactly. He knew that it involved question marks, so he used the question mark as a wildcard which could match any character. That left the ’|" character to be optional.So, for example: /P/H/I/L/E/G/E/X|??? would match “PHILEGEX!!!” or “PHILEGEWTF”. A date could be described as: nnnn/.nn/.nn. (YYYY.MM.DD or YYYY.DD.MM)Living on his own isolated island without access to the Internet to attempt to google up “How to match patterns in text”, Philemon invented his own language for describing parts of a regular expression. This will be useful to interpret the code below.PhilegexRegexMaskableMatchesp1Pattern / RegexBlock(s)Token(s)CTCharTypeSplitLineParseRegexCCcurrentCharauf_zuopenParenthesisCharsCharClassificationWith the preamble out of the way, enjoy Philemon’s approach to regular expressions, implemented elegantly in VB.Net.
Error'd: Billboards Show Obvious Disasters
"Actually, this board is outside a casino in Sheffield which is next to the church, but we won't go there," writes Simon.
CodeSOD: If Not Null…
Robert needed to fetch some details about pump configurations from the backend. The API was poorly documented, but there were other places in the code which did that, so a quick search found this block:
The Search for Truth
Every time you change existing code, you break some other part of the system. You may not realize it, but you do. It may show up in the form of a broken unit test, but that presumes that a) said unit test exists, and b) it properly tests the aspect of the code you are changing. Sadly, more often than not, there is either no test to cover your change, or any test that does exist doesn't handle the case you are changing.This is especially true if the thing you are changing is simple. It is even more true when changing something as complex as working with a boolean.Mr A. was working at a large logistics firm that had an unusual error where a large online retailer was accidentally overcharged by millions of dollars. When large companies send packages to logistics hubs for shipment, they often send hundreds or thousands of them at a time on the same pallet, van or container (think about companies like Amazon). The more packages you send in these batches the less you pay (a single lorry is cheaper than a fleet of vans). These packages are lumped together and billed at a much lower rate than you or I would get.One day, a particular developer saw something untidy in the code - an uninitialized Boolean variable in one of the APIs. The entire code change was from this:
The Big Balls of…
The dependency graph of your application can provide a lot of insight into how objects call each other. In a well designed application, this is probably mostly acyclic and no one node on the graph has more than a handful of edges coming off of it. The kinds of applications we talk about here, on the other hand, we have a name for their graphs: the Enterprise Dependency and the Big Ball of Yarn.Thomas K introduces us to an entirely new iteration: The Big Ball of MandelbrotThis gives new meaning to points “on a complex plane”.What you’re seeing here is the relationship between stored procedures and tables. Circa 1995, when this application shambled into something resembling life, the thinking was, “If we put all the business logic in stored procedures, it’ll be easy to slap new GUIs on there as technology changes!”Of course, the relationship between what the user sees on the screen and the underlying logic which drives that display means that as they changed the GUI, they also needed to change the database. Over the course of 15 years, the single cohesive data model ubercomplexificaticfied itself as each customer needed a unique GUI with a unique feature set which mandated unique tables and stored procedures.By the time Thomas came along to start a pseudo-greenfield GUI in ASP.Net, the first and simplest feature he needed to implement involved calling a 3,000 line stored procedure which required over 100 parameters. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
Representative Line: The Truth About Comparisons
We often point to dates as one of the example data types which is so complicated that most developers can’t understand them. This is unfair, as pretty much every data type has weird quirks and edge cases which make for unexpected behaviors. Floating point rounding, integer overflows and underflows, various types of string representation…But file-not-founds excepted, people have to understand Booleans, right?Of course not. We’ve all seen code like:
Error'd: Placeholders-a-Plenty
"On my admittedly old and cheap phone, Google Maps seems to have confused the definition of the word 'trip'," writes Ivan.
CodeSOD: A Problematic Place
In programming, sometimes the ordering of your data matters. And sometimes the ordering doesn’t matter and it can be completely random. And sometimes… well, El Dorko found a case where it apparently matters that it doesn’t matter:
The Proprietary Format
Have you ever secured something with a lock? The intent is that at some point in the future, you'll use the requisite key to regain access to it. Of course, the underlying assumption is that you actually have the key. How do you open a lock once you've lost the key? That's when you need to get creative. Lock picks. Bolt cutters. Blow torch. GAU-8...In 2004, Ben S. went on a solo bicycle tour, and for reasons of weight, his only computer was a Handspring Visor Deluxe PDA running Palm OS. He had an external, folding keyboard that he would use to type his notes from each day of the trip. To keep these notes organized by day, he stored them in the Datebook (calendar) app as all-day events. The PDA would sync with a desktop computer using a Handspring-branded fork of the Palm Desktop software. The whole Datebook could then be exported as a text file from there. As such, Ben figured his notes were safe. After the trip ended, he bought a Windows PC that he had until 2010, but he never quite got around to exporting the text file. After he switched to using a Mac, he copied the files to the Mac and gave away the PC.Ten years later, he decided to go through all of the old notes, but he couldn't open the files!Uh oh.The Handspring company had gone out of business, and the software wouldn't run on the Mac. His parents had the Palm-branded version of the software on one of their older Macs, but Handspring used a different data file format that the Palm software couldn't open. His in-laws had an old Windows PC, and he was able to install the Handspring software, but it wouldn't even open without a physical device to sync with, so the file just couldn't be opened. Ben reluctantly gave up on ever accessing the notes again.Have you ever looked at something and then turned your head sideways, only to see it in a whole new light?One day, Ben was going through some old clutter and found a backup DVD-R he had made of the Windows PC before he had wiped its hard disk. He found the datebook.dat file and opened it in SublimeText. There he saw rows and rows of hexadecimal code arranged into tidy columns. However, in this case, the columns between the codes were not just on-screen formatting for readability, they were actual space characters! It was not a data file after all, it was a text file.The Handspring data file format was a text file containing hexadecimal code with spaces in it! He copied and pasted the entire file into an online hex-to-text converter (which ignored the spaces and line breaks), and voilà , Ben had his notes back! [Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.
CodeSOD: Breaking Changes
We talk a lot about the sort of wheels one shouldn’t reinvent. Loads of bad code stumbles down that path. Today, Mary sends us some code from their home-grown unit testing framework.Mary doesn’t have much to say about whatever case of Not Invented Here Syndrome brought things to this point. It’s especially notable that this is Python, which comes, out of the box, with a perfectly serviceable unittest module built in. Apparently not serviceable enough for their team, however, as Burt, the Lead Developer, wrote his own.His was Object Oriented. Each test case received a TestStepOutcome object as a parameter, and was expected to return that object. This meant you didn’t have to use those pesky, readable, and easily comprehensible assert… methods. Instead, you just did your test steps and called something like:
CodeSOD: All the Things!
Yasmin needed to fetch some data from a database for a report. Specifically, she needed to get all the order data. All of it. No matter how much there was.The required query might be long running, but it wouldn’t be complicated. By policy, every query needed to be implemented as a stored procedure. Yasmin, being a smart prograammer, decided to check and see if anybody had already implemented a stored procedure which did what she needed. She found one called GetAllOrders. Perfect! She tested it in her report.Yasmin expected 250,000 rows. She got 10.She checked the implementation.
Error'd: Surgeons, Put Down Your Scalpels
"I wonder what events, or lawsuits, lead TP-Link to add this warning presumably targeted individuals who updated firmware just ahead of performing medical procedures," writes Andrew.
To Suffer The Slings and Arrows of Vendor Products…
Being a software architect is a difficult task. Part of the skill is rote software design based upon the technology of choice. Part of it is the very soft "science" of knowing how much to design to make the software somewhat extensible without going so far as to design/build something that is overkill. An extreme version of this would be the inner platform effect.Way back when I was a somewhat new developer, I was tasked with adding a fairly large feature that required the addition of a database to our otherwise database-less application. I went to our in-team architect, described the problem, and asked him to request a modest database for us. At the time, Sybase was the in-house tool. He decreed that "Sybase sucks", and that he could build a better database solution himself. He would even make it more functional than Sybase.At the time, I didn't have a lot of experience, especially with databases, but intuition told me that Sybase had employed countless people for more than a decade to build and tweak Sybase. When I pointed this out, and the fact the it was unlikely that he was going to build a better database than all that effort - by himself - in only a few days, I received a full-on dressing down because I didn't know what was possible, and that a good architect could design and build anything. While I agreed that given enough time it might be possible, it was highly unlikely that it would happen in the next three days (because I needed time to do my coding against the database to meet the delivery schedule). I was instructed to wait and he would get it to me in time.My Spidy-Senseâ„¢ told me not to trust him, so I went to the DBAs that day and told them what I needed. Since I had little relevant experience with setting up a database, I told them of my inexperience with such things and asked them to optimize it with indices, etc. They created it for me that day. Since it was their implementation of my (DB) requirements, I knew that it would at least pass their review. I then coded the required feature and delivered on time. Was it perfect? No. Could it have been designed better? In retrospect, sure. But I was new to databases and it was fast enough for the need at the time.At every meeting for the next three months, our manager asked the architect how his Sybase-replacement was coming along. He sheepishly admitted that while it was coming along well, coming up with a design that would support all of the features provided by Sybase was proving to be a bit more involved than he had imagined, and that it would take a while longer.Several months after that, he was still making schematics and flow diagrams to try and build a new and improved Sybase.Our manager never did do anything to stop him from wasting time.As for me, I learned an important lesson about knowing when to write code, and when not to write code. [Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!
Sponsor Post: Make Your Apps Faster With Raygun APM
Your software is terrible, but that doesn’t make it special. All software is terrible, and yes, you know this is true. No matter how good you think it is, bugs and performance problems are inevitable.But it’s not just the ugly internals and mysterious hacks and the code equivalent of duct-tape and chewing gum which make your software terrible. Your software exists to fill some need for your users, and how do you know that’s happening? And worse, when your application fails, how do you understand what happened?In the past, we’ve brought your attention to Raygun, which allows you to add a real-time feedback loop that gives you a picture of exactly what’s happening on their device or their browser. And now, Raygun is making it even better, with Raygun APM.Raygun Application Performance Monitoring (APM) tackles the absolute worst part of releasing/supporting applications: dealing with performance issues. With Raygun APM, you can get real-time execution stats on your server-side code, and find out quickly which specific function, line, or database call is slowing down your application.You won’t have to wait for someone to notice the issue, either- Raygun APM proactively identifies performance issues and builds a workflow for solving them. Raygun APM sorts through the mountains of data for you, surfacing the most important issues so they can be prioritized, triaged and acted on, cutting your Mean Time to Resolution (MTTR) and keeping your users happy.In addition to all this, Raygun is adding tight integration with source control, starting with GitHub.Request access to the beta here. Or if you’re already tired of searching logs for clues in an effort to replicate an issue, try out Raygun’s current offerings and resolve errors, crashes and performance issues with greater speed and accuracy. [Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!
A Comment on the Military Industrial Complex
Simon T tugged at his collar when the video played. It wasn’t much, just a video of their software being tested. It wasn’t the first time they’d tested Simon’s most recent patch, but it was going to be the last time. There were a lot of eyes in the conference room, and they were all turned on him.Simon worked for the kind of company which made missiles. The test in the video was one of the highly expensive tests of a real missile under real-world conditions. Several of these had already been done with this software package, so Simon hadn’t expected any problems to crop up. In this case, though, the missile left its launcher and sailed in a perfect parabolic arc into the ground 5 meters away from the launch site.Missiles diving headfirst into the ground mere meters from their launch site was officially considered a bad thing. There were all sorts of checkpoints and automated tests and simulations that were supposed to keep this thing from happening. It didn’t take long to find the problem.
CodeSOD: Without Context
When writing up a Code SOD, a big part of the goal is to provide context for the bad code. Why is it bad, what would be better,, etc. In other words, we need to… ShowContext. Vasco O has exactly the method for that.
...34353637383940414243...