Dilbert





The Daily WTF

Error'd: You Must Agree!;

"Apparently they don't want you to Strongly Agree with everything they say!" wrote David S.

 

"When updating some Logitech software recently, I learned that under the right conditions, you can update that which doesn't exist yet," wrote David N.

 

Eric P. writes, "I guess that’s what I get for requesting Ol’ Dirty Bastard from the jukebox at my local dive bar...which, ironically, was the only sign of any windows in the joint!"

 

"Maybe I really DO need the five minute overview!" Cindy H. wrote.

 

Marius E. writes, "Altough we did make it to Amsterdam in time I wonder how fast we were going?"

 

"I'm going to hibernate for the next couple thousand years so I don't have to wait so long," wrote Erwin.

 

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!


CodeSOD: An Ugly Mutation;

If there’s a hell for programmers, it probably involves C-style strings on some level. C’s approach to strings is rooted in arrays, and arrays are rooted in pointers, and now suddenly everything is memory manipulation, and incautious printf and memcpy commands cause buffer overruns. I'm oversimplifying and leaving out some of the better libraries that make this less painful, but the roots remain the same.

Fortunately, most of the time, we’re not working with that sort of string representation. If you’re using a high-level language, like Java, you get all sorts of perks, like abstract string methods, no concerns about null termination, and immutability by default.

In C, a string is just a pointer to a block of memory and you can do anything you like with it. In Java, a string is an object that can’t have its contents changed.

Cid has a co-worker that comes from a C background, and constantly equates “references” in Java to “pointers” in C, which is largely accurate, but highlights certain misunderstandings in this case.

Since, obviously, every non-primitive variable is holding an object reference, and it’s like pointers, and that means if you mutate the object in one place, it mutates everywhere. Much like a C-string, it’s just a pointer to memory and anybody can do anything.

That means, when this developer writes getters and setters for string properties, they want to make sure that nobody’s ever sharing a reference. That means thousands of lines of code like this:

public String getValue() {
  if (value == null) {
    return null;
  }
  else {
    return new String(value);
  }
}

public void setValue(String value) {
  if (value == null) {
    this.value = null;
  }
  else {
    if (value.trim().length == 0) {
      this.value = null;
    }
    else {
      this.value = new String(value);
      }
  }
}

Every string property gets that treatment, and there are a lot of string properties. It’s a great stress test for the garbage collector; there’s no reason to spin up extra instances of these immutable objects, but we do it anyway.

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!


CodeSOD: String Up Your Replacement;

Generating SQL statements is a necessary feature of many applications. String concatenation is the most obvious, and also the most wrong way to do this. Most APIs these days offer a way to construct SQL statements out of higher-level abstractions, whether we’re talking about .NET’s LINQ, or the QueryBuilder objects in many languages.

But let’s say you’re doing string concatenation. This means you need to have lots of literals in your code. And literal values, as we know, are bad. So we need to avoid these magic values by storing them in variables.

That, at least, seems to be the logic behind this code. Richard G just inherited this C# code from a senior engineer who left:

String SQLstr2;
String cDate = ("'Date'");
String c0 = ("'0'");
String c1 = ("'1'");
String c2 = ("'2'");
String c3 = ("'3'");
String c4 = ("'4'");
String c5 = ("'5'");
String c6 = ("'6'");
String c7 = ("'7'");
String c8 = ("'8'");
String c9 = ("'9'");
String c10 = ("'10'");
String c11 = ("'11'");
String c12 = ("'12'");
String c13 = ("'13'");
String c14 = ("'14'");
String c15 = ("'15'");
String c16 = ("'16'");
String c17 = ("'17'");
String c18 = ("'18'");
String c19 = ("'19'");
String c20 = ("'20'");
String c21 = ("'21'");
String c22 = ("'22'");
String c23 = ("'23'");

// more code

Double[] CancelShiftArray = new Double[24];
String sPGA;
String sDate;

// more code

SQLstr2 = "INSERT INTO TBL_OUTPUT_DAILY (PGA ," + (cDate.Replace("'", "\"")) + "," + (c0.Replace("'", "\"")) + "," +
(c1.Replace("'", "\"")) + "," + (c2.Replace("'", "\"")) + "," + (c3.Replace("'", "\"")) + "," + (c4.Replace("'", "\"")) + "," +
(c5.Replace("'", "\"")) + "," + (c6.Replace("'", "\"")) + "," + (c7.Replace("'", "\"")) + "," + (c8.Replace("'", "\"")) + "," +
(c9.Replace("'", "\"")) + "," + (c10.Replace("'", "\"")) + "," + (c11.Replace("'", "\"")) + "," + (c12.Replace("'", "\"")) + "," +
(c13.Replace("'", "\"")) + "," + (c14.Replace("'", "\"")) + "," + (c15.Replace("'", "\"")) + "," + (c16.Replace("'", "\"")) + "," +
(c17.Replace("'", "\"")) + "," + (c18.Replace("'", "\"")) + "," + (c19.Replace("'", "\"")) + "," + (c20.Replace("'", "\"")) + "," +
(c21.Replace("'", "\"")) + "," + (c22.Replace("'", "\"")) + "," + (c23.Replace("'", "\"")) +
") VALUES ('" + sPGA + "' , to_timestamp('" + sDate + "','dd-mm-yyyy') ,'" + CancelShiftArray[0] + "','" + CancelShiftArray[1] + "','" +
CancelShiftArray[2] + "','" + CancelShiftArray[3] + "','" + CancelShiftArray[4] + "','" + CancelShiftArray[5] + "','" +
CancelShiftArray[6] + "','" + CancelShiftArray[7] + "','" + CancelShiftArray[8] + "','" + CancelShiftArray[9] + "','" +
CancelShiftArray[10] + "','" + CancelShiftArray[11] + "','" + CancelShiftArray[12] + "','" + CancelShiftArray[13] + "','" +
CancelShiftArray[14] + "','" + CancelShiftArray[15] + "','" + CancelShiftArray[16] + "','" + CancelShiftArray[17] + "','" +
CancelShiftArray[18] + "','" + CancelShiftArray[19] + "','" + CancelShiftArray[20] + "','" + CancelShiftArray[21] + "','" +
CancelShiftArray[22] + "','" + CancelShiftArray[23] + "')";

Each one of the cN variables has single quotes in the string. When we use them, we escape the single quote into a double quote. Why not just put the double quote in the original? At a guess, they didn’t know how. They knew how to use Replace to escape them, because they found that code on Stack Overflow once, but didn’t understand how it worked. I think they also didn’t understand how for loops worked.

Or really, how a lot of things worked.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!


CodeSOD: Accidental Toast of the Town;

Don't you just love it when some part of your app just suddenly and magically STOPS working all of a sudden?

Our submitter David sure does (not). While working on his Android app, much to his surprise, he noticed that after one build, it wasn't displaying pop-up toast style notifications.

He was positively stymied. It's not like this functionality is weird and custom with black magic UI coding behind it. No, this is something basic and ancient that one would normally expect to just work. However, upon checking the function behind the notifications below, the reason became immediately clear. At some point, David had accidentally pasted a URL in the middle of the function.

public void showToast(final String msg) {
        // Show small piece of text at the bottom of screen
        runOnUiThread(new Runnable() {
            public void run() {
                CharSequence text = msg;
                int duration = Toast.LENGTH_LONG;
                Toast toast = Toast.makeText(con, text, duration);
                http://example.com/ toast.show();
                Log.d("toast", msg);
            }
        });
    }

Normally, one would expect that a mistake like this would have set off alarms at compilation time but in this case, it's actually valid. In Java, the "http:" acts as a labeled statement, which is logically similar to a "goto" statement in other languages, and the // which follows it commented out the rest of the line which contains the bit of code that actually shows the toast pop-up.

Thankfully this sort of misery only applies to Java...right?

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!


A Military Virus;

The virus threats we worried about in the late 90s are quite different than the one we're worrying about in 2020, because someone looked at word processors and said, "You know what that needs? That needs a full fledged programming language I can embed in documents."

Alex was a sailor for the US Navy, fresh out of boot, and working for the Defense Information School. The school taught sailors to be journalists, which meant really learning how to create press releases and other public affairs documents. The IT department was far from mature, and they had just deployed the latest version of Microsoft Word, which created the perfect breeding ground for macro viruses.

Alex wasn't in the IT department- not yet- and was actually learning to be a journalist. At the end of classes one day, he saved a bunch of Word documents to a shared computer. The next day, he came in and found they were all destroyed- as were everyone else's.

The chiefs in the school sent out stern warnings about viruses, and not running any unfamiliar executables. Lots of work was lost, but this was the late 90s: many of the documents got printed out for review anyway, so there were hard copies of much of the classwork. After a week, things were basically back to normal.

And then the virus hit again.

Cue another round of stern warnings, and NCOs chewing out anybody who even looked at the computers wrong, or thought about running an unauthorized executable. One Seaman got caught with a floppy containing WOLF3D.EXE, and while no one in the barracks knew exactly what happened to him, everyone agreed it must have been pretty dire.

After the third time, Alex decided to offer his services. He wasn't an IT professional, but he was pretty technical. Maybe he could take a look?

Chief Donaldson thought it over for a few moments. "Well, kid, it's already jacked up. You probably can't make it any worse. Take a look."

Anti-virus protection was provided by Norton. It had been configured to use a whitelist to decide which files to scan. That whitelist didn't include *.doc files. Alex made that fix on his computer, and showed Chief Donaldson what he'd done.

The IT department was notified, but had no interest in listening to some kid fresh out of boot camp. They'd been in the service for years, so there was no need for them to change their policies or procedures.

Alex shared his knowledge with his peers. It quickly percolated out through the Navy barracks at the Defense Information School, and without the IT department doing anything, very quickly nearly all of the computers the Navy used were protected against macro viruses. The same couldn't be said about the other branches of military service, which each had their own barracks at the Defense Information School.

Still, the virus activity was severely curtailed. For months, nobody thought about anything, and the IT department patted themselves on the back for making a really good show of stopping the virus. And then came the "field trip": the budding military journalists would go to another military base to participate in a war game, simulating a "real world" scenario which would let them hone their journalistic skills under fire.

There was one problem. The only computers that had been configured to defend against macro viruses were the ones Alex and his peers had personally protected. Those were back at the Defense Information School Navy barracks. Here, they were using computers that were tagged for field deployments.

This meant they were about 15 minutes into the wargame when a Word virus started forwarding itself through every newsroom computer on the simulated battlefield. Since this was a number of branches at the same time, it was an even more varied collection: some raced to delete files, others opened as many porn sites as they possibly could, and yet others simply played an animation claiming that they were formatting your hard drive (they weren't).

You might think that makes this more of an IT education than a journalistic experience. Certainly, Alex eventually moved on to become an IT professional in the civilian sector. But there was a very valuable lesson on military journalism to be had, in the form of the after action report on the exercise. It managed to bury the entire IT disaster with a brief blurb: "Computer viruses and malfunctions were not part of the exercise parameters. These should be part of the plan for future exercises."

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


Error'd: Let's Dazzle Them with Errors!;

"Hmmm...Somehow, I can't seem to remember the password for this particular AppleID," writes Thomas G.

 

"The video will be finised processing in roughly 585 million years. (That's later than the lifetime of some of the stars in the Orion constellation)," David K. wrote.

 

Brian A. writes, "AWS Canary only speaks English, huh? Sure about that?"

 

"Every now and then, I change the language of my computer and here is an example of the result," wrote Beatrix W., "Not only does Apple mix German with English but the translations for the languages get confused too."

 

Bryan writes, "Apparently, you can be fooled again and again by the wrong lyrics for this popular song from The Who."

 

"When it comes down to it, captchas aren't about proving that you're a human, but rather proving that you're able to think like a computer. If you give the computer what it expects, then you've passed! (Image: verified!)" Daniel S. wrote.

 

[Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!


CodeSOD: Deep VB;

Thomas had an application which was timing out. The code which he sent us has nothing to do with why it was timing out, but it provides a nice illustration of why timeouts and other bugs are a common “feature” of the application.

The codebase contains 9000+ line classes, functions with hundreds of lines, and no concept of separation of function. So, when someone needed to look at an account number and decide if that account needs special handling, this is what they did:

       For i As Integer = 0 To R - 1
            If DataSet.Tables(0).Rows(i)("Code") = Code Then
                If Not IsDBNull(DataSet.Tables(0).Rows(i)("Estimate")) Then
                    If DataSet.Tables(0).Rows(i)("Estimate") <> "E" Then
                        If Not (IsDBNull(DataSet.Tables(0).Rows(i)("Code2"))) Then
                            If Not (DataSet.Tables(0).Rows(i)("Code2").contains("XX")) Then      'does not perform the test on XX accounts
                                If Not (DataSet.Tables(0).Rows(i)("Code2").contains("YYY")) Then
                                    If Not (DataSet.Tables(0).Rows(i)("Code2") = "ZZZZZZ") Then
                                        If Not (DataSet.Tables(0).Rows(i)("Code2").contains("ZZZ")) Then
                                            If (Not (DataSet.Tables(0).Rows(i)("Code2").Contains("CC"))) Or (Not (DataSet.Tables(0).Rows(i)("Code2").Contains("cc"))) Then
                                                If Not (DataSet.Tables(0).Rows(i)("Code2") = "AAAAAA") Then
                                                    If Not (DataSet.Tables(0).Rows(i)("Code2").StartsWith("BB")) Then
                                                        If Not (DataSet.Tables(0).Rows(i)("Code2").Contains("BBBB")) Then
                                                            If Not (IsDBNull(DataSet.Tables(0).Rows(i)("Location"))) Then
                                                                Dim tempLocation As String = DataSet.Tables(0).Rows(i)("Location")
                                                                If Not (tempLocation.Contains("XX")) Then      'does not perform the test on XX accounts
                                                                    If Not (tempLocation.Contains("YYY")) Then
                                                                        If Not (tempLocation = "ZZZZZZ") Then
                                                                            If Not (DataSet.Tables(0).Rows(i)("Location").contains("ZZZ")) Then
                                                                                If tempLocation = "CCCCCC" Or tempLocation = "CCCCCC" Then
                                                                                    GoTo Skip
                                                                                Else
                                                                                    If Not (DataSet.Tables(0).Rows(i)("Location") = "AAAAAA") Then
                                                                                        If Not (DataSet.Tables(0).Rows(i)("Location").StartsWith("BB")) Then
                                                                                            If Not (DataSet.Tables(0).Rows(i)("Location").Contains("BBBB")) Then
                                                                                                If DataSet.Tables(0).Rows(i)("Date") > LastMonth Then

                                                                                                    LastMonth = DataSet.Tables(0).Rows(i)("Date")
                                                                                                    If Not IsDBNull(DataSet.Tables(0).Rows(i)("Present")) Then
                                                                                                        LastReading = DataSet.Tables(0).Rows(i)("Present")
                                                                                                    Else
                                                                                                        LastReading = 0
                                                                                                    End If


                                                                                                End If
                                                                                            End If
                                                                                        End If
                                                                                    End If
                                                                                End If
                                                                            End If
                                                                        End If
                                                                    End If
                                                                End If
                                                            End If
                                                        End If
                                                    End If
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
skip:
        Next

I don’t know what this code does. I don’t really want to. It’s a stack of if statements so deep that it provides a habitat for monothalameans.

The real treat, though, is that hidden goto, which sort circuits the loop. Thomas didn’t know that labels, in VB.Net, were scoped to functions, so you can re-use the same label, skip as often as you like, and don’t worry, the developer who wrote this did. skip:s all over the place.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!