You are here

The Daily WTF

Subscribe to The Daily WTF feed
Curious Perversions in Information Technology
Updated: 2 hours 15 min ago

News Roundup: The Internet of Nope

Wed, 06/28/2017 - 12:30

Folks, we’ve got to talk about some of the headlines about the Internet of “Things”. If you’ve been paying even no attention to that space, you know that pretty much everything getting released is some combination of several WTFs, whether in conception, implementation, and let’s not forget security.

I get it. It’s a gold-rush business. We’ve got computers that are so small, so cheap, and so power-efficient, that we can slap the equivalent of a 1980s super-computer in a toilet seat. There's the potential to create products that make our lives better, that make the world better, and could carry us into a glowing future. It just sometimes feels like that's not what anybody's actually trying to make, though. Without even checking, I’m sure you can buy a WiFi enabled fidget spinner that posts the data to a smartphone app where you can send “fidges” to your friends, bragging about your RPMs.

We need this news-roundup, because when Alexa locks you out of your house because you didn’t pay for Amazon Prime this month, we can at least say “I told you so”. You think I’m joking, but Burger King wants in on that action, with its commercial that tries to trick your Google Assistant into searching for burgers. That’s also not the first time that a commercial has trigged voice commands, and I can guarantee that it isn’t going to be the last.

Now, maybe this is sour grapes. I bought a Nest thermostat before it was cool, and now three hardware generations on, I’m not getting software updates, and there are rumors about the backend being turned off someday. Maybe Nest needs a model more like “Hive Hub”. Hive is a startup with £500M invested, making it one of the only “smart home” companies with an actual business model. Of course, that business model is that you’ll pay $39.99 per month to turn your lights on and off.

At least you know that some of that money goes to keeping your smart-home secure. I’m kidding, of course- nobody spends any effort on making these devices secure. There are many, many high profile examples of IoT hacks. You hook your toaster up to the WiFi and suddenly it’s part of a botnet swarm mining BitCoins. One recent, high-profile example is the ZigBee Protocol, which powers many smart-home systems. It’s a complete security disaster, and opens up a new line of assault- instead of tricking a target to plug a thumb drive into their network, you can now put your payload in a light bulb.

Smart-homes aside, IoT in general is breeding ground for botnets. Sure, your uncle Jack will blindly click through every popup and put his computer password in anything that looks like a password box, but at least you can have some confidence that his Windows/Mac/Linux desktop has some rudimentary protections bundled with the OS. IoT vendors apparently don’t care.

Let’s take a break, and take a peek at a fun story about resetting a computerized lock. Sure, they could have just replaced the lock, but look at all the creative hackery they had to do to get around it.

With that out of the way, let’s talk about tea. Ever since the Keurig coffee maker went big, everyone’s been trying to be “the Keurig for waffles” or “the Keurig for bacon” or “the Keurig for juice”- the latter giving us the disaster that is the Juicero. Mash this up with the Internet of Things, and you get this WiFi enabled tea-maker, which can download recipes for brewing tea off the Internet. And don’t worry, it’ll always use the correct recipe because each pod is loaded with an RFID that not only identifies which recipe to use, but ensures that you’re not using any unathorized tea.

In addition to the “Keurig, but for $X,” there’s also the ever popular “the FitBit, but for $X.” Here’s the FitBit for desks. It allows your desk to nag you about getting up, moving around, and it’ll upload your activity to the Internet while it’s at it. I’m sure we’re all really excited for when our “activity” gets logged for future review.

Speaking of FitBits, Qualcomm just filed some patents for putting that in your workout shoes. This is actually not a totally terrible idea- I mean, by standards of that tea pot, anyway. I share it here because they’re calling it “The Internet of Shoes” which is a funny way of saying, “our marketing team just gave up”.

Finally, since we’re talking about Internet connected gadgets that serve no real purpose, Google Glass got its first software update in three years. Apparently Google hasn’t sent the Glass to a farm upstate, where it can live with Google Reader, Google Wave, Google Hangouts, and all the other projects Google got bored of.

[Advertisement] Application Release Automation – build complex release pipelines all managed from one central dashboard, accessibility for the whole team. Download and learn more today!
Categories: Fun/Other

Not so DDoS

Tue, 06/27/2017 - 12:30

Joe K was a developer at a company that provided a SaaS Natural Language Processing system. As Chief Engineer of the Data Science Team (a term that make him feel like some sort of mad professor), his duties included coding the Data Science Service. It provided the back-end for handling the complex, heavy-lifting type of processing that had to happen in real-time. Since it was very CPU-intensive, Joe spent a lot of time trying to battle latency. But that was the least of his problems.

The rest of the codebase was a cobbled-together mess that had been coded by the NLP researchers- scientists with no background in programming or computer science. Their mantra was “If it gets us the results we need, who cares how it looks behind the scenes?” This meant Joe’s well-designed data service somehow had to interface with applications made from a pile of ugly hacks. It was difficult at times, but he managed to get the job done while also keeping CPU usage to a minimum.

One day Joe was working away when Burt, the company CEO, burst in to their humble basement computer lab in an obvious tizzy. Burt rarely visited the “egghead dungeon”, as he called it, so something had to be amiss. “JOE!” he cried out. “The production data science service is completely down! Every customer we have gave me an angry call within the last ten minutes!”

Considering this was an early-stage startup with only five customers, Burt’s assertion was probably true, if misleading. “Wow, ok Burt. Let me get right on that!” Joe offered, feeling flustered. He took a look at the error logging service and there was nothing to be found. He then attempted to SSH to each of the production servers, with success. He decided to check performance on the servers and an entire string of red flags shot straight up the proverbial flag pole. Every production server was at 100% CPU usage.

“I have an effect for you, Burt, but not a cause. I’ll have to dig deeper but it almost seems like… a Denial of Service attack?” Joe offered, not believing that would actually be the case. With only five whitelisted customers able to connect, all of them using the NLP system to its fullest shouldn’t come even close to causing this.

While looking further at the server logs, Joe got an instant message from Xander, the software engineer who worked on the dashboards, “Hey Joe, I noticed prod was down… could it be related to something I’m doing?”

“Ummm… maybe? What is it you are doing exactly?” Joe replied, with a new sense of concern. Xander’s dashboard shouldn’t have any interaction with the DSS, so it seemed like an odd question. Requests to the NLP site would initially come to a front-end server, and if there was some advanced analysis that needed to happen, that server would RPC to the DSS. After the response was computed, the front-end server would log the request and response to the Xander’s dashboard system so it could monitor usage stats.

“Well, the dashboard is out of sync,” Xander explained. There had been a bug causing events to not make it to the dashboard system for the past month. They would need to be added to make the dashboard accurate. This could have been a simple change to the dashboard’s database, but instead Xander decided to replay all of the actual HTTP requests to the front end. Many of those requests triggered processing on the DSS- processing which had already been done. And since it was taking a long time, Xander had batched up the resent requests and was running them from three different machines, thus providing a remarkably good simulation of a DDoS.


“Ok, ok, sorry. I’ll get this cleaned up,” Xander assured Joe. Within 15 minutes, the server CPU usage returned to normal levels and everything was great again. Joe was able to get Burt off his back and return to his normal duties.

A few minutes later, Joe’s IM dinged again with a message from Xander. "Hey Joe, sorry about that, LOL. But are we 100% sure that was the problem? Should I do it again just to be sure?

If there was a way for Joe to use instant messaging to send a virtual strangulation to Xander, he would have done it. But a “HELL NO!!!” would have to suffice.

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

CodeSOD: Plurals Dones Rights

Mon, 06/26/2017 - 12:30

Today, submitter Adam shows us how thoughtless language assumptions made by programmers are also hilarious language assumptions:

"So we're querying a database for data matching *title* but then need to try again with plural/singular if we didn't get anything. Removing the trailing S is bad, but what really caught my eye was how we make a word plural. Never mind any English rules or if the word is actually Greek, Chinese, or Klingon."

if ((locs == NULL || locs->Length() == 0) && (title->EndsWith(@"s") || title->EndsWith(@"S"))) { title->RemoveCharAt(title->Length()-1); locs = data->GetLocationsForWord(title); } else if ((locs == NULL || locs->Length() == 0) && title->Length() > 0) { WCHAR c = title->CharAt(title->Length()-1); if (c >= 'A' && c <= 'Z') { title->Append(@"S"); } else { title->Append(@"s"); } locs = data->GetLocationsForWord(title); }

Untils nexts times: ευχαριστώs &s 再见s, Hochs!

hljs.initHighlightingOnLoad(); code { font-family: Consolas, monospace; } [Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
Categories: Fun/Other

Error'd: Perfectly Logical

Fri, 06/23/2017 - 12:00

"Outlook can't open an attachment because it claims that it was made in Outlook, which Outlook doesn't think is installed...or something," writes Gavin.


Mitch wrote, "So, the problems I'm having with activating Windows 10 is that I need to install Windows 10. Of course!"


"I don't expect 2018 to come around," writes Adam K., "Instead we'll all be transported back to 2014!"


"Here I thought that the world had gone mad, but then I remembered that I had a currency converter add-on installed," writes Shahim M.


John S. wrote, "It's good to know that the important notices are getting priority!"


Michael D. wrote, "It's all fun and games until someone tries to exit the conference room while someone else is quenching their thirst."


[Advertisement] Atalasoft’s imaging SDKs come with APIs & pre-built controls for web viewing, browser scanning, annotating, & OCR/barcode capture. Try it for 30 days with included support.
Categories: Fun/Other

I Need More Space

Thu, 06/22/2017 - 12:30

Shawn W. was a newbie support tech at a small company. Just as he was beginning to familiarize himself with its operational quirks, he got a call from Jim: The Big Boss.

Dread seized Shawn. Aside from a handshake on Interview Day, the only "interaction" he'd had with Jim thus far was overhearing him tear into a different support rep about having to deal with "complicated computer crap" like changing passwords. No doubt, this call was bound to be a clinic in saintly patience.

"Tech Support," Shawn greeted. "How may—?"

"I'm out of space and I need more!" Jim barked over the line.

"Oh." Shawn mentally geared up for a memory or hard drive problem. "Did you get a warning or error mes—?"

"Just get up here and bring some more space with you!" Jim hung up.

"Oh, boy," Shawn muttered to himself.

Deciding that he was better off diagnosing the problem firsthand, Shawn trudged upstairs to Jim's office. To his pleasant surprise, he found it empty. He sank into the cushy executive-level chair. Jim hadn't been away long enough for any screensavers or lock screens to pop up, so Shawn had free rein to examine the machine.

There wasn't much to find. The only program running was a web browser, with a couple of tabs open to and an investment portfolio. The hardware itself was fairly new. CPU, memory, hard drive all looked fine.

"See, I'm out of space. Did you bring me more?"

Shawn glanced up to find Jim barreling toward him, steaming mug of coffee in hand. He braced himself as though facing down an oncoming freight train. "I'm not sure I see the problem yet. Can you show me what you were doing when you noticed you needed more space?"

Jim elbowed his way over to the mouse, closed the browser, then pointed to the monitor. "There! Can't you see I'm out of space?"

Indeed, Jim's desktop was full. So many shortcuts, documents, widgets, and other icons crowded the screen that the tropical desktop background was barely recognizable as such.

While staring at what resembled the aftermath of a Category 5 hurricane, Shawn debated his response. "OK, I see what you mean. Let's see if we can—"

"Can't you just get me more screen?" Jim pressed.

More screen? "You mean another monitor?" Shawn asked. "Well, yes, I could add a second monitor if you want one, but we could also organize your desktop a little and—"

"Good, get me one of those! Don't touch my icons!" Jim shooed Shawn away like so much lint. "Get out of my chair so I can get back to work."

A short while later, Shawn hooked up a second monitor to Jim's computer. This prompted a huge and unexpected grin from the boss. "I like you, you get things done. Those other guys would've taken a week to get me more space!"

Shawn nodded while stifling a snort. "Let me know if you need anything else."

Once Jim had left for the day, Shawn swung past the boss' office out of morbid curiosity. Jim had already scattered a few dozen shortcuts across his new real estate. Another lovely vacation destination was about to endure a serious littering problem.

[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
Categories: Fun/Other

CodeSOD: A Lazy Cat

Wed, 06/21/2017 - 12:30

The innermost circle of Hell, as we all know, is trying to resolve printer driver issues for all eternity. Ben doesn’t work with the printers that we mere mortals deal with on a regular basis, though. He runs a printing press, three stories of spinning steel and plates and ink and rolls of paper that could crush a man.

Like most things, the press runs Linux- a highly customized, modified version of Linux. It’s a system that needs to be carefully configured, as “disaster recovery” has a slightly different meaning on this kind of heavy equipment. The documentation, while thorough and mostly clear, was obviously prepared by someone who speaks English as a second language. Thus, Ben wanted to check the shell scripts to better understand what they did.

The first thing he caught was that each script started with variable declarations like this:

GREP="/bin/grep" CAT="/bin/cat"

In some cases, there were hundreds of such variable declarations, because presumably, someone doesn’t trust the path variable.

Now, it’s funny we bring up cat, as a common need in these scripts is to send a file to STDOUT. You’d think that cat is just the tool for the job, but you’d be mistaken. You need a shell function called cat_file:

# function send an file to STDOUT # # Usage: cat_file <Filename> # function cat_file () { local temp local error error=0 if [ $# -ne 1 ]; then temp="" error=1 else if [ -e ${1} ]; then temp="`${CAT} ${1}`" else temp="" error=1 fi fi echo "${temp}" return $((error)) }

This ‘belt and suspenders’ around cat ensures that you called it with parameters, that the parameters exist, and failing that, it… well… fails. Much like cat would, naturally. This gives you the great advantage, however, that instead of writing code like this:

dev="`cat /proc/dev/net | grep eth`"

You can instead write code like this:

dev="`cat_file /proc/dev/net | ${GREP} eth`"

Much better, yes?

hljs.initHighlightingOnLoad(); [Advertisement] BuildMaster integrates with an ever-growing list of tools to automate and facilitate everything from continuous integration to database change scripts to production deployments. Interested? Learn more about BuildMaster!
Categories: Fun/Other

The CMS From Hell

Tue, 06/20/2017 - 12:30

Contracting can be really hit or miss. Sometimes, you're given a desk and equipment and treated just like an employee, except better paid and exempt from team-building exercises. Sometimes, however, you're isolated in your home office, never speaking to anyone, working on tedious, boring crap they can't convince their normal staff to do.

Eric was contracted to perform basic website updating tasks for a government agency. Most of the work consisted of receiving documents, uploading them to the server, and adding them to a page. There were 4 document categories, each one organized by year. Dull as dishwater, but easy.

The site was hosted by a third party in a shared hosting environment. It ran on a CMS produced by another party. WTFCMS was used in many high-profile sites, so the agency figured it had to be good. Eric was given login credentials and—in the way of techies given boring tasks everywhere—immediately began automating the task at hand.

Step 1 of this automation was to get a list of articles with their IDs. Eric was pleased to discover that the browser-based interface for the CMS used a JSON request to get the list of pages. With the help of good old jq, he soon had that running in a BASH shell script. To get the list of children for an article, he passed the article's ID to the getChildren endpoint.

Usually, in a heirarchy like this, there's some magic number that means "root element." Eric tried sending a series of likely candidates, like 0, -1, MAX_INT, and MIN_INT. It turned out to be -1 ... but he also got a valid list when he passed in 0.

Curious, he thought to himself. This appears to be a list of articles ... and hey, here's the ones I got for this site. These others ...? No way.

Sure enough, passing in a parent ID of 0 had gotten Eric some sort of super-root: every article across every site in the entire CMS system. Vulnerability number 1.

Step 2 was to take the ID list and get the article data so he could associate the new file with it. This wasn't nearly as simple. There was no good way to get the text of the article from the JSON interface; the CMS populated the articles server-side.

Eric was in too deep to stop now, though. He wrote a scraper for the edit page, using an XML parser to handle the HTML form that held the article text. Once he had the text, he compared it by hand to the POST request sent from his Firefox instance to ensure he had the right data.

And he did ... mostly. Turns out, the form was manipulated by on-page Javascript before being submitted: fields were disabled or enabled, date/time formats were tweaked, and the like. Eric threw together some more scripting to get the job done, but now he wasn't sure if he would hit an edge case or somehow break the database if he ran it. Still, he soldiered on.

Step 3 was to upload the files so they could be linked to the article. With Firebug open, Eric went about adding an upload.

Now, WTFCMS seemed to offer the usual flow: enter a name, select a file, and click Upload to both upload the file and save it as the given name. When he got to step 2, however, the file was uploaded immediately—but he still had to click the Upload button to "save" it.

What happens if I click Cancel? Eric wondered. No, never mind, I don't want to know. What does the POST look like?

It was a mess of garbage. Eric was able to find the file he uploaded, and the name he'd given it ... and also a bunch of server-side information the user shouldn't be privvy to, let alone be able to tamper with. Things like, say, the directory on the server where the file should be saved. Vulnerability number 2.

The response to the POST contained, unexpectedly, HTML. That HTML contained an iframe. The iframe contained an iframe. iframe2 contained iframe3; iframe3 contained a form. In that form were two fields: a submit button, reading "Upload", and a hidden form field containing the path of the uploaded file. In theory, he could change that to read anything on the server. Now he had both read and write access to any arbitrary destination in the CMS, maybe even on the server itself. Vulnerability number 3.

It was at this point that Eric gave up on his script altogether. This is the kind of task that Selenium IDE is perfect for. He just kept his head down, hoped that the server had some kind of validation to prevent curious techies like himself from actually exploiting any of these potential vulnerabilities, and served out the rest of his contract.

code { font-family: Consolas, monospace; } sup { font-size: .83em; vertical-align: super; } [Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

Representative Line: Highly Functional

Mon, 06/19/2017 - 12:30

For a brief period of time, say, about 3–4 years ago, if you wanted to sound really smart, you’d bring up “functional programming”. Name-dropping LISP or even better, Haskell during an interview marked you as a cut above the hoi polloi. Even I, surly and too smart for this, fell into the trap of calling JavaScript “LISP with curly braces”, just because it had closures.

Still, functional programming features have percolated through other languages because they work. They’re another tool for the job, and like any tool, when used by the inexpert, someone might lose a finger. Or perhaps someone should lose a finger, if only as a warning to others.

For example, what if you wanted to execute a loop 100 times in JavaScript? You could use a crummy old for loop, but that’s not functional. The functional solution comes from an anonymous submitter:

Array.apply(null, {length: 99}).map(, Number).forEach(function (element, index) { // do some more crazy stuff });

This is actually an amazing abuse of JavaScript’s faculties, and I thought I saw the worst depredations one could visit on JavaScript while working with Angular code. When I first read this line, my initial reaction was, “oh, that’s not so bad.” Then I tried to trace through its logic. Then I realized, no, this is actually really bad. Not just extraneous arrays bad, but full abused of JavaScript bad. Like call Language Protective Services bad. This is easier to explain if you look at it backwards.

forEach applies a function to each element in the array, supplying the element and the index of that element. invokes the Number function, used to convert things into numbers (shocking, I know), but it allows you to supply the this against which the function is executed. map takes a callback function, and supplies an array item for the currentValue, the index, and the whole array as parameters. map also allows you to specify what this is, for the callback itself- which they set to be Number- the function they’re calling.

So, remember, map expects a callback in the form f(currentValue, index, array). We’re supplying a function: call(thisValue, numberToConvert). So, the end result of map in this function is that we’re going to emit an array with each element equal to its own index, which makes the forEach look a bit silly.

Finally, at the front, we call Array.apply, which is mostly the same as, with a difference in how arguments get passed. This allows the developer to deftly avoid writing new Array(99), which would have the same result, but would look offensively object-oriented.

hljs.initHighlightingOnLoad(); [Advertisement] High availability, Load-balanced or Basic – design your own Universal Package Manager, allow the enterprise to scale as you grow. Download and see for yourself!
Categories: Fun/Other

Error'd: @TitleOfErrord

Fri, 06/16/2017 - 12:00

"I asked my son, @Firstname, and he is indeed rather @Emotion about going to @ThemePark!" wrote Chris @LASTNAME.


"I think Google assumes there is only one exit on the highway," writes Balaprasanna S.


Axel C. writes, "So what you're saying here is that something went wrong?"


"Hmmmm...YMMV, but that's not quite the company that I would want to follow," wrote Rob H.


"You know, I also confuse San Francisco with San Jose all the time. I mean, they just sound so much alike!" writes Mike S.


Mike G. writes, "Sure, it's and a little avant garde, but I hear this film was nominated for an award."


[Advertisement] Otter enables DevOps best practices by providing a visual, dynamic, and intuitive UI that shows, at-a-glance, the configuration state of all your servers. Find out more and download today!
Categories: Fun/Other

CodeSOD: Classic WTF: Hacker Proof Booleans

Thu, 06/15/2017 - 12:30
We continue our summer break with a classic case of outsmarting oneself in the stupidest way. Original -- Remy

"Years ago, long before I'd actually started programming, I spent my time learning about computers and data concepts by messing around with, believe it or not, cheat devices for video games," wrote Rena K., "The one I used primarily provided a RAM editor and some other tools which allowed me to tool around with the internal game files and I even get into muddling around with the game data all in the interest of seeing what would happen."

"As such, by the time my inflated hacker ego and I got into programming professionally, I was already pretty familiar with basic things like data types and binary. I was feeling pretty darn L33T."

"However, this mindset lead to me thinking that someone could potentially 'steal my program' by replacing my name with theirs in a hex editor and claiming to have made it themselves. (Which wasn't unheard of in the little game hacking communities I was in...) So I used the h4x0r sk1llz I'd picked up to make my program hacker-proof."

"Of course I knew full well how boolean variables worked, but I'd read somewhere that in VB6, boolean types were actually integers. From this, I concluded that it was technically possible that a boolean variable could hold a value that was neither true or false. Of course there was no way to do this from within VB, so that could only mean someone was monkeying around with something they shouldn't. I needed a way to detect this."

if var = true then doThings() else if var = false then doOtherThings() else MsgBox("omfg haxor alert") End --terminate program end if

"I kept up adding the above to my code for years until I grew up enough to realize that it didn't do a darn thing. For the record though, nobody ever managed to 'steal my program'."

Do you have any confessions you'd like to make? Send them on in.

[Advertisement] Infrastructure as Code built from the start with first-class Windows functionality and an intuitive, visual user interface. Download Otter today!
Categories: Fun/Other

Classic WTF: The Accidental Hire

Wed, 06/14/2017 - 12:30
At least we get a summer break, I suppose. Not like over at Doghouse Insurance. Original -- Remy

Doghouse Insurance (as we'll call them) was not a pleasant place to work. Despite being a very successful player in their industry, the atmosphere inside Doghouse was filled with a constant, frenzied panic. If Joe Developer didn't delay his upcoming vacation and put in those weekend hours, he might risk the timely delivery of his team's module, which might risk delaying the entire project, which might risk the company's earnings potential, which might risk the collapse of the global economy. And that's just for the Employee Password Change Webpage project; I can't even begin to fathom the overarching devastation that would ensue from a delayed critical project.

To make matters worse, the primary business application that poor souls like Vinny maintained was a complete nightmare. It was developed during the company's "database simplification" era and consisted of hundreds of different "virtual attribute tables" stuffed into four real tables; it was a classic case of The Inner-Platform Effect. But amidst all this gloom and despair was an upbeat fellow named Chris who accidentally became a part of the Doghouse Insurance team.

Chris interviewed with Doghouse Insurance back in 2002 for a developer position on the Data Warehouse team. With the large pool of available candidates at the time, Chris didn't make the cut and the opening was awarded to someone else. However, Doghouse never communicated this to him and instead offered him a job.

It was an awkward first day; Chris showed up and no one knew what to do with him. They obviously couldn't immediately fire him (it would risk a lawsuit, which might risk a -- oh, you know the drill) and, since all teams were short-staffed, they couldn't increase the headcount on one team because that would be unfair to all of the other managers. After a few weeks, it was finally decided: Chris would be the Source Control Guy.

Doghouse Insurance didn't really have a need for a Source Control Guy and Chris didn't really have any experience being a Source Control Guy. It was a perfect match. After a few months, Chris figured out how to manage Doghouse's Source Control System and became responsible for the entirety of SCS-related tasks: adding new users, reseting forgotten passwords, creating new repositories, and -- well -- that was pretty much it.

While everyone else stressed out and practically killed themselves over deadlines, Chris mostly sat around all day, waiting for that occasional "I forgot my source control password" email. He never gloated nor complained and instead made himself available to listen to his coworker's grievances and tales of woe. Chris would offer up whatever advice he could and would generally lighten the mood of anyone who stopped by his desk for a chat. His cubicle became the sole oasis of sanity in the frantic world of Doghouse Insurance.

Although Vinny is no longer at Doghouse Insurance (he actually left after following Chris' advice), he still does keep in touch with Chris. And Vinny is happy to report that, should you ever find yourself unfortunate enough to work at Doghouse Insurance, you can still find Chris there, managing the Source Control System and eager to chat about the insanity that is Doghouse.

[Advertisement] Scale your release pipelines, creating secure, reliable, reusable deployments with one click. Download and learn more today!
Categories: Fun/Other

CodeSOD: Classic WTF: It's Like Calling Assert

Tue, 06/13/2017 - 12:30
We continue our summer vacation with this gem- a unique way to interact with structured exception handling, to be sure. Original. --Remy

When we go from language to language and platform to platform, a whole lot of “little things” change about how we write code: typing, syntax, error handling, etc. Good developers try to adapt to a new language by reading the documentation, asking experienced colleagues, and trying to follow best practices. “Certain Developers,” however, try to make the language adapt to their way of doing things.

Adrien Kunysz discovered this following code written by a “Certain Developer” who wasn’t a fan of the try...catch…finally approach called for in .NET Java development and exception handling.

/** * Like calling assert(false) in C. */ protected final void BUG (String msg) { Exception e = null; try { throw new Exception (); } catch (Exception c) { e = c; } logger.fatal (msg, e); System.exit (1); }

And I’m sure that, by commenting “Like calling assert(false) in C,” the author doesn’t mean assert.h, but means my_assert.h. After all, who is C – or any other language – to tell him how errors should be handled?

UPDATE: Fixed Typos and language. I swear, at 7:00AM this looked fine to me...

[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
Categories: Fun/Other

Classic WTF: Server Room Fans and More Server Room Fun

Mon, 06/12/2017 - 12:30
The Daily WTF is taking a short summer break this week, and as the temperatures around here are edging up towards "Oh God I Want to Die" degrees Fahrenheit, I thought it'd be great to kick off this week of classic articles with some broiling hot server room hijinks. -- Remy

"It's that time of year again," Robert Rossegger wrote, "you know, when the underpowered air conditioner just can't cope with the non-winter weather? Fortunately, we have a solution for that... and all we need to do is just keep an extra eye on people walking near the (completely ajar) server room door."


"For as long as anyone can remember," Mike E wrote, "the fax machine in one particular office was a bit spotty whenever it was wet out. After having the telco test the lines from the DMARC to the office, I replaced the hardware, looked for water leaks all along the run, and found precisely nothing. The telco disavowed all responsibility, so the best solution I could offer was to tell the users affected by this to look out the window and, if raining, go to another fax machine."

"One day, we had the telco out adding a T1 and they had the cap off of the vault where our cables come in to the building. Being curious by nature, I wandered over when nobody was around and wound up taking this picture. After emailing same to the district manager of the telco, suddenly we had the truck out for an extra day (accompanied by one very sullen technician) and the fax machine worked perfectly from then on."


"I found this when I came back in to work after some time off," writes Sam Nicholson, "that drive is actually earmarked for 'off-site backup'. Also, this is what passes for a server rack at this particular software company. Yes, it's made of wood."


"Some people use 'proper electrical wiring'," writes Mike, "others use 'extension cords'. We, on the other hand, apparently do this."


"I was staying at a hotel in Manhattan and somehow took a wrong turn and wound up in the stairwell," wrote Dan, "not only is all their equipment in a public place (without even a door), it's mostly hanging from cables in several places."


"I spotted this in China," writes Matt, "This poor switch was bolted to a column in the middle of some metal shop about 4m above ground. There were many more curious things, but I decided to keep a low profile and stop taking pictures."


[Advertisement] Infrastructure as Code built from the start with first-class Windows functionality and an intuitive, visual user interface. Download Otter today!
Categories: Fun/Other

Error'd: Know Your Bits!

Fri, 06/09/2017 - 12:00

"I know software can't always be perfect, but things like this make me want to shut down my PC and say that's enough computering for the day," writes Timothy W.


Richard S. wrote, "I suppose you don't really need an email body when you have everything you need in the subject."


"I recently inherited a project from a contractor that left the project," writes Michael H., "I have never seen code quite like his, and that is NOT a compliment."


Bruce C. writes, "The fact that this won't ship to NZ is kind of immaterial - the REAL question is do I feel like spending $10.95 for new or can I settle for used at a discount?"


"I'm sure their product is great, but I don't want to be an early adopter if I can help it," writes Jaime A.


"To be fair, the email did catch my attention," wrote Philip G.


[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

The Gassed Pump

Thu, 06/08/2017 - 12:30

“Staff augmentation,” was a fancy way of saying, “hey, contractors get more per hour, but we don’t have to provide benefits so they are cheaper,” but Stuart T was happy to get more per hour, and even happier to know that he’d be on to his next gig within a few months. That was how he ended up working for a national chain of gas-station/convenience stores. His job was to build a “new mobile experience for customer loyalty” (aka, wrapping their website up as an app that can also interact with QR codes).

At least, that’s what he was working on before Miranda stormed into his cube. “Stuart, we need your help. ProdTrack is down, and I can’t fix it, because I’ve got to be at a mandatory meeting in ten minutes.”

ProdTrack was their inventory system that powered their point-of-sale terminals. For it to be down company wide was a big problem, and essentially rendered most of their stores inoperable. “Geeze, what mandatory meeting is more important than that?”

“The annual team-building exercise,” Miranda said, using a string of profanity for punctuation. “They’ve got a ‘no excuses’ policy, so I have to go, ‘or else’, but we also need to get this fixed.”

Miranda knew exactly what was wrong. ProdTrack could only support 14 product categories. But one store- store number 924- had decided that they needed 15. So they added a 15th category to the database, threw a few products into the category, and crossed their fingers. Now, all the stores were crashing.

“You’ll need to look at the StoreSQLUpdates and the StoreSQLUpdateStatements tables,” Miranda said. “And probably dig into the ProductDataPump.exe app. Just do a quick fix- we’re releasing an update supports any number of categories in three weeks or so, we just need to hold this together till then.”

With that starting point, Stuart started digging in. First, he puzzled over the tables Miranda had mentioned. StoreSQLUpdates looked like this:

td { border: 1px solid black; padding: 1em; } IDSTATEMENTSTATEMENT_ORDER 145938DELETE FROM SupplierInfo90 148939INSERT INTO ProductInfo VALUES(12348, 3, 6)112

Was this an audit tables? What was StoreSQLUpdateStatements then?

IDSTATEMENT 168597INSERT INTO StoreSQLUpdates(statement, statement_order) VALUES (‘DELETE FROM SupplierInfo’, 90) 168598INSERT INTO StoreSQLUpdates(statement, statement_order) VALUES (‘INSERT INTO ProductInfo VALUES(12348, 3, 6)’, 112)

Stuart stared at his screen, and started asking questions. Not questions about what he was looking at, but questions about the life choices that had brought him to this point, questions about whether it was really that bad an idea to start drinking at work, and questions about the true nature of madness- if the world was mad, and he was the only sane person left, didn’t that make him the most insane person of all?

He hoped the mandatory team building exercise was the worst experience of Miranda’s life, as he sent her a quick, “WTF?” email message. She obviously still had her cellphone handy, as she replied minutes later:

Oh, yeah, that’s for data-sync. Retail locations have flaky internet, and keep a local copy of the data. That’s what’s blowing up. Check ProductDataPump.exe.

Stuart did. ProductDataPump.exe was a VB.Net program in a single file, with one beautifully named method, RunIt, that contained nearly 2,000 lines of code. Some saintly soul had done him the favor of including a page of documentation at the top of the method, and it started with an apology, then explained the data flow.

Here’s what actually happened: a central database at corporate powered ProdTrack. When any data changed there, those changes got logged into StoreSQLUpdateStatements. A program called ProductDataShift.exe scanned that table, and when new rows appeared, it executed the statements in StoreSQLUpdateStatements (which placed the actual DML commands into StoreSQLUpdates).

Once an hour, ProductDataPump.exe would run. It would attempt to connect to each retail location. If it could, it would read the contents of the central StoreSQLUpdates and the local StoreSQLUpdates, sorting by the order column, and through a bit of faith and luck, would hopefully synchronize the two databases.

Buried in the 2,000 line method, at about line 1,751, was a block that actually executed the statements:

If bolUseSQL Then For Each sTmp As String In sProductsTableSQL sTmp = sTmp.Trim() If sTmp <> "" Then SQLUpdatesSQL(lngIDSQL, sTmp, dbQR5) End If Next sTmp End If

Once he was done screaming at the insanity of the entire process, Stuart looked at the way product categories worked. Store 924 didn’t carry anything in the ALCOHOL category, due to state Blue Laws, but had added a PRODUCE category. None of the other stores had a PRODUCE category (if they carried any produce, they just put it in PREPARED_FOODS). Fixing the glitch that caused the application to crash when it had too many categories would take weeks, at least- and Miranda already told him a fix was coming. All he had to do was keep it from crashing until then.

Into the StoreSQLUpdates table, he added a DELETE statement that would delete every category that contained zero items. That would fix the immediate problem, but when the ProductDataPump.exe ran, it would just copy the broken categories back around. So Stuart patched the program with the worst fix he ever came up with.

If bolUseSQL Then For Each sTmp As String In sProductsTableSQL sTmp = sTmp.Trim() If sTmp <> "" Then If nStoreNumber = 924 And sTmp.Contains("ALCOHOL") Then Continue For ElseIf nStoreNumber <> 924 And sTmp.Contains("PRODUCE") Then Continue For Else SQLUpdatesSQL(lngIDSQL, sTmp, dbQR5) End If End If Next sTmp End If [Advertisement] Application Release Automation – build complex release pipelines all managed from one central dashboard, accessibility for the whole team. Download and learn more today!
Categories: Fun/Other

CodeSOD: A Promise of Timing

Wed, 06/07/2017 - 12:30

Asynchronous programming is hard, and there’s never been a perfect way to solve that problem. One of the most widely used solutions is the “promise” or “future”. We wrap the asynchronous process up in a, well, promise of a future result. “Someday, there will be data here, I hope.” The real beauty of promises comes from their composability- “getData promises to fetch some records, and then the calling method can promise to display them.”

Of course, it’s still asynchronous, and when an application has multiple asynchronous processes happening at the same time, “weird behavior” can happen, thanks to timing issues. Keith W encountered one of those timing related Heisenbugs, and became immediately suspicious about how it was getting invoked:

this.disableUI("Loading form..."); this.init(workflowId, ordinal).done(() => this.enableUI("Form loaded!"));

init isn’t passing data to the next promise in the chain. So what actually happens in the init method?

public init(workflowId: string, ordinal: number): JQueryPromise<any> { var self = this; var promise = $.Deferred<boolean>(); $.when( $.ajax({ type: "GET", url: getEndpoint("work", "GetFormInputForm"), data: { id: workflowId, ordinal: ordinal }, contentType: "application/json", success(result) { if (result) { var formType = result.FormType || Forms.FormType.Standard; self.formMetaDataExcludingValues = result; var customForm = new Forms.CustomForm(formType, Forms.FormEditorMode.DataInput, result); self.CustomForm(customForm); self.flatControlList = customForm.flattenControls(); ko.utils.arrayForEach(self.flatControlList, (cnt) => { var row = { name:, value: {}, displayText: "", required: cnt.required() }; if (cnt instanceof Forms.SelectControl) { row.value = cnt.values(); } else if (cnt instanceof Forms.ContactControl || cnt instanceof Forms.OrganisationControl) { row.displayText = cnt.displayName(); row.value = cnt.value(); } else if (cnt instanceof Forms.SequenceControl) { row.value = ""; } else if (cnt instanceof Forms.AssetControl) { row.value = cnt.value(); row.displayText = row.value ? cnt.displayName() : null; } else if (cnt instanceof Forms.CategoryControl) { row.value = cnt.cachedValue; } else { row.value = cnt.value(); } self.defaultValues.push(new ControlValue(row)); }); } } }) ).done(() => { $.ajax({ type: "GET", url: url, data: { id: workflowId, ordinal: ordinal, numberOfInstances: self.NoOfInstances() }, contentType: "application/json", success(result) { if (result) { var formType = result.FormType || Forms.FormType.Standard; if (!multiple) { self.CurrentInstanceNo(1); // store a blank form control values self.saveCurrentFormValues().done(() => self.applyKoBinding().done(() => {"Data Saved Once."); })); } else { self.Forms([]); self.CurrentInstanceNo(self.NoOfInstances()); self.saveAllFormValues(result).done(() => self.applyKoBinding().done(() => {"Data Saved for all."); })); } } } }) }) promise.resolve(true); return promise; }

This code is awful at first glance. It’s complicated spaghetti code, with all sorts of stateful logic that manipulates properties of the owning object. That’s your impression at first glance, but it’s actually worse.

Let’s highlight the important parts:

public init(workflowId: string, ordinal: number): JQueryPromise<any> { var promise = $.Deferred<boolean>(); //big pile of asynchronous garbage promise.resolve(true); return promise; }

Yes, this init method returns a promise, but that promise isn’t contingent on any other promises being made, here. promise.resolve(true) essentially renders this promise synchronous, not asynchronous. Instead of waiting for all the pending requests to complete, it immediately claims to have succeeded and fulfilled its promise.

No wonder there’s a…

… timing issue.

hljs.initHighlightingOnLoad(); [Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

The Insurance Plan

Tue, 06/06/2017 - 12:30

When designing a new feature of an application, among other things, you always want to decide how it will be used. Is it single threaded or will it need to happen in parallel. Will only one user do it at a time, or does it need to support asynchronous access. Will every user want to do it in the same way, or will they each want something just a little different.

Charlie C. worked for a modestly sized financial startup that had gained some traction. The company had grown to about 100 people. They had garnered about 300 customers, and they were building software that would solve a problem that was causing regulators all manner of headaches.

The system essentially provided the ability for customers to swap bond insurance contracts. These swaps could be between any two, three or four parties, depending upon the type of transaction. One day, one of the customers asked the CEO if they could implement an approval workflow. Specifically, before letting some low level trader execute a swap, it would be routed to a group with approval authority. If approved, the transaction would be routed to the other party. If not, it would be rejected back to the initiator.

The CEO asked the development manager who came to Charlie and told him to just hard code some flags in the main transaction record, and check for them as special cases at every relevant place in the code. Charlie knew that if one customer wanted it, that most (if not all) of them would want it. Accordingly, he explained as much and said he would make it table driven.

"Won't that take longer to build?" the boss inquired.

"Of course it will take longer, but it's a whole lot more supportable than special-casing the code all over, and corrupting the main transaction record," Charlie replied. With 300 customers and transactions involving 2, 3 or 4 parties, there were almost 8 billion permutations; even a tiny fraction of customers requesting special handling would make it absolutely unsupportable. "Think of it like… insurance."

The manager insisted on the hard coding, but Charlie ignored him, knowing all too well the consequences of listening to his boss.

A few months later, the work was done. On the very last day of work, as Charlie was doing some final cleanup, his boss walked over with the CEO in tow. They were both in a bit of a panic. "Another customer has asked for special workflow processing, but in a slightly different way. How much time will it take to add the additional workflow logic?"

Charlie looked at his boss, laughed, and said "About thirty minutes."

"But it took months this time!"

"And this is why I don't listen to you." Charlie went on to explain that it would take about a half hour to create the relevant groups, users and flags to simulate the new workflow, and that he would try to start the servers, queue managers and 16 copies of their application (one for each user in the scenario) on his PC to demonstrate that it would perform the required routing.

At the appointed time, both CEO and development manager returned and watched as Charlie made his machine groan through the motions to perform the desired flow processing. While it was busy thrashing, he used the opportunity to point out that they had no demo environment, that the developer workstations were simply not powerful enough to perform these sorts of demos, and he apologized for taking so much of their time. As the CEO listened to the hard disk grinding away, he agreed and offered to let them buy more powerful developer workstations.

After about an hour of going through all the different scenarios, the CEO was pleased, thanked Charlie for his time and told him to put in an order for the workstations the next day. Then they walked away.

Later that day, the development manager was transferred to manage another team and someone else was put in charge of Charlie's project. Shortly thereafter, Charlie grabbed the other developers and put together specs for their dream machines, which were ordered the next day.

Over the next year, configurations for more than a thousand different special case workflows were added, and not a single byte of code had to change.

[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
Categories: Fun/Other

CodeSOD: Variation on a Theme

Mon, 06/05/2017 - 12:30

If you’re not already aware, the Daily WTF is open source. We went the route of building our own CMS mostly because our application needs are pretty light. We don’t need themes, we don’t need WYSIWYG editors, we don’t need asset uploads. Also, with home-grown code, we know what’s in it, what it does, and any problems in the code are our own.

Which brings us to WordPress, land of the themes. There’s a cottage industry around building WordPress themes, and it’s a busy enough space that there are specialists in developing themes for specific industries. Alessandro ended up doing some work in the real estate business, tweaking a WP theme to change the way certain images would get displayed in a slide show.

$pic1 = get_field('pic_1'); $pic2 = get_field('pic_2'); $pic3 = get_field('pic_3'); $pic4 = get_field('pic_4'); $pic5 = get_field('pic_5'); $pic6 = get_field('pic_6'); $pic7 = get_field('pic_7'); $pic8 = get_field('pic_8'); $pic9 = get_field('pic_9'); $pic10 = get_field('pic_10'); if ($pic1!=""){ if (strpos($pic1,'php') === false) { if (strpos($pic1,'floorplan')) { $floor = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic1); } else { if (strpos($pic1,'EPC')) { $epc = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic1); } else { $pic1r = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic1); echo '<li><a href="'.$pic1r.'" class="lbp_primary"><img src="'.$pic1r.'" /></a></li>'; } } } } if ($pic2!=""){ if (strpos($pic2,'php') === false) { if (strpos($pic2,'floorplan')) { $floor = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic2); } else { if (strpos($pic2,'EPC')) { $epc = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic2); } else { $pic2r = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic2); echo '<li><a href="'.$pic2r.'" class="lbp_primary"><img src="'.$pic2r.'" /></a></li>'; } } } } if ($pic3!=""){ if (strpos($pic3,'php') === false) { if (strpos($pic3,'floorplan')) { $floor = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic3); } else { if (strpos($pic3,'EPC')) { $epc = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic3); } else { $pic3r = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic3); echo '<li><a href="'.$pic3r.'" class="lbp_primary"><img src="'.$pic3r.'" /></a></li>'; } } } } if ($pic4!=""){ if (strpos($pic4,'php') === false) { if (strpos($pic4,'floorplan')) { $floor = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic4); } else { if (strpos($pic4,'EPC')) { $epc = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic4); } else { $pic4r = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic4); echo '<li><a href="'.$pic4r.'" class="lbp_primary"><img src="'.$pic4r.'" /></a></li>'; } } } } if ($pic5!=""){ if (strpos($pic5,'php') === false) { if (strpos($pic5,'floorplan')) { $floor = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic5); } else { if (strpos($pic5,'EPC')) { $epc = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic5); } else { $pic5r = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic5); echo '<li><a href="'.$pic5r.'" class="lbp_primary"><img src="'.$pic5r.'" /></a></li>'; } } } } if ($pic6!=""){ if (strpos($pic6,'php') === false) { if (strpos($pic6,'floorplan')) { $floor = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic6); } else { if (strpos($pic6,'EPC')) { $epc = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic6); } else { $pic6r = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic6); echo '<li><a href="'.$pic6r.'" class="lbp_primary"><img src="'.$pic6r.'" /></a></li>'; } } } } if ($pic7!=""){ if (strpos($pic7,'php') === false) { if (strpos($pic7,'floorplan')) { $floor = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic7); } else { if (strpos($pic7,'EPC')) { $epc = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic7); } else { $pic7r = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic7); echo '<li><a href="'.$pic7r.'" class="lbp_primary"><img src="'.$pic7r.'" /></a></li>'; } } } } if ($pic8!=""){ if (strpos($pic8,'php') === false) { if (strpos($pic8,'floorplan')) { $floor = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic8); } else { if (strpos($pic8,'EPC')) { $epc = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic8); } else { $pic8r = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic8); echo '<li><a href="'.$pic8r.'" class="lbp_primary"><img src="'.$pic8r.'" /></a></li>'; } } } } if ($pic9!=""){ if (strpos($pic9,'php') === false) { if (strpos($pic9,'floorplan')) { $floor = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic9); } else { if (strpos($pic9,'EPC')) { $epc = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic9); } else { $pic9r = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic9); if( file_exists( $pic9 ) ) { echo '<li><a href="'.$pic9r.'" class="lbp_primary"><img src="'.$pic9r.'" /></a></li>'; } } } } } if ($pic10!=""){ if (strpos($pic10,'php') === false) { if (strpos($pic10,'floorplan')) { $floor = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic10); } else { if (strpos($pic10,'EPC')) { $epc = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic10); } else { $pic10r = str_replace("[HIDDEN-URL]","/wp-content/uploads/",$pic10); echo '<li><a href="'.$pic10r.'" class="lbp_primary"><img src="'.$pic10r.'" /></a></li>'; } } } }

As you can see, the loop was unrolled for performance, and the extraneous tab characters were removed to keep the filesize down. It's easy to add or remove images from the slide-show, by doing a simple copy/paste action. This is some top-shelf code here.

hljs.initHighlightingOnLoad(); [Advertisement] Atalasoft’s imaging SDKs come with APIs & pre-built controls for web viewing, browser scanning, annotating, & OCR/barcode capture. Try it for 30 days with included support.
Categories: Fun/Other

Error'd: A World Turned Upside Down

Fri, 06/02/2017 - 12:00

John A. wrote, "Wait, so 'Cancel' is 'Continue' and 'OK' is really 'Cancel'!?"


"Not only that; we are thankful too!" writes Bob S.


"With those NaN folks viewing my profile on, it's only a matter of time before the world beats a path to my door!" writes Jason K.


Andrea S. wrote, "I'm not sure what fail(ed) but it definitely fail(ed)."


"Never thought I'd say it, but thank goodness for unpatched OS! Now I don't have to pay the parking meter!" writes Juan J.


"Congrats on your new job... Oh wait...what?!" Leslie A. writes.


Tony wrote, "My laptop seems to think it's REALLY good at charging its battery."


[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
Categories: Fun/Other

CodeSOD: Switched Over

Thu, 06/01/2017 - 12:30

Twelve years ago, a company decided they needed a website. They didn’t have any web developers, and they didn’t want to hire any, so they threw a PHP manual at the new hire who happened to “be good with computers”, and called it a day.

Ms. “Good With Computers” actually learned something from the experience, and moved on to a lucrative career in web development. Unfortunately, she left behind the code she learned by doing, and now Bert has been brought in to clean up the code.

Take this block, which translates an airport code into a location name…

switch ($v) { case "EIN": $ori = "Eindhoven"; break; case "EIN": $ori = "Eindhoven"; break; case "EIN": $ori = "Eindhoven"; break; case "EIN": $ori = "Eindhoven"; break; case "EIN": $ori = "Eindhoven"; break; case "EIN": $ori = "Eindhoven"; break; default: break; } switch ($b) { case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; case "WRO": $des = "Wroclaw"; break; default: break; }

There’s hundreds of lines of this, following the same pattern- one switch block with the same condition repeated many times for each possible airport code. These blocks don’t exist in a function, either- they’re slapped right into the global namespace.

hljs.initHighlightingOnLoad(); [Advertisement] Otter enables DevOps best practices by providing a visual, dynamic, and intuitive UI that shows, at-a-glance, the configuration state of all your servers. Find out more and download today!
Categories: Fun/Other


Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer