<?xml version="1.0" encoding="windows-1252"?>
<node id="990798" title="Input validation for built-in hex function" created="2012-08-30 13:04:02" updated="2012-08-30 13:04:02">
<type id="120">
perlmeditation</type>
<author id="622051">
toolic</author>
<data>
<field name="doctext">
&lt;p&gt;
I had a bug in my code which was a result of insufficient validation of a string passed to the built-in [doc://hex] function.

&lt;p&gt;
In my opinion, [doc://hex] is much too forgiving.  As shown in its
documentation, it allows for a string to have a leading &lt;c&gt;0x&lt;/c&gt;; for
example, it converts &lt;c&gt;0xC&lt;/c&gt; to &lt;c&gt;12&lt;/c&gt;.  Although &lt;c&gt;x&lt;/c&gt; is not
a legal hexadecimal character, it is customary to denote a hex value
with the &lt;c&gt;0xC&lt;/c&gt; prefix.  This is quite reasonable.

&lt;p&gt;
Although not mentioned in the documentation, it also allows for a string 
to have a leading &lt;c&gt;x&lt;/c&gt;; for example, it converts &lt;c&gt;xC&lt;/c&gt; to &lt;c&gt;12&lt;/c&gt;. 
I guess that's reasonable, too.

&lt;p&gt;
My problem occurred when I inadvertently passed a lone &lt;c&gt;x&lt;/c&gt; to 
[doc://hex].  The function returned 0.  Even with [doc://warnings] enabled, 
I did not get a warning message (perl v5.12.2, linux):

&lt;c&gt;
perl -w -E "say hex(q{x})"
0
&lt;/c&gt;

&lt;p&gt;
Passing it an illegal hex string like &lt;c&gt;t&lt;/c&gt; does generate a warning, as desired:

&lt;c&gt;
perl -w -E "say hex(q{t})"
Illegal hexadecimal digit 't' ignored at -e line 1.
0
&lt;/c&gt;

&lt;p&gt;I think passing a lone &lt;c&gt;x&lt;/c&gt; should generate a warning message (with [doc://warnings] enabled), but I'm not sure it's worth submitting a
[doc://perlbug] since I really need to do some checking before passing
a string to [doc://hex] anyway.

&lt;p&gt;Here is a wrapper function I decided to use.  It calls [doc://hex]
after performing some input validation:

&lt;c&gt;
sub hex2 {
    my $str = shift;
    $str =~ s/^(0x|x)//;
    if (length $str) {
        if ($str =~ /([^0-9a-f])/i) {
            die "hex2: Illegal hexadecimal digit found: '$1'";
        }
        else {
            return hex $str;
        }
    }
    else {
        die "hex2: No chars found after stripping leading 0x or x";
    }
}
&lt;/c&gt;


&lt;p&gt;
Another approach is to
[http://perldoc.perl.org/CORE.html#OVERRIDING-CORE-FUNCTIONS|override hex].

</field>
</data>
</node>
