You are here

The Daily WTF

Subscribe to The Daily WTF feed
Curious Perversions in Information Technology
Updated: 51 min 33 sec ago

Bank $Security

Tue, 03/20/2018 - 11:30

Banks. They take your money and lend it to others. They lend money deposited by other people to you, either as a car loan, mortgage, or for credit card purchases. For this privilege, you give them all of your personal information, including your social security number. Implicit in that exchange is the fact that the bank should keep your personal information confidential. Security is important. One might think that such a concept would be important to banks. One would be wrong.

To be fair, the high ranking people at the banks probably believe that all of their customer information should be - and is - secure and protected. Unfortunately, there are multiple layers of middle and lower management (that we all know all too well) that might not comprehend that point.

The other thing that banks do is nightly batch processing to keep assorted records updated, generate TPS reports, issue bills, update financial inventory, credit usage and so forth. Since customers tend to hit ATMs at all hours of the day and night, you want your systems-update processing to be able to occur while the system is live. To that end, date and timestamp ranges of transactions to be processed for a given business period usually come into play in some form. The point is that you shield your ongoing transactions from reconciliation activity by excluding it from the reconciliations. The beat business goes on.

Randy worked at a major bank in the Pittsburgh, PA area. Considering that it's a major bank, it seemed odd that their customer facing website was often down for more than an hour at a time during business hours. When he started in 2016, it took about a month to get permissions to get the development tools he needed installed. Hmmm, perhaps they are vigilant about controlling access to their environments, even development; possibly a good, if bureaucratic sign. Once set up, he was assigned to work on their Web Banking app which was written not in MVC but in ASP.NET WebForms. OK, maybe they're slow to adopt newer technologies because they want someone else to beta test them. Caution can be a good sign.

As part of doing his work, Randy sent SOAP messages to the mainframe to retrieve test data for developmental testing. One day, he deduced that the test social security number was that of his boss. He verified this by asking his boss what he had for lunch that day. Sure enough, there were debit card charges for it in the test environment. Uh oh.

That's right; live data in the test environment. Anyone with even novice skills could have gotten social security, routing and account numbers for every customer of the bank! Rather than fight with the, ahem, highly knowledgeable individuals that thought that this was a good setup - and potentially be blamed for any breaches, Randy chose to jump ship and head for saner pastures.

Interestingly, I went to their website, which states that their business hours are M-F 8AM-8PM and Sat 9AM-3PM. At 1:15 on a clear, dry Saturday when the bank should have been open for business, I called the bank posing as a potential customer to ask why their website is often down for more than an hour at a time almost every single night. The auto attendant said to try back during business hours.


[Advertisement] ProGet can centralize your organization's software applications and components to provide uniform access to developers and servers. Check it out!
Categories: Fun/Other

CodeSOD: A Passion for Details

Mon, 03/19/2018 - 11:30

Passion projects are so common in our industry that there are some people who won’t hire you as a programmer if you’re not also programming in your free time. That’s TRWTF, honestly. There’s nothing wrong with being the kind of programmer who shows up for your 9–5 and then goes home and doesn’t touch a computer until the next day.

There’s also nothing wrong with passion projects. I have a bunch of them, usually carefully chosen to have absolutely no utility whatsoever, so they never start feeling like a job.

A Fish of Greater Size (FoGS) has a passion project, which they work on with a number of friends. It’s a web application written in C… or C++… or maybe a little of both? FoGS isn’t entirely certain what they’re using precisely. It’s an existing code base.

In that code base, there’s a CSS file. It sits in the site’s root directory, but there’s no entry in source control explaining how it got there. There’s no developer on the team who knows how it got there. None of them admits to putting it there. And yet, there it sits.

ls > details > summary { margin-left: calc(1em - 2px); } details > details > details > summary { margin-left: calc(2em - 4px); } details > details > details > details > summary { margin-left: calc(3em - 6px); } details > details > details > details > details > summary { margin-left: calc(4em - 8px); } details > details > details > details > details > details > summary { margin-left: calc(5em - 10px); } details > details > details > details > details > details > details > summary { margin-left: calc(6em - 12px); } details > details > details > details > details > details > details > details > summary { margin-left: calc(7em - 14px); } details > details > details > details > details > details > details > details > details > summary { margin-left: calc(8em - 16px); } details > details > details > details > details > details > details > details > details > details > summary { margin-left: calc(9em - 18px); } details > details > details > details > details > details > details > details > details > details > details > summary { margin-left: calc(10em - 20px); } details > details > details > details > details > details > details > details > details > details > details > details > summary { margin-left: calc(11em - 22px); } details > details > details > details > details > details > details > details > details > details > details > details > details > summary { margin-left: calc(12em - 24px); } details { border-left: 1px solid black; } details { margin-left: 1px; }

As you can see, this project is all about the details.

hljs.initHighlightingOnLoad(); [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
Categories: Fun/Other

Error'd: Drunken Parsing

Fri, 03/16/2018 - 11:30

"Hi, $(lookup(BOOZE_SHOP_OF_LEAST_MISTRUST))$ Have you been drinking while parsing your variables?" Tom G. writes.


"Alright, so, I can access this website at more than an hour...Yeah. Okay," wrote Robin.


Mark W. writes, "Of course, Apple, I downloaded @@itemName@@. I mean, how could I not? It got @@starCount@@ stars in the app store!"


"One would hope that IEEE knows how to do this engineering thing," Chris S. wrote.


Mike H. writes, "I don't know what language this is in, but if I had to guess, it appears to be in Yak."


"Sexy ladies AND inline variables? YES! I WANT TO LEARN MORE!" wrote Chris.


[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
Categories: Fun/Other

Representative Line: Flushed Down the Pipe

Thu, 03/15/2018 - 11:30

No matter how much I personally like functional programming, I know that it is not a one-size fits all solution for every problem.

Vald M knows this too. Which is why they sent us an email that simply said: “We have a functional programmer on the team”, with this representative line attached.

function groupByBreakdown (breakdowns) { return R.pipe(,,, [R.prop, R.identity]))) ); };

The use of R.pipe is a good argument about why the proposed pipeline operator is a terrible idea whose time isn’t going to come. Ever. Yes, there’s value in being able to easily compose functions into a pipeline. Shells support pipelining for a reaason, after all. But it's an awkward fit into imperative languages, and unfortunately, the tool is too dangerous to be used in real-world code. Even functional languages, like Elixir, warn you against abusing the pipeline. Mixing opaque functional styles with JavaScript is just flirting with disaster. I mean, more disaster than JavaScript already is.

hljs.initHighlightingOnLoad(); [Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!
Categories: Fun/Other

CodeSOD: Lightweight Date Handling

Wed, 03/14/2018 - 11:30

Darlene has a co-worker who discovered a problem: they didn’t know or understand any of the C++ libraries for manipulating dates and times. Checking the documentation or googling it is way too much to ask, so instead they opted to use the tools they aalready understood- a database. We’ve seen that before.

There was just one other problem: this application wasn’t data-driven, and thus didn’t have a database to query.

Darlene’s co-worker had the solution to that: create an in-memory Sqlite database!

std::string foo::getTimeStamp() { static const char *sqlStmt = "SELECT strftime( '%Y-%m-%dT%H:%M:%fZ', CURRENT_TIMESTAMP );"; sqlite3 *db = 0; int sqliteRC = SQLITE_OK; char *sqlErr = 0; // Well we should return something that can be used, so picked an // arbitrary date, which I believe is the time of the first armistice // for the First World War std::string rval = "1918-11-11T11:11:00.000Z"; sqliteRC = sqlite3_open( ":memory:", &db ); if( sqliteRC != SQLITE_OK ) { LOG( Log::Warn ) << "Failed to open sqlite memory DB, with error [" << sqlite3_errmsg( db ) << "]"; return rval; } sqliteRC = sqlite3_exec( db, sqlStmt, &::populate, (void*) &rval, &sqlErr ); if( sqliteRC != SQLITE_OK ) { LOG( Log::Warn ) << "Failed to gather current time stamp" << " from sqlite memory DB with error [" << sqlErr << "]"; sqlite3_free( sqlErr ); } sqliteRC = sqlite3_close( db ); if( sqliteRC != SQLITE_OK ) { // We may leak some memory if this happens LOG( Log::Warn ) << "Failed to close sqlite memory DB with error [" << sqlite3_errmsg( db ) << "]"; } db = 0; return rval; }

This is very lightweight- it's Sqlite, after all. There's nothing light about strftime or its ilk. Just look at the names.

hljs.initHighlightingOnLoad(); [Advertisement] Ensure your software is built only once and then deployed consistently across environments, by packaging your applications and components. Learn how today!
Categories: Fun/Other

CodeSOD: And Now You Have Two Problems

Tue, 03/13/2018 - 11:30

We all know the old saying: “Some people, when confronted with a problem, think ‘I know, I’ll use regular expressions.’ Now they have two problems.” The quote has a long and storied history, but Roger A’s co-worker decided to take it quite literally.

Specifically, they wanted to be able to build validation rules which could apply a regular expression to the input. Thus, they wrote the RegExpConstraint class:

public class RegExpConstraint { private readonly Regex _pattern; private readonly string _unmatchedErrorMessage; protected string UnmatchedErrorMessage => _unmatchedErrorMessage; public RegExpConstraint(string pattern, string unmatchedErrorMessage) { _pattern = new Regex(pattern); _unmatchedErrorMessage = unmatchedErrorMessage; } /// <summary> /// Check if the given value match the RegExp. Return the unmatched error message if it doesn't, null otherwise. /// </summary> public virtual string CheckMatch(string value) { if (!_pattern.IsMatch(value)) { return _unmatchedErrorMessage; } return null; } }

This “neatly” solved the problem of making sure that an input string matched a regex, if by “neatly” you mean, “returns a string instead of a boolean value”, but it introduced a new problem: what if you wanted to make certain that it absolutely didn’t match a certain subset of characters. For example, if you wanted “\:*<>|@” to be illegal characters, how could you do that with the RegExpConstraint? By writing a regex like this: [^\:*<>|@]? Don’t be absurd. You need a new class.

public class RegExpExcludeConstraint : RegExpConstraint { private Regex _antiRegex; public Regex AntiRegex => _antiRegex; public RegExpExcludeConstraint() : base(null, null) { } /// <summary> /// Constructor /// </summary> /// <param name="pattern">Regex expression to validate</param> /// <param name="antiPattern">Regex expression to invalidate</param> /// <param name="unmatchedErrorMessage">Error message in case of invalidation</param> public RegExpExcludeConstraint(string pattern, string antiPattern, string unmatchedErrorMessage) : base(pattern, unmatchedErrorMessage) { _antiRegex = new Regex(antiPattern); } /// <summary> /// Check if the constraint match /// </summary> public override string CheckMatch(string value) { var baseMatch = base.CheckMatch(value); if (baseMatch != null || _antiRegex.IsMatch(value)) { return UnmatchedErrorMessage; } return null; } }

Not only does this programmer not fully understand regular expressions, they also haven’t fully mastered inheritance. Or maybe they know that this code is bad, as they named one of their parameters antiPattern. The RegExpExcludeConstraint accepts two regexes, requires that the first one matches, and the second one doesn’t, helpfully continuing the pattern of returning null when there’s nothing wrong with the input.

Perhaps the old saying is wrong. I don’t see two problems. I see one problem: the person who wrote this code.

hljs.initHighlightingOnLoad(); [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Categories: Fun/Other

Daylight Losing Time

Mon, 03/12/2018 - 12:30

The second Sunday of March has come to pass, which means if you're a North American reader, you're getting this an hour earlier than normal. What a bonus! That's right, we all got to experience the mandatory clock-changing event known as Daylight Saving Time. While the sun, farm animals, toddlers, etc. don't care about an arbitrary changing of the clock, computers definitely do.

Early in my QA career, I had the great (dis)pleasure of fully regression testing electronic punch clocks on every possible software version every time a DST change was looming. It was every bit as miserable as it sounds but was necessary because if punches were an hour off for thousands of employees, it would wreak havoc on our clients' payroll processing.

Submitter Iain would know this all too well after the financial services company he worked for experienced a DST-related disaster. As a network engineer, Iain was in charge of the monitoring systems. Since their financial transactions were very dependent on accurate time, he created a monitor that would send him an alert if any of the servers drifted three or more seconds from what the domain controllers said the time should be. It rarely ever went off since the magic of NTP was in use to keep all the server clocks correct.

One fateful early morning of the 2nd Sunday in March, Iain's phone exploded with alerts from the monitor. Two load-balanced web servers were alternately complaining about being an entire hour off from the actual time. The servers in question were added in recent months and had never caused an issue before.

He rolled out of bed to grab his laptop to begin troubleshooting. The servers were supposed to connect to time sync with their domain controller, which would NTP with an external stratum 1 time server. He figured one or more of the servers were having network connectivity issues when the time change occurred and were now confused as to who had the right time.

Iain sent an NTP packet to each of the troubled servers expecting to see the domain controller as the reference server. Instead, he saw the IP addresses of TroublesomeServer1 and TroublesomeServer2. Thinking he did something wrong in an early morning fog, he ran it again only to get the same result. It seemed that the two servers were pointed to each other for NTP.

While that was a ridiculous setup, it wouldn't explain why they were off by an entire hour and kept switching their times. Iain noticed that the old-fashioned clock on his desk showed the time was a bit after 2 AM, while the time on his laptop was a bit after 3 AM. It dawned on him that the time issues had to be related to the Daylight Saving Time change. The settings for that were kept in the load balancer, which he had read-only access to.

In the load balancer console, he found that TroublesomeServer1 was correctly set to update its time for Daylight Saving, while TroublesomeServer2 was not. Since they were incorrectly set to each other for NTP, when TroublesomeServer1 jumped ahead an hour, TroublesomeServer2 would follow. But then TroublesomeServer2 would realize it wasn't supposed to adjust for DST, so it would jump back an hour, bringing TroublesomeServer1 with it. This kept repeating itself, which explained the volume of alerts Iain got.

Since he was powerless to correct the setting on the load balancer, he made a call to his manager, who escalated to another manager and so on until they tracked down who had access to make the setting change. Three hours later, the servers were on the correct time. But the mess of correcting all the overnight transactions that happened during this window were just beginning. The theoretical extra hour of daylight provided was negated by everyone spending hours in a windowless conference room adjusting financial data by hand.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Downloadtoday!
Categories: Fun/Other

Error'd: ICANN't Even...

Fri, 03/09/2018 - 12:00

Jeff W. writes, "You know, I don't think this one will pass."


"Wow! This Dell laptop is pretty sweet!...but I wonder what that other 999999913 GB of data I have can contain..." writes Nicolas A.


"XML is big news at our university!" Gordon S. wrote.


Mark B. wrote, "On Saturday afternoons this British institution lets its hair down and fully embraces the metric system."


"Apparently, my computer and I judge success by very different standards," Michael C. writes.


"I agree you can't disconnect something that doesn't exist, more so when it's named two random Unicode characters," wrote Jurjen.


[Advertisement] Onsite, remote, bare-metal or cloud – create, configure and orchestrate 1,000s of servers, all from the same dashboard while continually monitoring for drift and allowing for instantaneous remediation. Download Otter today!
Categories: Fun/Other

CodeSOD: Let's Set a Date

Thu, 03/08/2018 - 12:30

Let’s imagine, for a moment, that you came across a method called setDate. Would you think, perhaps, that it stores a date somewhere? Of course it does. But what else does it do?

Matthias was fixing some bugs in a legacy project, and found himself asking exactly that question.

function setDate(objElement, strDate, objCalendar) { if (objElement.getAttribute("onmyfocus")) { eval(objElement.getAttribute("onmyfocus").replace(/this/g, "$('" + + "')")); } else if (objElement.onfocus && objElement.onfocus.toString()) { eval(GetInnerFunction(objElement.onfocus.toString()).replace(/this/g, "$('" + + "')")); } objElement.value = parseDate(strDate); if (objElement.getAttribute("onmyblur")) { eval(objElement.getAttribute("onmyblur").replace(/this/g, "$('" + + "')")); } else if (objElement.onblur && objElement.onblur.toString()) { eval(GetInnerFunction(objElement.onblur.toString()).replace(/this/g, "$('" + + "')")); } if (objCalendar) { ToggleCalendar(objCalendar); } else { ToggleCalendar($('divCalendar')); } return; }

In this code, objElement and objCalendar are both expected to be DOM elements. strDate, as the name implies, is a string holding a date. You can see a few elements in the code which obviously have something to do with the actual function of setting a date: objElement.value = parseDate(strDate) and the conditional about trying to toggle the calendar object seem like they might have something to do with managing the date.

It’s the rest of the code that gets… weird. The purpose, at a guess, is that this setDate method is emulating a user interacting with a DOM element- perhaps this is part of some bolted-on calendar widget- so they want to fire the on-focus and on-blur methods of the underlying element. That, alone, would be an ugly but serviceable hack.

But that’s not what they do.

First, they’ve apparently created attributes onmyfocus and onmyblur. Should the element have those attributes, they extract the value there, and replace any references to this with a call to $(), passing in the objElementId… and then they eval it.

If there isn’t a special onmyfocus/onmyblur attribute, they instead check for the more normal onfocus/onblur event handlers. Which are functions. But this code doesn’t want functions, so it converts them to a string and replaces this again, before passing it back to eval.

Replacing this means that they were trying to reinvent function.apply, a JavaScript method that allows you to pass in whatever object you want to be this within the function you’re calling. But, at least in the case of the onfocus/onblur, this isn’t necessary, since every browser has had a method to dispatchEvent or createEvent since time immemorial. You don’t need to mangle a function to emulate an event.

The jQuery experts might notice that $ and say, “Well, heck, if they’re using jQuery, that has a .trigger() method which fires events.” That’s a good thought, but this code is actually worse than it looks. I’ll allow Matthias to explain:

$ is NOT jQuery, but a global function that does a getElementById-lookup

hljs.initHighlightingOnLoad(); [Advertisement] Universal Package Manager - ProGet easily integrates with your favorite Continuous Integration and Build Tools, acting as the central hub to all your essential components. Learn more today!
Categories: Fun/Other

CodeSOD: Just One More Point

Wed, 03/07/2018 - 12:30

Tim B. had been tasked with updating an older internal application implemented in Java. Its primary purpose was to read in and display files containing a series of XY points—around 100,000 points per file on average—which would then be rendered as a line chart. It was notoriously slow, taking 1-2 minutes to process each file, but otherwise remained fairly stable.

Except that lately, some newer files were failing during the loading process. Tim quickly identified the problem—date formats had changed—and fixed the necessary code. Since the code that read in the XY points happened to reside in the same class, Tim asked his boss whether he could take a crack at killing two birds with one stone. With her approval, he dug in to figure out why the loading process was so slow.

//Initial code, pulled from memory so forgive any errors. try { //The 3rd party library we are passing the values to requires //an array of doubles double[][] points = null; BufferedReader input = new BufferedReader(new FileReader(aFile)); try { String line = null; while (( line = input.readLine()) != null) { //First, get the XY points from line using a convenience class //to parse out the values. XYPoint p = new XYPoint(line); //Now, to store the points in the array. if ( points == null ) { //Okay, we've got one point so far. points = new double[1][2]; points[0][0] = p.X; points[0][1] = p.Y; } else { //Uh oh, we need more room. Let's create an array that's one larger //and copy all of our points so far into it. double[][] newPointArray = new double[points.length + 1][2]; for ( int i = 0; i < points.length; i++ ) { newPointArray[i][0] = points[i][0]; newPointArray[i][1] = points[i][1]; } //Now we can add the new point! newPointArray[points.length][0] = p.X; newPointArray[points.length][1] = p.Y; points = newPointArray; } } //Now, we can pass this to our next function drawChart( points ); } finally { input.close(); } } catch (IOException ex) { ex.printStackTrace(); } //End original code

After scouring the code twice, Tim called over a few coworkers to have a look for themselves. Unfortunately, no, he wasn't reading it wrong. Apparently the original developer, who no longer worked there, had run into the problem of not knowing ahead of time how many points would be in each file. However, he'd needed an array of doubles to pass to the next library so he could use a list, which only accepted objects. Thus had he engineered a truly brillant workaround.

Tim determined that for the average file of 100,000 points, each import required a jaw-dropping 2 billion copy operations (1 billion for the Xs, 1 billion for the Ys). After a quick refactoring to use an ArrayList, followed by a copy to a double array, the file load time went from minutes to nearly instantaneous.

//Re-factored code below. try { //The 3rd party library we are passing the values to requires //an array of doubles double[][] points = null; ArrayList xyPoints = new ArrayList(); BufferedReader input = new BufferedReader(new FileReader(aFile)); try { String line = null; while (( line = input.readLine()) != null) { xyPoints.add( new XYPoint(line) ); } //Now, convert the list to an array points = new double[xyPoints.size()][2]; for ( int i = 0; i < xyPoints.size(); i++ ) { points[i][0] = xyPoints.get(i).X; points[i][1] = xyPoints.get(i).Y; } //Now, we can pass this to our next function drawChart( points ); } finally { input.close(); } } catch (IOException ex) { ex.printStackTrace(); } //End re-factored code. hljs.initHighlightingOnLoad(); code { font-family: Consolas, monospace; } [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 Unbidden Password

Tue, 03/06/2018 - 12:30

So here's a thing that keeps me up at night: we get a lot of submissions about programmers who cannot seem to think like users. There's a type of programmer who has never not known how computers worked, whose theory of computers in their mind has been so accurate for so long that they can't look at things in a different way. Many times, they close themselves off from users, insisting that if the user had a problem with using the software, they just don't know how computers work and need to educate themselves. Rather than focus on what would make the software more usable, they program what is easiest for the computer to do, and call it a day.

The same is sometimes true of security concerns. Rather than focus on what would be secure, on what the best practices are in the industry, these programmers hammer out something easy and straightforward and consider it good enough. Today's submitter, Rick, recently ran across just such a "security system."

Rick was shopping at a small online retailer, and found some items he liked. He got through the "fill in all your personal information and hope they have good security" stage of the online check-out process and placed his order. At no time was he asked if he wanted an account—which is good, because he never signs up for accounts at small independent retailers, preferring for his card information not to be stored at all. He was asked to fill in his email, which is common enough; a receipt and shipping updates are usually sent to the email associated with the order.

Sure enough, Rick received an email from the retailer moments later. Only this wasn't a receipt. It was, in fact, confirmation of a new account creation ... complete with a password in plain text.

Rick was understandably alarmed. He headed back to the site immediately to change the password to a longer, more secure one-off he could store in a password manager and never, ever have emailed to him in plaintext. But once on the site, he could find no sign of a login button or secure area. So at this point, he had an insecure password he couldn't appear to use, for an account he didn't even want in the first place.

Rick sent an email, worried about this state of affairs. The reply came fairly rapidly, from someone who was likely the sole tech department for the company: this was by design. All Rick had to do next time he purchased any goods was to enter the password on the checkout screen, and it would remember his delivery address for him.

As Rick put it:


So you send a random password insecurely and don't allow the user to change it, only because you think users would rather leave your web page to login to their email, search for the email that includes the password and copy that password in your web page, instead of just filling in their address that they know by heart.

Of course in this case, it doesn't matter one bit: Rick isn't going back to buy anything else. He didn't name-and-shame, but I encourage you to do so in the comments if you know of a retailer with similarly bad security. After all, there's only one thing that can beat programmer arrogance in this kind of situation: losing customers.

[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

CodeSOD: A Very Private Memory

Mon, 03/05/2018 - 12:30

My the gods spare us from “clever” programmers.

Esben found this little block of C# code:

System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess(); long check = proc.PrivateMemorySize64; if (check > 1150000000) { MessageBox.Show(Strings.ReportForm_HighMemoryUse); return; }

Even before you check on the objects and methods in use, it’s hard to figure out what the heck this method is supposed to do. If some memory stat is over a certain size, pop up a message box and break out of the method? Why? Isn’t this more the case for an exception? Since the base value is hard coded, what happens if I run this code on a machine with way more RAM? Or configure the CLR to give my process more memory? Or…

If the goal was to prevent an operation from starting if there wasn’t enough free memory, this code is dumb. It’s “clever”, in the sense that the original developer said, “Hey, I’m about to do something memory intensive, let me make sure there’s enough memory” and then patted themselves on the head for practicing defensive programming techniques.

But that isn’t what this code exactly does. PrivateMemorySize simply reports how much memory is allocated to the process. Not how much is free, not how much is used, just… how much there is. That number may grow, as the process allocates objects, so if it’s too large relative to available memory… you’ll be paging a bunch, which isn’t great I suppose, but it still doesn’t explain this check.

This is almost certainly means this was a case of “works on my/one machine”, where the developer tuned the number 1550000000 based on one specific machine. Either that, or there was a memory leak in the code- and yes, even garbage collected languages can still have memory leaks if you’re an agressively “clever” programmer- and this was the developer’s way of telling people “Hey, restart the program.”

hljs.initHighlightingOnLoad(); [Advertisement] Otter allows you to easily create and configure 1,000's of servers, all while maintaining ease-of-use, and granular visibility down to a single server. Find out more and download today!
Categories: Fun/Other

Error'd: I Don't Always Test my Code, but When I do...

Fri, 03/02/2018 - 12:30

"Does this mean my package is here or is it also in development?" writes Nariim.


Stuart L. wrote, "Who needs a development environment when you can just test in production on the 'Just In' feed?"


"It was so nice of Three to unexpectedly include me - a real user - in their User Acceptance Testing. Yeah, it's still not fixed," wrote Paul P.


"I found this great nearby hotel option that transcended into the complex plane," Rosenfield writes.


Stuart L. also wrote in, "I can't think of a better place for BoM to test out cyclone warnings than in production."


"The Ball Don't Lie blog at Yahoo! Sports seems to have run out of content during the NBA Finals so they started testing instead," writes Carlos S.


[Advertisement] Otter allows you to easily create and configure 1,000's of servers, all while maintaining ease-of-use, and granular visibility down to a single server. Find out more and download today!
Categories: Fun/Other

CodeSOD: What a Stream

Thu, 03/01/2018 - 12:30

In Java 8, they added the Streams API. Coupled with lambdas, this means that developers can write the concise and expressive code traditionally oriented with functional programming. It’s the best bits of Java blended with the best bits of Clojure! The good news, is that it allows you to write less code! The better news is that you can abuse it to write more code, if you’re so inclined.

Antonio inherited some code written by “Frenk”, who was thus inclined. Frenk wasn’t particularly happy with their job, but were one of the “rockstar programmers” in the eyes of management, so Frenk was given the impossible-to-complete tasks and given complete freedom in the solution.

Frenk had a problem, though. Nothing Frenk was doing was actually all that impossible. If they solved everything with code that anyone else could understand, they wouldn’t look like an amazing genius. So Frenk purposefully obfuscated every line of code, ignoring indentation, favoring one-character variable names, and generally trying to solve each problem in the most obtuse way possible.

Which yielded this.

Resource[] r; //@Autowired ndr Map<File, InputStream> m = null; if (file != null) { m.put(file, new FileInputStream(file));}else { m = -> { try { return x.getFile(); } catch (Exception e) { throw new IllegalStateException(e);}}, x -> {try{return x.getInputStream();}catch (Exception e){throw new IllegalStateException(e) ;}})); }

As purposefully unreadable code, I’d say that Frenk fails. That’s not to say that it isn’t bad, but Frenk’s attempts to make it unreadable… just make it annoying. I understand what the code does, but I’m just left wondering at why.

I can definitely say that this has never been tested in a case where the file variable is non-null, because that wouldn’t work. Antonio confirms that their IDE was throwing up plenty of warnings about calling a method on a variable that was probably null, with the m.put(…) line. It’s nice that they half-way protect against nulls- one variable is checked, but the other isn’t.

Frenk’s real artistry is in employing streams to convert an array to a map. On its surface, it’s not an objectively wrong approach- this is the kind of things streams are theoretically good at. Examine each element in the array, and apply a lambda that extracts the key and another lambda that extracts the value and put it into a map.

There are many real-world cases where I might use this exact technique. But in this case, Antonio refactored it to something a bit cleaner:

Resource[] resources; //@Autowired again Map<File, InputStream> resourceMap = new HashMap<>(); if (file != null) resourceMap.put(file, new FileInputStream(file)); else for (Resource res : resources) resourceMap.put(res.getFile(), res.getInputStream());

Here, the iterative approach is much simpler, and the intent of the code is more clear. Just because you have a tool doesn’t make it the right tool for the job. And before you wonder about the lack of exception handling- both the original block and the refactored version were already wrapped up in an exception handling block that can handle the IOException that failed access to the files would throw.

hljs.initHighlightingOnLoad(); [Advertisement] Onsite, remote, bare-metal or cloud – create, configure and orchestrate 1,000s of servers, all from the same dashboard while continually monitoring for drift and allowing for instantaneous remediation. Download Otter today!
Categories: Fun/Other

CodeSOD: The Part Version

Wed, 02/28/2018 - 12:30

Once upon a time, there was a project. Like most projects, it was understaffed, under-budgeted, under-estimated, and under the gun. Death marches ensued, and 80 hour weeks became the norm. The attrition rate was so high that no one who was there at the start of the project was there at the end of the project. Like the Ship of Theseus, each person was replaced at least once, but it was still the same team.

Eric wasn’t on that team. He was, however, a consultant. When the project ended and nothing worked, Eric got called in to fix it. And then called back to fix it some more. And then called back to implement new features. And called back…

While diagnosing one problem, Eric stumbled across the method getPartVersions. A part number was always something like “123456–1”, where the first group of numbers were the part number itself, and the portion after the “-” was the version of that part.

So, getPartVersions, then, should be something like:

String getPartVersions(String part) { //sanity checks omitted return part.split("-")[1]; }

The first hint that things weren’t implemented in a sane way was the method’s signature:

private List<Integer> getPartVersions(final String searchString)

Why was it returning a list? The calling code always used the first element in the list, and the list was always one element long.

private List<Integer> getPartVersions(final String searchString) { final List<Integer> partVersions = new ArrayList<>(); if (StringUtils.indexOfAny(searchString, DELIMITER) != -1) { final String[] splitString = StringUtils.split(searchString, DELIMITER); if (splitString != null && splitString.length > 1) { //this is the partIdentifier, we make it empty it so it will not be parsed as a version splitString[0] = ""; for (String s : splitString) { s = s.trim(); try { if (s.length() <= 2) { partVersions.add(Integer.parseInt(s)); } } catch (final NumberFormatException ignored) { //Do nothing probably not an partVersion } } } } return partVersions; }

A part number is always in the form “{PART}-{VERSION}”. That is what the variable searchString should contain. So, they do their basic sanity checks- is there a dash there, does it split into two pieces, etc. Even these sanity checks hint at a WTF, as StringUtils obviously is just wrappers around built-in string functions.

Things get really odd, though, with this:

splitString[0] = ""; for (String s : splitString) //…

Throw away the part number, then iterate across the entire series of strings we made by splitting. Check the length- if it’s less than or equal to two, it must be the part version. Parse it into an integer and put it in the list. The real “genius” element of this code is that since the first entry in the splitString array is set to an empty string, Integer.parseInt will throw an exception, thus ensuring we don’t accidentally put the part number in our list.

I’ve personally written methods that have this sort of tortured logic, and given what Eric tells us about the history of the project, I suspect I know what happened here. This method was written before the requirement it fulfilled was finalized. No one, including the business users, actually knew the exact format or structure of a part number. The developer got five different explanations, which turned out to be wrong in 15 different ways, and implemented a compromise that just kept getting tweaked until someone looked at the results and said, “Yes, that’s right.” The dev then closed out the requirement and moved onto the next one.

Eric left the method alone: he wasn’t being paid to refactor things, and too much downstream code depended on the method signature returning a List<Integer>.

hljs.initHighlightingOnLoad(); [Advertisement] Application Release Automation for DevOps – integrating with best of breed development tools. Free for teams with up to 5 users. Download and learn more today!
Categories: Fun/Other


Tue, 02/27/2018 - 12:30

In software development, there are three kinds of problems: small, big and subtle. The small ones are usually fairly simple to track down; a misspelled label, a math error, etc. The large ones usually take longer to find; a race condition that you just can't reproduce, an external system randomly feeding you garbage, and so forth.

The subtle problems are an entirely different beast. It can be as simple as somebody entering 4321 instead of 432l (432L), or similar with 'i', 'l', '1', '0' and 'O'. It can be an interchanged comma and period. It can be something more complex, such as an unsupported third party library that throws back errors for undefined conditions, but randomly provides so little information as to be useful to neither user nor developer.

Brujo B encountered such a beast back in 2003 in a sub-equatorial bank that had been especially fond of VB6. This bank had tried to implement standards. In particular, they wanted all of their error messages to appear consistently for their users. To this end, they put a great deal of time and effort into building a library to display error messages in a consistent format. Specifically:


An example error message might be:

File Not Found - 127 / File 'your.file' could not be found / FileImporter

Unfortunately, the designers of this routine could not compensate for all of the third party tools and libraries that did NOT set some/most/all of those variables. This led to interesting presentations of errors to both users and developers:

- 34 / Network Connection Lost / Unauthorized - 401 //

Crystal Reports was particularly unhelpful, in that it refused to populate any field from which error details could be obtained, leading to the completely unhelpful:


...which could only be interpreted as Something really bad happened, but we don't know what that is and you have no way to figure that out. It didn't matter what Brujo and peers did. Everything that they tried to cajole Crystal Reports into giving context information failed to varying degrees; they could only patch specific instances of errors; but the Ever-Useless™ -0// error kept popping up to bite them in the arse.

After way too much time trying to slay the beast, they gave up, accepted it as one of their own and tried their best to find alternate ways of figuring out what the problems were.

Several years after moving on to saner pastures, Brujo returned to visit old friends. On the wall they had added a cool painting with many words that "describe the company culture". Layered in were management approved words, like "Trust" and "Loyalty". Some were more specific in-jokes, names of former employees, or references to big achievements the organization had made.

One of them was -0//

[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

CodeSOD: Waiting for the Future

Mon, 02/26/2018 - 12:30

One of the more interesting things about human psychology is how bad we are at thinking about the negative consequences of our actions if those consequences are in the future. This is why the death penalty doesn’t deter crime, why we dump massive quantities of greenhouse gases into the atmosphere, and why the Y2K bug happened in the first place, and why we’re going to do it again when every 32-bit Unix system explodes in 2038. If the negative consequence happens well after the action which caused it, humans ignore the obvious cause and effect and go on about making problems that have to be fixed later.

Fran inherited a bit of technical debt. Specifically, there’s an auto-numbered field in the database. Due to their business requirements, when the field hits 999,999, it needs to wrap back around to 000,001. Many many years ago, the original developer “solved” that problem thus:

function getstan($callingMethod = null) { $sequence = 1; // get insert id back $rs = db()->insert("sequence", array( 'processor' => 'widgetsinc', 'RID' => $this->data->RID, 'method' => $callingMethod, 'card' => $this->data->cardNumber ), false, false); if ($rs) { // if query succeeded... $sequence = $rs; if ($sequence > 999999) { db()->q("delete from sequence where processor='widgetsinc'"); db()->insert("sequence", array('processor' => 'widgetsinc', 'RID' => $this->data->RID, 'card' => $this->data->cardNumber), false, false); $sequence = 1; } } return (substr(str_pad($sequence, 6, "0", STR_PAD_LEFT), -6)); }

The sequence table uses an auto-numbered column. They insert a row into the table, which returns the generated ID used. If that ID is greater than 999,999, they… delete the old rows. They then insert a new row. Then they return “000001”.

Unfortunately, sequences don’t work this way in MySQL, or honestly any other database. They keep counting up unless you alter or otherwise reset the sequence. So, the counter keeps ticking up, and this method keeps deleting the old rows and returning “000001”. The original developer almost certainly never tested what this code does when the counter breaks 999,999, because that day was so far out into the future that they could put off the problem.

Speaking of putting off solving problems, Fran also adds:

For the past 2 years this function has been returning 000001 and is starting to screw up reports.

Broken for at least two years, but only now is it screwing up reports badly enough that anyone wants to do anything to fix it.

hljs.initHighlightingOnLoad(); [Advertisement] Easily create complex server configurations and orchestrations using both the intuitive, drag-and-drop editor and the text/script editor.  Find out more and download today!
Categories: Fun/Other

Error'd: Everybody's Invited!

Fri, 02/23/2018 - 12:30

"According to Outlook, it seems that I accidentally invited all of the EU and US citizens combined," writes Wouter.


"Just an array a month sounds like a pretty good deal to me! And I do happen to have some arrays to spare..." writes Rutger W.


Lucas wrote, "VMWare is on the cutting edge! They can support TWICE as much Windows 10 as their competitors!"


"I just wish it was CurrentMonthName so that I could take advantage of the savings!" Ken wrote.


Mark B. "I had no idea that Redboxes were so cultured."


"I'm a little uncomfortable about being connected to an undefined undefined," writes Joel B.


[Advertisement] Easily create complex server configurations and orchestrations using both the intuitive, drag-and-drop editor and the text/script editor.  Find out more and download today!
Categories: Fun/Other

CodeSOD: Functional IsFunction

Thu, 02/22/2018 - 12:30

Julio S recently had to attempt to graft a third-party document viewer onto an internal web app. The document viewer was from a company which specialized in enterprise “document solutions”, which can be purchased for enterprise-sized licensing fees.

Gluing the document viewer onto their internal app didn’t go terribly well. While debugging, and browsing through the vendor’s javascript, he saw a lot of calls to a function called IsFunction. It was loaded from a “utilities.js”-type do-everything library file. Curious, Julio pulled up the implementation.

function IsFunction ( func ) { var bChk=false; if (func != "undefined") bChk=true; else bChk=false; return bChk; }

I cannot emphasize enough how beautiful this block of code is, by the standards of bad code. There’s so much there. One variable, bChk uses Hungarian notation. Nothing else seems to. It’s a totally superfluous variable, as we could just do return func != "undefined".

Then again why would we even do that? The real beauty, though, is how the name of the function and its implementation have no relationship to each other, and the implementation is utterly useless. For example:

IsFunction("Hello World"); //true IsFunction({spam: "eggs"}); //true IsFunction(function() {}); //true, but it was probably an accident IsFunction(undefined); //true IsFunction("undefined"); //false

Yes, the only time this function returns false is the specific case where you pass it the string “undefined”. Everything else IsFunction apparently. The useless function sounds important. Someone wrote it, probably as a quick attempt at vaguely defensive programming. “I should make sure my inputs are valid”. They didn’t test it. The certainly didn’t think about it. But they wrote it. And then someone else saw the function in use, and said, “Oh… I should probably use that, too.” Somewhere, there’s probably a “Style Guide”, which mandates that, before attempting to invoke a variable that should contain a function, you use IsFunction to confirm it does. It comes up in code reviews, and code has been held from going into production because someone didn't use IsFunction.

And Julio probably is the first person to actually check the implementation since it was first written.

hljs.initHighlightingOnLoad(); [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

Shiny Side Up

Wed, 02/21/2018 - 12:30

It feels as though disc-based media have always been with us, but the 1990s were when researchers first began harvesting these iridescent creatures from the wild in earnest, pressing data upon them to create the beast known as CD-ROM. Click-and-point adventure games, encyclopedias, choppy full-motion video ... in some cases, ambition far outweighed capability. Advances in technology made the media cheaper and more accessible, often for the worst. There are some US households that still burn America Online 7.0 CDs for fuel.

But we’re not here to delve into the late-90s CD marketing glut. We’re nestling comfortably into the mid-90s, when Internet was too slow and unreliable for anyone to upload installers onto a customer portal and call it a day. Software had to go out on physical media, and it had to be as bug-free as possible before shipping.

Chris, a developer fresh out of college, worked on product catalog database applications that were mailed to customers on CDs. It was a small shop with no Tech Support department, so he and the other developers had to take turns fielding calls from customers having issues with the admittedly awful VB4 installer. It was supposed to launch automatically, but if the auto-play feature was disabled in Windows 95, or the customer canceled the installer pop-up without bothering to read it, Chris or one of his colleagues was likely to hear about it.

And then came the caller who had no clue what Chris meant when he suggested, "Why don't we open up the CD through the file system and launch the installer manually?"

These were the days before remote desktop tools, and the caller wasn't the savviest computer user. Talking him through minimizing his open programs, double-clicking on My Computer, and browsing into the CD drive took Chris over half an hour.

"There's nothing here," the caller said.

So close to the finish line, and yet so far. Chris stifled his exasperation. "What do you mean?"

"I opened the CD like you said, and it's completely empty."

This was new. Chris frowned. "You're definitely looking at the right drive? The one with the shiny little disc icon?"

"Yes, that's the one. It's empty."

Chris' frown deepened. "Then I guess you got a bad copy of the CD. I'm sorry about that! Let me copy down your name and address, and I'll get a new one sent out to you."

The customer provided his mailing address accordingly. Chris finished scribbling it onto a Post-it square. "OK, lemme read that back to—"

"The shiny side is supposed to be turned upwards, right?" the customer blurted. "Like a gramophone record?"

Chris froze, then slapped the mute button before his laughter spilled out over the line. After composing himself, he returned to the call as the model of professionalism. "Actually, it should be shiny-side down."

"Really? Huh. The little icon's lying, then."

"Yeah, I guess it is," Chris replied. "Unfortunately, that's on Microsoft to fix. Let's turn the disc over and try again."

[Advertisement] Incrementally adopt DevOps best practices with BuildMaster, ProGet and Otter, creating a robust, secure, scalable, and reliable DevOps toolchain.
Categories: Fun/Other


Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer