More Perl Weak Typing Woes

I’ve written about Perl weak typing woes already, but that was almost two years ago now. With that blog post a slightly faded memory it only makes sense that a similar and just as subtle bug came up in some legacy code.

I’ll summarise with a small example system featuring a Perl script reading from a PHP page which returns either 1 or 0:

<?php
echo is_something_true() ? 1 : 0;

The Perl script then uses this:

my $ua  = Mojo::UserAgent->new;
my $res = $ua->get('http://example.com/script.php')->result;

if ($res->body) {
    // Do something
} else {
    // Do something else
}

Without taking a parenthetical excursion into the various issues with this code, ostensibly the setup works. If the PHP function is_something_true returns a true value then our Perl script will follow the if branch. If the function returns false, then our Perl script will follow the else branch.

How about if the PHP script was edited to include a closing PHP tag before the trailing new line at the end of the file?

<?php
echo is_something_true() ? 1 : 0;
+ ?>
+ \n

After applying this change, the Perl script no longer follows the else branch. In fact $res->body always evaluates to a truthy value even when the PHP script returns a “0”. The difference of course lies in the details, specifically the trailing whitespace in the response body meaning that perl interprets the value as truthy.

if ("0\n") {
    print 'Truthy';
} else {
    print 'Falsy';
}

Any variety of fixes can be applied here, refactoring the API to return a structured response being a favourite. Simply reverting the change to the PHP file also offers a fix for some definition of fix, at least the next person would have this blog post to refer to.

Fancy reading more? See more blog posts.