Not Comparing The Way You Meant

Here’s another example of code taken, terrifyingly, from a script that a contractor was paid cash money to write. The contractor’s code included a script to remote into another system and perform a command. Most systems required ssh, but we had some older systems that required rsh instead. So the contractor made a configuration file that contained client definitions:

  {
     "ferrari" : {
        "method": "ssh", "ipaddr": "10.26.101.92"
     },
     "yugo" : {
        "method": "rsh", "ipaddr": "10.25.34.112"
     }
  }

In the script, he looked up the client in question, and put its configuration into variables like $method. So far, so good. But here’s the code that decides which access method to use:

  if (method == "ssh") {
    do_ssh($ipaddr, $command);
  }
  else {
    do_rsh($ipaddr, $command);
  }

So this code omits the sigil on $method—problem #1—and thus treats method as a bareword (i.e. the literal string "method"), then compares that to the literal string "ssh", but does so NUMERICALLY—problem #2. Since both are non-numeric strings, they are both treated as 0, and the comparison is always true. Needless to say, this script did not turn on warnings or strict mode—problem #3. Luckily, the vast majority of our critical systems required ssh, and on those systems, three wrongs made a “right!”


3 Comments

You forgot to mention Problem #0 - this script cannot be using strict and warnings.

Ugh - never mind. Need more coffee.

Leave a comment

About morandimus

user-pic My real name is Jeremy Holland. I've been a programmer for 25 years, using primarily Perl since 2000.