Last minute geek

last minute tech news from around the net

Tuesday, Nov 21st

Last update01:00:00 AM

You are here: English WTF

WTF

Jumped The Gun

1904 Olympic sprint

Sheldon was a support engineer at Generic Media Co. In his 6 years with the company, he'd enjoyed working for several great managers—but then came the reorg. Once the dust cleared, he found himself in the wrong department, reporting to one of the most loathed individuals in the entire organization.

Gene was the type of manager who believed his fancy title awarded him instant respect. No engineer who spent any time working with him had anything good to say. Sheldon went in hoping for the best ... but Gene's relentless micromanaging and childish stunts quickly ground Sheldon's optimism into dust. When it came time for Sheldon to go on an extended vacation, he felt like a shell-shocked veteran limping out of the trenches.

The months away were bliss, but Sheldon couldn't enjoy the last few days out of dread. To his surprise, though, Gene wasn't waiting at his cubicle with twelve urgent tasks upon his return. There hadn't been a peep from Gene all vacation long: no emails, no meeting requests. It was getting close to performance review time; nothing about that, either.

As Sheldon worked through his vacation backlong, it became starkly apparent that he was being allowed to work through his vacation backlog. No panicky IMs, emails, cubicle pop-ins. The radio silence extended into days, then weeks. Sheldon began to wonder whether Gene even still worked there. Not wanting to kick a potential sleeping dragon in the nose, he asked his coworkers instead.

"Of course he's still here," one of them grumbled. "If they haven't canned him by now, they're not going to."

Soon after, Sheldon found out he had it exactly backwards.

A meeting invitation from Gene landed in his inbox. Catch-up meeting, tomorrow. No agenda, no room booked. Distracted with work, Sheldon didn't immediately accept the meeting. By the end of the day, his desk phone rang.

Gene. When had Gene ever phoned his desk? Frowning, Sheldon picked up.

"I need you to accept the invite," Gene blurted with no preamble.

It was then that Sheldon's paranoia clued him into reality. Gene still works here. I'm the one who's out. Gene's extended avoidance had been just another of his immature games. They'd never even done that performance review, had they?

"I'll be there," Sheldon muttered.

All that night, Sheldon tried to put a positive spin on the situation. A job he'd enjoyed had been ruined by a terrible manager, it was true. But he'd soon be free to look for a better job and a better manager.

Sure enough, once the meeting began, Gene smugly informed Sheldon that his role was going offshore, making him redundant. (Sheldon later found out that the offshore bit was a lie, but you didn't hear it from us.) Sheldon hoped this would be the last of their interaction, but it wasn't to be.

Fast-forward to Sheldon's second-to-last day, 4:00 PM. Sheldon was leaving to pick up his kids from school. He was on a tight schedule, as he had a train to catch. He hurried to the lobby, summoned an elevator, and darted in.

Just as he turned around, he spied Gene entering the lobby from the stairwell. Gene saw Sheldon as well, and flashed him a big smile.

Not to be cowed, Sheldon smiled right back.

Gene frowned, confused. "Do you have a minute?"

"No," Sheldon answered honestly as the elevator doors began to close.

"I need to collect your badge!" Gene yelled.

The doors shut, and the elevator began its descent. You're a day early, Sheldon thought to himself, shaking his head.

He made it to his train and boarded just in time. While shuttling along, he grabbed his phone and sent Gene a quick message via Google Hangouts. I'll be in tomorrow. You can have my badge then.

The message seemed to have trouble going through. A few moments later, the Hangout closed. You have been successfully logged out.

Strange. Sheldon switched to Slack. You have successfully signed out.

"What?" Sheldon blurted aloud.

It got him thinking. Gene had just seen him leaving the building in a hurry, grinning like a fool. Did he think Sheldon had planted a bomb or something? Sheldon had no bombs, but he did have admin access to plenty of important systems. Had Gene gotten his account terminated in a panic?

Sheldon called the IT department and confirmed his suspicions. There was even a note attached to his account, from Gene: DO NOT RE-ENABLE.

"What am I supposed to do for my last day?" Sheldon asked.

"No worries," the tech replied. "I'll roll it back."

Upon returning the next day, Sheldon learned his security badge didn't work, either. The security guard at the front desk had to call Gene for authorization. Still too much of a wimp to show his face, Gene just told him to let Sheldon through.

"He couldn't even get my last day right," Sheldon said with a chuckle.

Gene kept his distance whole day. Sheldon left at 4:00 PM again, this time headed for the whiskey bar with a few ex-colleagues to celebrate freedom.

[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!

Read all

CodeSOD: The Generated JavaScript

Once upon a time, I discovered a bug in some JavaScript. I went off to investigate the source, only to find… the JS wasn’t coming from a file. It was being generated by a server-side method. Through string concatenation. It was a simple generation, something along the lines of:

jsCode += "location.href = 'foo?id=" + someIdField + "';n";

Bad, but a minor WTF- and the bug was caused because someIdField contained characters which needed to be escaped. It was actually unnecessary, and I could construct the logic completely on the client-side, which is what I ended up doing in that case.

I bring that tale up, because Konstantinos T has a special case of anguish.

<script>
function droppy(droppy_id, max_files) {
    var droppy = new Dropzone(dropzone_name, {
         //(...)
        init: function() {
            this.on('addedfile', function(file) {
                 //(...)
                var edit_button = '<?php ob_start();
                include(__DIR__.'/dropzone_edit_button_template.php');
                $include = ob_get_contents(); ob_end_clean(); echo str_replace(PHP_EOL, '', str_replace("'", '\'', str_replace('"', '"', str_replace("/", "/", str_replace('__script__','script',$include))))); ?>
                ';
                //(...)

Here, we see a client-side JS variable named edit_button. Stare at the variable initialization. What you see before you is a dank abyss, a gaping hole with a bottom so deep that the bottom may as well not exist. Here, we stand at a precipice.

The value of edit_button comes from PHP code, executed on the server-side. The actual template comes from an external PHP file, dropzone_edit_button_template.php. But that template, the result of all the other methods called here, returns a string that may not be safe for JavaScript, like my simple bug above. Thus, the chain of str_replace calls, nested one within the other.

[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!

Read all

Error'd: Never ASSume that You're Free from Errors

"This was in an email from Nest. I'm sure in some other font this shows a heartwarming image of fluffy bunnies frolicking in an energy saving Utopia, but instead, we get this," wrote Matthew W.

 

"Um...yeah, sure I guess?" writes Chris U.

 

Stuart L. wrote, "Looks like the weather has made an 8-bit turn for the worse."

 

"I had no idea that the success of entering my enrollment depended on whether or not my donkey was nearby," writes Ernie D.

 

Jamie S. writes, "What exactly are you trying to smuggle in, Fujitsu updater?"

 

"I'm the fastest man alive. Don't believe me? Check this out," writes John W.

 

[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.

Read all

CodeSOD: Delebation

When faced with an API or programming paradigm that requires repetitive, boilerplate code, a developer is left with two options. They may refine or adapt the API/paradigm, using the idioms of their language to make something tedious and verbose into something elegant and clear.

Or they just automate it. If you have a mile of boilerplate that’s mostly the same across the application, just generate that. It’s like copy/paste, but, y’know… automatic.

Which is why Derf Skren found this pile in their codebase:

  public abstract class ExchangeSingleData : IExchangeData
  {
    private readonly string mName;
    private readonly int mLength;

    private Dictionary<string, string> mMapValidData;
    private byte[] mBuffer;

    void AddValidValue(string name, string value) {
        mMapValidData[name] = value;
    }
    //...
    //...
  }

  public class NetChangeSign : ExchangeSingleData
  {
        public const string Plus = "+";
        public const string Minus = "-";

    public NetChangeSign()
      : base("NetChangeSign", 1)
    {
            AddValidValue("Plus", Plus);
            AddValidValue("Minus", Minus);
          }
  }

  public class BidPriceSign : ExchangeSingleData
  {
        public const string Plus = "+";
        public const string Minus = "-";

    public BidPriceSign()
      : base("BidPriceSign", 1)
    {
            AddValidValue("Plus", Plus);
            AddValidValue("Minus", Minus);
          }
  }

  public class AskPriceSign : ExchangeSingleData
  {
        public const string Plus = "+";
        public const string Minus = "-";

    public AskPriceSign()
      : base("AskPriceSign", 1)
    {
            AddValidValue("Plus", Plus);
            AddValidValue("Minus", Minus);
          }
  }

  // ... and 7 more versions of the same class

The goal of this code is so that they can prepend a “+” or a “-” to a transaction’s value. Note the mBuffer in the base class- they don’t use strings (or, y’know… numbers) to represent the transaction value, but a byte array instead. The “value” is that it lets them write a line like this:

lMessage.NetChangeSign.SetValue(GeneratePriceSign(lPrice));

Which allows the instance stored in NetChangeSign to flip that +/- based on the return value of GeneratePriceSign. Obviously, this lets the NetChangeSign instance have full control of the logic of how the sign gets set, right? I mean, each instance has its own map that contains all the allowed values, right? Well… sure, but how do they decide? Based on GeneratePriceSign… which looks like this:

  private static string GeneratePriceSign(Side aSide)
  {
    if (aSide.Equals(Side.Buy))
      return "+";
    else
      return "-";
  }

In design patterns terms, we call this “delebation”. It’s like delegation, but only one the person doing it to themselves enjoys it.

[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!

Read all

The For While Loop

Alex R. was the architect of a brand spanking new system that was to read inputs from numerous other internal systems, crunch a whole bunch of numbers, record everything in a database and spew forth a massive report file. He spent months designing the major details of the system, and more months designing the various sub-components. From all this came a variety of business-level data structures which spawned POJOs and the underlying DB tables to store assorted inputs, flags and outputs. He did a fairly thorough job of documenting all the interfaces, and provided detailed specifications for all of the next-level methods that were left as TBDs in the design.

Java Programming Cover

The project manager then assigned units of work to numerous offshored junior developers who managed to get virtually everything wrong. If they couldn't understand what a spec required, they changed the spec to reflect what they actually wrote. This caused Alex to start versioning the requirements document in order to catch the changes by the junior developers so that they could be rolled back.

After a while, the number of junior-developer-caused issues was piling up and Alex suggested some training sessions on certain ways of doing things to reduce the chaff he had to deal with. Management turned him down because they couldn't afford to take developers off of coding tasks for purposes of training; there was a schedule to keep! The fact that oodles of time were being wasted on them building the wrong stuff only to have to have why it was wrong explained and then have them go back and re-do it - sometimes 6 or 7 times - was irrelevant.

So how does one deal with idiotic management like this?

Alex thought that he had found a way to expose the problem and (hopefully) force something to be done. He would put in something (that any experienced developer should be able to spot as a simple code formatting issue) that the junior developers would never spot. The code would work correctly, but it would stymie them so that they had to first understand it before they could change it. He used the following coding style in a variety of locations throughout the codebase and waited:

  List<Widget> widgets;
  for (int i=0; i<limit; i++) {
      // Do stuff
  } while ((widgets = getWidgets()) == null);

For those not familiar with Java, the closing brace of a for-loop is followed by an implicit semicolon, so the while (expression); statement is unrelated to the for-loop. However, the junior developers didn't know this, and couldn't find any documentation on a for-while statement. Although they were able to create little test programs, they didn't understand how the while-expression controlled the for-loop (it doesn't). In this case, the underlying DAO either returned a populated list or threw an exception, so it was effectively while-false (the function call and assignment occurred once) and was just syntactic nonsense that confused the junior developers.

They couldn't recognize a Java 101 code format issue and they were sufficiently stubborn that they refused to simply ask Alex what the code was doing. They were even foolish enough to openly discuss it amongst themselves on a conference line - agreeing not to ask for help until they figured it out - before a meeting with Alex and his boss began.

After 6 weeks of them floundering around on it, the offshore manager finally brought the issue up with Alex and his boss, at which time Alex explained what running the code formatter would show. He then pointed out that since they didn't know the basics of reading Java code and preferred to waste massive amounts of time rather than just asking about something they didn't understand, it was clear that they didn't have the wherewithall to make technical decisions on a larger scale, or change the design documents as they saw fit.

He continued to point out that until the junior developers showed marked improvements in their understanding of simple code, they should concentrate on learning to do basic programming instead of trying to be architects. To this end, he again offered to have ongoing training sessions where he would attempt to raise their skill level.

Of course management backed the cheap offshore labor. It was at this point that Alex realized it was a lost cause, so he fixed all the for-while snippets and updated the latest version of the detailed design document with a new opening paragraph:

  To Whomever Inherits This System:

  Detailed design documents were created by experienced people. Management decreed
  that junior developers could ignore them, at will and without penalty. The state
  of the code reflects this.
  
  Fair Warning!

Then he committed it, secure in the knowledge that the junior developers would never bother to look at it again once he was gone. Then he gave two weeks notice.

[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!

Read all

CodeSOD: One's Company

The more you learn about something, the less confident you often become in making statements about it, because you understand the complexities of the matter. If, for example, I asked you to help me refine my definition of how dates and times work, you know that many assumptions are wrong. Or if we tried to define what makes a string a person’s name, we’ll run into similar problems. This is even true for a value we’ve all probably seen implemented as a boolean value: gender. The more you learn about these subjects, the more complex and nuanced your understanding of them becomes. More and more, your answers start with, “It’s complicated…”.

Eugene was going through some code at a customer’s site, and he found that their business logic depended heavily on a flag ISCOMPANY, but there was no ISCOMPANY field anywhere in the database. There was, however, a SEX field on the customer records, implemented as an integer.

Digging through the queries, Eugene found a new approach to defining a company:

SELECT …, CASE ISNULL(c.SEX, '')
    WHEN '6'
THEN '-1'
    WHEN '9'
THEN '-1'
    ELSE '0'
END AS ISCOMAPNY, …
FROM customers
WHERE …

Like I said, it's complicated.

[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!

Read all

Representative Line: An Exceptional Contract

The life of a contractor can be precarious. Contracts end- sometimes suddenly, and you rarely know what the organization you’re working for is actually like until it’s too late.

Ian S, for example, was contracting for a platform-as-a-service (PAAS) company, adding new features to their existing infrastructure automation system. It was the kind of place that had two copies of the same code-base, maintained side-by-side, just so that a single customer could use a script they’d written eight years prior.

That wasn’t too much of a challenge. The real challenge was that when things went wrong, there was almost no logging, and what little logging they got contained helpful, “[10:14:17] An error occurred” messages.

It wasn’t hard to see why that happened:

try {
    // Entry point to most of the program here
} catch (Exception e) {
    if ( e instanceof ProcessingException ) {
        throw new ProcessingException("An error occurred");
    } else if (e instanceof BatchException ) {
        throw new BatchException("An error occurred");
    } //… more types of exceptions
}

Ian describes this as “Pokemon Exception Handling”: you wrap the entire main method of your app in a single try, so you’re left with a single catch block that’s “gotta catch ’em all”. The use of instanceof is a nice touch, in the awfulness of it.

The developer responsible, John, was involved in a lot of important architectural decisions. For example, John decided “DevOps” and “Agile” meant that any code placed in the production branch needed to go to production, automatically. There were no checks around this, anyone with access to the main repo could merge-and-push.

“We enforce it by practice,” John explained. “We know that all of our developers, even the contractors, will follow the best practices.”

Late, on Friday afternoon, John was working on making some configuration file changes. Among other things, his changes caused the whole program to crash on startup- but not before messing up some rows in the database. That was no problem, he was working on a branch, and running against a local dev environment.

It what John claimed was a “simple mistake”, he merged that branch with master. Then he pushed to the central repo. “It could happen to anyone,” he said. At 4:59PM, on Friday, their entire PAAS configuration and management suite went down. Garbage data was thrown into the database, repeatedly, and since there was no exception handling, the only information they had was “An error occurred.”

Truly, the life of a contractor is perilous, and for management, this became a 4-alarm, hair-on-fire emergency. All hands on deck! Even the contractors!

There was just one problem. The PAAS company had decided that they weren’t going to renew the contract. They had gone further, and announced that with a day’s notice, which left a number of the contractors flapping in the wind, between gigs, Ian included. So at 5:00PM, when he officially didn’t work there anymore, he wished John the best and went home.

[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!

Read all