Why do I have problems using the Perl CGI.pm escape() function with binary data?

Our servers support the CGI.pm Perl module.

However, the CGI::escape() function has a bug that will cause problems if you're a Perl programmer and you try to escape() binary data. For example, the following script will not work on our servers, even though it may look like it should:

#!/usr/bin/perl

use strict;
use warnings;
use CGI;

my $binary_data = "\xff\x20";
my $escaped = CGI::escape($binary_data);
my $unescaped = CGI::unescape($escaped);

if ($binary_data eq $unescaped)
{
  print "Success.\n";
}
else
{
  print "Failure.\n";
}

This problem is caused by a bug in CGI.pm.

In general, you probably shouldn't rely on escaping raw binary data; it's better to convert it to Base64 first. This works, for example:

#!/usr/bin/perl

use strict;
use warnings;
use CGI;
use MIME::Base64;

my $binary_data = "\xff\x20";
my $escaped = CGI::escape(encode_base64 $binary_data);
my $unescaped = decode_base64 CGI::unescape($escaped);

if ($binary_data eq $unescaped)
{
  print "Success.\n";
}
else
{
  print "Failure.\n";
}

This bug will eventually be fixed when Debian Linux releases a newer version of Perl (and we upgrade to that version).