Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2024-11-26 06:31
Representative Line: Constantly True
An anonymous reader had something to share."I came across this code in a 13,000 line file called Constants.cs."
Error'd: What the Truck?!
"I think I'll order the big-busted truck," writes Alicia.
CodeSOD: The Mike Test
The Joel Test is about to turn 18 this year. Folks have attempted to “update” it, but even after graduating high school, the test remains a good starting point for identifying a “good” team.Mike was impressed to discover a PHP script which manages to fail a number of points on the Joel Test in only 8 lines.
CodeSOD: Fortran the Undying
There are certain languages which are still in use, are still changing and maturing, and yet are also frozen in time. Fortran is a perfect example- over the past 40–60 years, huge piles of code, mostly for scientific and engineering applications, was written. It may be hard to believe, but modern Fortran supports object-oriented programming and has a focus on concurrency.Most of the people using Fortran, it seems, learned it in the 70s. And no matter what happens to the language, they still write code like it’s the 70s. Fortran’s own seeming immortality has imbued its users with necromantic energy, turning them into undying, and unchanging Liches.Which brings us to Greg. Greg works with an engineer. This engineer, the Dark Lich Thraubagh, has a personal “spellbook” containing snippets of Fortran they’ve picked up over the past 40 years. For example, there’s this block, which creates an array of every number from 1–999, padded out to three characters.I don’t know Fortran, so I give credit to this engineer/lich for writing code which even I can understand why it’s wrong and bad.
Undermining the Boss
During the browser wars of the late 90's, I worked for a company that believed that security had to consist of something you have and something you know. As an example, you must have a valid site certificate, and know your login and password. If all three are valid, you get in. Limiting retry attempts would preclude automated hack attempts. The security (mainframe) team officially deemed this good enough to thwart any threat that might come from outside our firewall.As people moved away from working on mainframes to working on PCs, it became more difficult to get current site certificates to every user every three months (security team mandate). The security team decreed that e/snail-mail was not considered secure enough, so a representative of our company had to fly to every client company, go to every user PC and insert a disk to install the latest site certificate. Every three months. Ad infinitum.You might imagine that this quickly became a rather significant expense for the business (and you'd be right), so they asked our department to come up with something less costly.After a month of designing, our crack engineers came up with something that would cost several million dollars and take more than a year to build. I tried, but failed to stifle a chuckle. I told them that I could do it for $1500 (software license) and about two days of work. Naturally, this caused a wave of laughter, but the boss+1 in charge asked me to explain.I said that we could put an old PC running a web server outside the firewall and manually dump all the site certificate installer programs on it. Then we could give the help desk a simple web page to create a DB entry that would allow our users to go to that PC, load the single available page to enter the unique code provided by the help desk, and get back a link to download a self-installing program to install the site certificate.To preempt the inevitable concerns, I pointed out that while I had some knowledge of how to secure PCs and databases, that I was not by any means an expert, but that our Security Analysts (SAs) and DBAs were. We could have the SA's strip out all but the most necessary services, and clamp down the firewall rules to only let it access a dedicated DB on an internal machine on a specific port. The DBA's could lock down the dedicated DB with a single table to only allow read access from the web page; to pass in the magic phrase and optionally spit back a link to download the file.Of course, everyone complained that the PC in-the-wild would be subject to hacking.Since I believe in hoping for the best but planning for the worst, I suggested that we look at the worst possible case. I take out a full page ad in Hacker's Weekly saying "Free site certificates on exposed PC at IP a.b.c.d. They can be used at http://www.OurCompany.com. Enjoy!" After all, it can't get worse than that, right? So Mr. Hacker goes to the page and downloads the site certificate installation programs for every user and then goes to our website. What's the first thing he faces? Something he has and something he knows. He has the certificates, but doesn't know any login/passwords. Since the security people have already blessed this as "Good Enough", we should be safe.After much discussion, everyone agreed that this made sense, but that they (reasonably) wanted to verify it. It was agreed that the SA's and DBA's had the needed expertise to strip and lock down the PC, firewall and DB. I took an old PC out of one of the closets, did a fresh install, put on the latest web server and relevant software, and then installed the few things we needed. Then I handed it to the SA's and told them to strip it and lock it down. I created a tiny DB with a single table and two stored procedures; one for the help desk to add a new time-limited entry for a user and the other to check to see if an unexpired entry existed and return a link to the installer on the exposed PC. Then I handed it to the DBA's and told them to restrict it so the table could only be accessed via the two stored procs, and to only allow the Help desk to call the proc that created the time limited entry for the user, and the external IP to call the proc to query the table. Since all of our users already had credentials to call the help desk, this was only a minimal additional cost.We threw a couple of test certificate installers on it and put it outside the firewall. After I tested the "good" paths, I had the SA's and DBA's try to hack around their restrictions. When they couldn't, it was deemed safe and loaded up with all the certificates. I wrote up a very short how-to manual and had it installed in production.This reduced the certificate installations to one trip per quarter to our data center.The user was pleased at having saved millions of dollars on an ongoing basis.I found out later that I inadvertently pissed off the boss+1 because he was planning on hiring more people for this project and I negated the need for him to expand his empire.Whoops. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Old Lennart
Gustav's tech support job became a whole lot easier when remote support technology took off. Instead of having to slowly describe the remedy for a problem to a computer-illiterate twit, he could connect to their PC and fix it himself. The magical application known as TeamViewer was his new best friend.Through Gustav's employer's support contract with CAD+, a small engineering design firm, he came to know Roger. The higher-ups at CAD+ decided to outsource most of their IT work and laid off everyone except Roger, who was to stay on as liaison to Gustav and Co. Roger was the type whose confidence in his work did not come close to matching the quality of it. He still felt like he could accomplish projects on his own without any outside help. Thanks to that, Gustav had to get him out of a jam several times early in their contract.Roger's latest folly was upgrading all of the office workstations from the disaster that was Windows Vista to the much more reliable Windows 7. "I had such a smooth rollout to Windows 7, I tell ya," Roger bragged over the phone. "I brilliantly used this cloning process to avoid installing the same things repeatedly!" Gustav rolled his eyes while wondering if this was a support call or if Roger just needed someone to talk to. "Well anywho, I had two system images - one with the basic software everyone gets, and one that included SolidWorks for our CAD designers. Seems they don't have SolidWorks even though I installed it. Can you do your support wizardry and take a look?"Gustav agreed and was transferred to Dave, their lead CAD designer. He figured Dave just didn't know where to find SolidWorks on the new OS and it would be a quick call. He got Dave's TeamViewer ID and connected to his PC in no time. He decided to ignore the fact that Dave had a browser open to an article about the twenty greatest Michael Bolton songs of all time."Thanks Dave, I'm in. Are you able to see me moving your mouse?" Gustav asked. He wasn't. "Ok then, there must be some lag here. I'm going to look around to find where you have SolidWorks and make a shortcut for you." Gustav spent the next few minutes looking at the places any sane person would install SolidWorks. Since Roger wasn't sane, he didn't find it in a logical directory. He then went to Programs and Features and noticed that it wasn't installed anywhere."Hey Dave, bad news," Gustav informed. "It seems like your PC got the wrong image from Roger and your CAD software isn't on there.""Bummer. I didn't know if you were doing anything, on my side the computer screen was just sitting there," Dave replied, just as an incredible ruckus broke out behind him. Gustav could hear doors slamming and someone cursing at Roger in the background. Dave chuckled quietly into the phone."... is everything ok there?" Gustav asked, concerned."Oh, that's just Old Lennart throwing a fit. He's our cranky old Vice President. He's super pissed because Roger keeps hacking his computer and messing around on it."Gustav suddenly had a suspicion. "Dave, don't take this the wrong way, but were you reading an article about Michael Bolton's greatest hits?" he asked cautiously."Hell no, why would I be doing that?" Dave shot back, almost sounding insulted. Gustav apologized and quickly ended their call.Once Roger was done getting chewed out by Old Lennart, Gustav gave him a call. In their discussion, Roger revealed how he'd installed TeamViewer before making his system clones to save time. Gustav explained how that caused every system image to have the same TeamViewer ID, which was bad. Since Old Lennart was always the first one in the office each morning, any remote connection through TeamViewer would connect to his PC. Thus, whenever Gustav or one of his cohorts connected for remote support, it seemed like someone was hacking in to Lennart's computer.Roger remedied the problem over the next couple days by reinstalling TeamViewer and bringing in a series of "I'm sorry" baked goods for Old Lennart; but it wasn't enough to save his hide. By the end of the week, he was informed that their IT department would be further reduced from one employee to zero. With his computer and Roger problems addressed, Old Lennart could return to researching his favorite performing artist. [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.
Error'd: When BSODs Pile Up
"I suppose the ropes were there to keep the infection from spreading to other screens," Stan I. wrote.
CodeSOD: An Incomparable Event
Sandra’s ongoing battles continue. She currently works for Initrovent, and is doing her best to clean Karl’s dirty fingerprints off their event-planning codebase.Now, as it turns out, Karl wasn’t their only developer. Another previous developer was a physicist who knew their way around APL and Fortran, then decided to follow the early 2000s money and became a self-taught web developer.This Einstein decided to solve some problems, common problems, utility problems, the kind of things you might want to put in your central library and reuse in every project.For example, do you hate comparisons? Does writing if ($x == $y)… make your skin crawl? Don’t you just wish you could write something like, compareValues($x, $y, '==') instead?Well, have I got news for you.
Finding Your Strong Suit
Anyone with more than a few years of experience has been called upon to interview candidates for a newly opened/vacated position. There are many different approaches to conducting an interview, including guessing games, gauntlets and barrages of rapid-fire questions to see how much of the internet the candidate has memorized.
Announcements: Come Work at Inedo, the Most Non-WTF Company You Know
The "Enterprise DevOps" tools market has really been taking off lately, and so has Inedo! We build market-leading tools for package management, deployment automation, and configuration automation space that aids some of the world's best companies in delivering their applications to users faster than ever.We're looking for some great people to help us continue to grow:
You'd Need an Oracle to Understand These Docs
Documentation is difficult in the best of situations. I've encountered lots of bad documentation. Bad because it's unclear, inaccurate, or incomprehensible. Bad because it's non-existent. Bad because it insists on strictly using the vendor's own in-house terms, carefully chosen to be the most twee little metaphors they could imagine, but never explains those terms, thus being both incomprehensible and infuriating. "Enterprise" packages bring their own quirks and foibles, and tend to be some combination of unclear, inaccurate, or incomprehensible. Unless, sometimes, what we attribute to incompetence probably is actual malice.I've brushed up against a lot of ERP systems in may day, ranging from the home-(over)-grown Excel spreadsheet on the network drive all the way to gigundous SAP build-outs.On such project involved migrating 12 business units from a mixture of home-grown systems, legacy mainframe systems, and home-grown systems running on legacy mainframes into one, single, cohesive ERP. The product chosen was an offering from a company we'll call "Augur". Augur took one look at our insanely ambitious project, knew it was doomed to failure, and muttered to themselves, "Think about the consulting fees we can rack up!"Of course, my employer didn't want to pay the consulting fees. They already had Augur domain experts hired in from a much cheaper consultancy, and our in-house developers knew how to read documentation. What could go wrong?Plenty, but one of the smaller, simpler tasks I tackled delivered the biggest WTF. In a factory, there was a flow meter hooked up to a pipe that could tell us how much raw material flowed through that pipe. That flow meter was hooked up to a proprietary database with a very picky and flaky ODBC driver. I needed to get data out of the proprietary database and pass it off, after a little massaging, to Augur's ERP. Based on whatever product the ERP believed was being made at the time, it would then calculate raw material consumption, cost-of-goods-sold (COGS), losses, and all sorts of other wonderful production statistics.Talking to the proprietary database involved some DLL hell, but once I was getting the data, it was time to feed it into Augur. The documentation for their consumption APIs said that I should call a method called RM_CONS_IN_FRMLU_FPT. It told me how to structure the data. It told me what other parameters needed to be set. I followed the instructions and checked the results: consumption got updated, but not COGS.I checked my work. I rechecked the documentation. I skimmed through the underlying tables to understand the schema hiding beneath the API. I cried a little when I saw it, and then I went back to the docs. I twiddled a few parameters, and tried again. This time COGS was right, but consumption wasn't. Tried again, and now it refused to recognize the current production formula, and assumed I was just disposing of material, and only incremented my losses.Eventually, I discover that RM_CONS_IN_FRMLU_FPT is actually a wrapper method for RM_FPT_CONS_BY_UT. I have to bootstrap a few more complex parameters myself, but I try again. Still doesn't works. Back to the docs, and then I notice a tiny little footnote: "To calculate COGS accurately, the parameter rec_cons_config must have its cogs_behavior property set to 57". So I tried that.It crashed. It didn't just crash, though, it managed to go romping off down a bad code branch, mangled a bunch of records, committed the changes, and then crashed. I reset my dev environment and went back to the docs.This time, I trace through a few references, discover another footnote which is itself reference to a white paper, which itself contains a footnote. "If cogs_behavior is set,RM_CONS_BY_UT,RM_CONS_IN_FRMLU_FPT,RM_CALC_FRMLUandCOGS_RM_CALC_USAGE may alter data in an unrecoverable fashion."Now, Augur's database technology separates the header for a code package from the body. This is great for Augur, as they can distribute the compiled versions of their proprietary stored procedures, but not the code. That was less great for me, as I couldn't just read the code to see what it was doing, but I could read the headers.And there were so many undocumented parameters, each using undocumented record data types- Augur's equivalent of a struct. Tracing through the headers, I eventually found that there was a flag which was, for all intents and purposes, the secret_make_cogs_work_flag. I flipped that to true, and voila, suddenly everything was calculating.I can't say, beyond a shadow of a doubt, that the documentation lied to me. It could have been wrong, outdated, or I could have just misread things. But given the problem- a major feature doesn't work or even destroys data- and given the simplicity of the fix, I can't see it as anything but an active attempt to mislead."Never attribute to malice what could be explained by incompetence- unless it's a major enterprise product vendor, in which case they really just want to sell you consulting." [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
NoeTimeToken
"Have you had a chance to look at that JIRA ticket yet?"Marge debated pretending she hadn't seen the Slack message yet—but, if she did, she knew Gary would just walk over to her desk and badger her further. In truth, she didn't want to look at the ticket: it was a low priority ticket, and worse, it only affected a small fraction of one client's customers, meaning it was likely to be some weird edge case bug nobody would ever run into again. Maybe if I ignore it long enough, it'll go away on its own, she thought.The client was a bookseller with a small but signifigant-to-them online presence; the software they used to sell books, including your standard e-commerce account functionality, was made by Marge's company. The bug was somewhere in the password reset feature: some customers, seemingly at random, were unable to use the password reset link the software emailed out.Marge pulled up the ticket, looking over the half-hearted triage work that had been done before it landed on her desk to solve. The previous guy had pulled logs and figured out that all the customers who were complaining were using the same ISP based out of Germany. He'd recommended reaching out to them, but had been transferred to another division before he'd gotten around to it.When Marge realized that the contact information was all in German, she almost gave up then and there. But with the magic of Google Translate, she managed to get in touch with a representative via email. After a bit of back and forth, she noticed this gem in one of his (translated) replies:
Error'd: Upon Reaching a Certain Age...
"Evidently, once you hit 55, LinkedIn thinks you'll age until your buffer overflows," writes Jonathan L.
Classic WTF: Flawless Compilation
Classic WTF: The Mega Bureaucracy
Classic WTF: The Source Control Shingle
Classic WTF: The Virtudyne Saga
Error'd: All the Way from Sweden
"And to think, this price doesn't include assembly," wrote Adam G.
CodeSOD: A Symbol of Bad Code
As developers, when we send data over the network, we can usually safely ignore the physical implementation of that network. At some level, though, the bits you’re sending become physical effects in your transmission medium, whether it’s radio waves or electrical signals.You can’t just send raw bits over the wire. Those bits have to be converted into a symbol suitable for the transmission medium. Symbols could be the dots-and-dashes of morse code, tones transmitted over a phone line, or changing duty cycles on a pulse-width-modulated signal. The number of symbols per second is the baud rate of the channel. What this means for digital transmission is that even if your channel has a potential bit rate of one gigabit per second, the actual baud rate may be different- either much larger or much smaller. For example, modems might send 4-bits per symbol, meaning a 2,400 baud modem actually can transmit 9,600 bits per second. GPS, on the other hand, can transmit 50 bits/s, but over one million symbols per second thanks to spread spectrum broadcast.Marnie works for a telcoms company which greatly cares about these sorts of details. There’s a variety of client-side web apps which accrued over time which can help with things like symbol rate calculations.For their environment, this calculation is straightforward: whatever the bits-per-second of the channel is, divide by 1.25 to find the symbol rate. Of course, this simple calculation can’t be performed without regexes. Marnie found this code in the code base:
Reproducible Heisenbug
Matt had just wrapped up work on a demo program for an IDE his company had been selling for the past few years. It was something many customers had requested, believing the documentation wasn't illustrative enough. Matt's program would exhibit the IDE's capabilities and also provide sample code to help others get started on their own creations.It was now time for the testers to do their thing with the demo app. Following the QA team's instructions, Matt changed the Debug parameter in the configuration file from 4 (full debugging) to 1 (no debugging). Build and deploy completed without a hitch. Matt sent off the WAR file, feeling good about his programming aptitude and life in general.And then his desk phone rang. The caller ID revealed it was Ibrahim, one of the testers down in QA.Already? Matt wondered. With a mix of confusion and annoyance, he picked up the phone, assuming it was something PEBKAC-related."I've got no descriptors for the checkboxes on the main page," Ibrahim told him. "And the page after that has been built all skew-whiff.""Huh?" Matt frowned. "Everything works fine on my side."What could be different about Ibrahim's setup? The first thing Matt thought of was that he'd disabled debugging before building the WAR file for QA.That can't be it! But it was easy enough to test."Hang on one sec here." Matt muted his phone, then changed the Debug parameter on his local deployment from 4 to 1. Indeed, upon refreshing, the user interface went wonky, just as Ibrahim had described. Unfortunately, with debugging off, Matt couldn't check the logs for a clue as to what was going wrong.Back on the phone, Matt explained how he was able to do reproduce the problem, then instructed Ibrahim on manually hacking the WAR file to change the Debug parameter. Ibrahim reported that with full debugging enabled, the program worked perfectly on his end."OK. Lemme see what I can do," Matt said, trying not to sound as hopeless as he felt.With absolutely no hints to guide him, Matt spent hours stepping through his code to figure out what was going wrong. At long last, he isolated a misbehaving repeat-until loop. When the Debug parameter was set to 4, the program exited the loop and returned data as expected. But when Debug was set to anything less than 4, it made an extra increment of the loop counter, leading to the graphical mayhem experienced earlier.Horror crept down Matt's spine. This problem would affect anyone using repeat-until loops in conjunction with the IDE. Such programs were bound to fail in unexpected ways. He immediately issued a bug report, suggesting this needed to be addressed urgently.Later that day, he received an email from one of the IDE developers. I found where it was testing the wrong boolean. Should we raise this as a defect?"Yes! Duh!" Matt grumbled out loud, then took to typing. And can we find out where this bug crept in? All projects released since that time are compromised!!As it turned out, the bug had been introduced to the IDE 2 years earlier. It'd been found almost immediately and fixed. Unfortunately, it'd only been fixed in one specific branch within source control—a branch that had never been merged to the trunk. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
CodeSOD: Is the Table Empty?
Sean has a lucrative career as a consultant/contractor. As such, he spends a great deal of time in other people’s code bases, and finds things like a method with this signature:public boolean isTableEmpty()Already, you’re in trouble. Methods which operate directly on “tables” are a code-smell, yes, even in a data-driven application. You want to operate on business objects, and unless you’re a furniture store, tables are not business objects. You might think in those terms when building some of your lower-level components, but then you’d expect to see things like string tableName in the parameter list.Now, maybe I’m just being opinionated. Maybe there’s a perfectly valid reason to build a method like this that I can’t imagine. Well, let’s check the implementation.
Walking on the Sun
In 1992, I worked at a shop that was all SunOS. Most people had a Sparc-1. Production boxes were the mighty Sparc-2, and secretaries had the lowly Sun 360. Somewhat typical hardware for the day.Sun was giving birth to their brand spanking new Solaris, and was pushing everyone to convert from SunOS. As with any OS change in a large shop, it doesn't just happen; migration planning needs to occur. All of our in-house software needed to be ported to the new Operating System.This planning boiled down to: assign it to snoofle; let him figure it out.This was before Sun made OpCom available to help people do their migrations.I took the latest official code, opened an editor, grepped through the include files and compiled, for each OS. Then I went into a nine month long compile-edit-build cycle, noting the specifics of each item that required different include files/syntax/whatever. Basically, Sun had removed the Berkeley libraries when they first put out Solaris, so everything signal or messaging related had to change.Finally, I naively thought the pain was over; it compiled. I had coalesced countless functions that had nearly identical multiple versions, deleted numerous blocks of dead code, and reduced 1.4 million LOC to about 700K. Then began the debugging cycle. That took about 3 weeks.Then I was told not to merge it because another subteam in our group was doing a 9-month sub-project and couldn't be interrupted. Naturally, they were working in the main branch, which forced me to keep pulling and porting their code into mine several times a week, for months. Ironically, they were constantly changing dead code as part of trying to fix their own code.You can only do this for so long before getting fed up; I'd had it and let it be known to boss+1 (who was pushing for Solaris) that this had to end. He set a date three months out, at which time I would do the merge and commit; other tasks be damned! The subteam was repeatedly informed of this drop-dead date.So I put up with it for 3 months, then did the final merge; over 3,500 diffs. I went through them all, praying the power wouldn't cut out. After fixing a few typos and running the cursory test, I held my breath and committed. Then I told everyone to pull and merge.It turns out that I missed 3 little bugs, but they were suffiently visible that it prevented the application from doing anything useful. The manager of the sub-team ordered me to roll it back because they were busy. I handed her the written memo from B+1 ordering me to do it on this date and told her to suck it up and give me a chance to debug it.An hour later, it was working and committed.I instructed everyone to pull and build, and to follow the instructions in my handout for coding going forward. Anything that broke the Solaris build would be summarily rolled back per orders from B+1.It took a few months and hundreds of rollbacks for them to start to follow my instructions, but when they finally did, the problems ceased.Then the managers from the other teams took my instructions and all my global edit scripts (it wasn't a perfect parser, but it at least left syntax errors if it tried to change code that was really badly formatted, so you could trivially find them and fix them very quickly).Using my scripts and cheat sheets, my peers on the other projects managed to do their ports in just a couple of hours, and mercilessly rode me about it for the next 3 years. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
Error'd: Is Null News Good News?
"The Eugene (Oregon) Register-Guard knows when it's a slow news day, null happens," Bill T. writes.
CodeSOD: To Read or Parse
When JSON started to displace XML as the default data format for the web, my initial reaction was, "Oh, thank goodness." Time passed, and people reinvented schemas for JSON and RPC APIs in JSON and wrote tools which turn JSON schemas into UIs and built databases which store BSON, which is JSON with extra steps, and… it makes you wonder what it was all for.Then people like Mark send in some code with a subject, "WHY??!??!". It's code which handles some XML, in C#.Now, a useful fact- C# has a rich set of API- for handling XML, and like most XML APIs, they implement two approaches.The simplest and most obvious is the DOM-style approach, where you load an entire XML document into memory and construct a DOM out of it. It's easy to manipulate, but for large XML documents can strain the available memory.The other is the "reader" approach, where you treat the document as a stream, and read through the document, one element at a time. This is a bit trickier for developers, but scales better to large XML files.So let's say that you're reading a multi-gigabyte XML file. You'd want to quit your job, obviously. But assuming you didn't, you'd want to use the "reader" approach, yes? There's just one problem: the reader approach requires you to go through the document element-by-element, and you can't skip around easily.
Classic WTF: Common Sense Not Found
Flobble
The Inner Platform Effect, third only after booleans and dates, is one of the most complicated blunders that so-called developers (who think that they know what they're doing) do to Make Things Better.â„¢ Combine that with multiple inheritance run-amok and a smartass junior developer who thinks documentation and method naming are good places to be cute, and you get todays' submission.Chops,an experienced C++ developer somewhere in Europe, was working on their flagship product. It had been built slowly over 15 years by a core of 2-3 main developers, and an accompanying rotating cast of enthusiastic but inexperienced C++ developers. The principal developer had been one of those juniors himself at the start of development. When he finally left, an awful lot of knowledge walked out the door with him.Enormous amounts of what should have been standard tools were homegrown. Homegrown reference counting was a particular bugbear, being thread dangerous as it was - memory leaks abounded. The whole thing ran across a network, and there were a half-dozen ways any one part could communicate with another. One such way was a "system event". A new message object was created and then just launched into the underlying messaging framework, in the hopes that it would magically get to whoever was interested, so long as that other party had registered an interest (not always the case).A new system event was needed, and a trawl was made for anyone who knew anything about them. <Crickets> Nobody had any idea how they worked, or how to make a new one. The documentation was raked over, but it was found to mostly be people complaining that there was no documentation. The code suffered from inheritance fever. In a sensible system, there would be only one message type, and one would simply tag it appropriately with an identifier before inserting the data of interest.In this system, there was an abstract base message type, and every specific message type had to inherit from it, implement some of the functions and override some others. Unfortunately, each time it seemed to be a different set of functions being implemented and a different set being overridden. Some were clearly cut and paste jobs, copying others, carrying their mistakes forward. Some were made out of several pieces of others; cut, paste and compiled until the warning messages were disabled compiler stopped complaining.Sometimes, when developing abstract base types that were intended to be inherited from to create a concrete class for a new purpose, those early developers had created a simple, barebones concrete example implementation. A reference implementation, with "Example" in the name, that could be used as a starting point, with comments, making it clear what was necessary and what was optional. No such example class could be found for this.Weeks of effort went into reverse-engineering the required messaging functionality, based on a few semi-related examples. Slowly, the shape of the mutant inside became apparent. Simple, do-nothing message objects were created and tested. Each time they failed, the logs were pored over, breakpoints were added, networks were watched, tracing the point of failure and learning something new.Finally, the new message object was finished. It worked. There was still some voodoo coding in it; magic incantations that were not understood (the inheritance chain was more than five levels deep, with multiple diamonds, and one class being inherited from six times), but it worked, although nobody was certain why.During the post development documentation phase, Mister Chops was hunting down every existing message object. Each would need reviewing and examination at some point, with the benefit of the very expensive reverse engineering. He came across one with an odd name; it wasn't used anywhere, so hadn't been touched since it was first committed. Nobody had ever had a reason to look at it. The prefix of the name was as expected, but the suffix - the part that told you at a glance what kind of message it was - was "Flobble". Chops opened it up.It was a barebones example of a concrete implementation of the abstract base class, with useful explanatory comments on how to use/extend it, and how it worked. Back at the start, some developer, instead of naming the example class "Example" as was customary, or naming it anything at all that would have made it clear what it was, had named it "Flobble". It sat there for a decade, while people struggled to understand these objects over and over, and finally reverse engineered it at *significant* expense. Because some whimsical developer a decade previously had decided to be funny. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
CodeSOD: An Eventful Career Continues
You may remember Sandra from her rather inglorious start at Initrovent. She didn't intend to continue working for Karl for very long, but she also didn't run out the door screaming. Perhaps she should have, but if she had- we wouldn't have this code.Initrovent was an event-planning company, and thus needed to manage events, shows, and spaces. They wrote their own exotic suite of software to manage that task.This code predates their current source control system, and thus it lacks any way to blame the person responsible. Karl, however, was happy to point out that he used to do Sandra's job, and he knew a thing or two about programming. "My fingerprints are on pretty much every line of code," he was proud to say.
Error'd: Testing English in Production
Philip G. writes, "I found this gem when I was on the 'Windows USB/DVD Download Tool' page (yes, I know Rufus is better) and I decided to increment the number in the URL."
CodeSOD: Foggy about Security
Maverick StClare’s company recently adopted a new, SaaS solution for resource planning. Like most such solutions, it was pushed from above without regard to how people actually worked, and thus required the users to enter highly structured data into free-form, validation-free, text fields. That was dumb, so someone asked Maverick: “Hey, could you maybe write a program to enter the data for us?”Well, you’ll be shocked to learn that there was no API, but the web pages themselves all looked pretty simple and the design implied they hadn’t changed since IE4, so Maverick decided to take a crack at writing a scraper. Step one: log in. Easy, right? Maverick fired up a trace on the HTTPS traffic and sniffed the requests. He was happy to see that his password wasn’t sent in plain text. He was less happy to see that it wasn’t sent using any of the standard HTTP authentication mechanisms, and it certainly wasn’t hashed using any algorithm he recognized. He dug into the code, and found this:
Representative Line: Got Your Number
You have a string. It contains numbers. You want to turn those numbers into all “0”s, presumably to anonymize them. You’re also an utter incompetent. What do you do?You already know what they do. Jane’s co-worker encountered this solution, and she tells us that the language was “Visual BASIC, Profanity”.
CodeSOD: External SQL
"Externalize your strings" is generally good advice. Maybe you pull them up into constants, maybe you move them into a resource file, but putting a barrier between your code and the strings you output makes everything more flexible.But what about strings that aren't output? Things like, oh… database queries? We want to be cautious about embedding SQL directly into our application code, but our SQL code often is our business logic, so it makes sense to inline it. Most data access layers end up trying to abstract the details of SQL behind method calls, whether it's just a simple repository or an advanced ORM approach.Sean found a… unique approach to resolving this tension in some Java code he inherited. He saw lots of references to keys in a hash-map, keys like user or pw or insert_account_table or select_all_transaction_table. But where did these keys get defined?Like all good strings, they were externalized into a file called sql.txt. A simple regex-based parser loaded the data and created the dictionary. Now, any module which wanted to query the database had a map of any query they could possibly want to run. Just chuck 'em into a PreparedStatement object and you're ready to go.Here, in its entirety, is the sql.txt file.
A Hard SQL Error
Padma was the new guy on the team, and that sucked. When you're the new guy, but you're not new to the field, there's this maddening combination of factors that can make onboarding rough: a combination of not knowing the product well enough to be efficient, but knowing your craft well enough to expect efficiency. After all, if you're a new intern, you can throw back general-purpose tutorials and feel like you're learning new things at least. When you're a senior trying to make sense of your new company's dizzying array of under-documented products? The only way to get that knowledge is by dragging people who are already efficient away from what they're doing to ask.By the start of week 2, however, Padma knew enough to get his hands dirty with some smaller bug-fixes. By the end of it, he'd begun browsing the company bug tracker looking for more work on his own. That's when he came across this bug report that seemed rather urgent:It had been in the tracker for a month. That could mean a lot of things, all of them opaque when you're new enough not to know anyone. Was it impossible to reproduce? Was it one of those reports thrown in by someone who liked to tamper with their test environment and blame things breaking on the coders? Was their survey product just low priority enough that they hadn't gotten around to fixing it? Which client was this for?It took Padma a few hours to dig into it enough to get to the root of the problem. The repository for their survey product was stored in their private github, one of dozens of repositories with opaque names. He found the codename of the product, "Santiago," by reading older tickets filed against the same product, before someone had renamed the tag to "Survey Deluxe." There was a branch for every client, an empty Master branch, and a Development branch as the default; he reached back out to the reporter for the name of the client so he could pull up their branch. Of course they had a "clientname" branch, a "clientname-new," and a "clientname3.0," but after comparing merge histories, he eventually discovered the production code: in a totally different branch, after they had merged two clients' environments together for a joint venture. Of course.But finally, he had the problem reproduced in his local dev environment. After an hour of digging through folders, he found the responsible code:
Error'd: Be Patient!...OK?
"I used to feel nervous when making payments online, but now I feel ...um...'Close' about it," writes Jeff K.
Wait Low Down
As mentioned previously I’ve been doing a bit of coding for microcontrollers lately. Coming from the world of desktop and web programming, it’s downright revelatory. With no other code running, and no operating system, I can use every cycle on a 16MHz chip, which suddenly seems blazing fast. You might have to worry about hardware interrupts- in fact I had to swap serial connection libraries out because the one we were using misused interrupts and threw of the timing of my process.And boy, timing is amazing when you’re the only thing running on the CPU. I was controlling some LEDs and if I just went in a smooth ramp from one brightness level to the other, the output would be ugly steps instead of a smooth fade. I had to use a technique called temporal dithering, which is a fancy way of saying “flicker really quickly” and in this case depended on accurate, sub-microsecond timing. This is all new to me. Speaking of sub-microsecond timing, or "subus", let's check out Jindra S’s submission. This code also runs on a microcontroller, and for… “performance” or “clock accuracy” is assembly inlined into C.
The Wizard Algorithm
Password requirements can be complicated. Some minimum and maximum number of characters, alpha and numeric characters, special characters, upper and lower case, change frequency, uniqueness over the last n passwords and different rules for different systems. It's enough to make you revert to a PostIt in your desk drawer to keep track of it all. Some companies have brillant employees who feel that they can do better, and so they create a way to figure out the password for any given computer - so you need to neither remember nor even know it.History does not show who created the wizard algorithm, or when, or what they were smoking at the time.Barry W. has the misfortune of being a Windows administrator at a company that believes in coming up with their own unique way of doing things, because they can make it better than the way that everyone else is doing it. It's a small organization, in a sleepy part of a small country. And yet, the IT department prides itself on its highly secure practices.Take the password of the local administrator account, for instance. It's the Windows equivalent of root, so you'd better use a long and complex password. The IT team won't use software to automate and keep track of passwords, so to make things extremely secure, there's a different password for every server.Here's where the wizard algorithm comes in.To determine the password, all you need is the server's hostname and its IP address.For example, take the server PRD-APP2-SERV4 which has the IP address 178.8.1.44.Convert the hostname to upper case and discard any hyphens, yielding PRDAPP2SERV4.Take the middle two octets of the IP address. If either is a single digit, pad it out to double digits. So 178.8.1.44 becomes 178.80.10.44 which yields 8010. Now take the last character of the host name; if that's a digit, discard it and take the last letter, otherwise just take the last letter, which gives us V. Now take the second and third letters of the hostname and concatenate them to the 8010 and then stick that V on the end. This gives us 8010RDV. Now take the fourth and fifth letters, and add them to the end, which makes 8010RDVAP. And there's your password! Easy.It had been that way for as long as anyone could remember, until the day someone decided to enable password complexity on the domain. From then on, you had to do all of the above, and then add @!#%&$?@! to the end of the password. How would you know whether a server has a password using the old method or the new one? Why by a spreadsheet available on the firm-wide-accessible file system, of course! Oh, by the way, there is no server management software.Critics might say the wizard algorithm has certain disadvantages. The fact that two people, given the same hostname and IP address, often come up with different results for the algorithm. Apparently, writing a script to figure it out for you never dawned on anyone.Or the fact that when a server has lost contact with the domain and you're trying to log on locally and the phone's ringing and everyone's pressuring you to get it resolved, the last thing you want to be doing is math puzzles.But at least it's better than the standard way people normally do it! [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
CodeSOD: A Unique Specification
One of the skills I think programmers should develop is not directly programming related: you should be comfortable reading RFCs. If, for example, you want to know what actually constitutes an email address, you may want to brush up on your BNF grammars. Reading and understanding an RFC is its own skill, and while I wouldn’t suggest getting in the habit of reading RFCs for fun, it’s something you should do from time to time.To build the skill, I recommend picking a simple one, like UUIDs. There’s a lot of information encoded in a UUID, and five different ways to define UUIDs- though usually we use type 1 (timestamp-based) and type 4 (random). Even if you haven’t gone through and read the spec, you already know the most important fact about UUIDs: they’re unique. They’re universally unique in fact, and you can use them as identifiers. You shouldn’t have a collision happen within the lifetime of the universe, unless someone does something incredibly wrong.Dexen encountered a database full of collisions on UUIDs. Duplicates were scattered all over the place. Since we’re not well past the heat-death of the universe, the obvious answer is that someone did something entirely wrong.
CodeSOD: The Sanity Check
I've been automating deployments at work, and for Reasonsâ„¢, this is happening entirely in BASH. Those Reasonsâ„¢ are that the client wants to use Salt, but doesn't want to give us access to their Salt environment. Some of our deployment targets are microcontrollers, so Salt isn't even an option.While I know the shell well enough, I'm getting comfortable with more complicated scripts than I usually write, along with tools like xargs which may be the second best shell command ever invented. yes is the best, obviously.The key point is that the shell, coupled with the so-called "Unix Philosophy" is an incredibly powerful tool. Even if you already know that it's powerful, it's even more powerful than you think it is.How powerful? Well, how about ripping apart the fundamental rules of mathematics? An anonymous submitter found this prelude at the start of every shell script in their organization.
Error'd: Just Handle It
Clint writes, "On Facebook, I tried to report a post as spam. I think I might just have to accept it."
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!
...30313233343536373839...