php pack(“H*, $s) does not throw exception or return false on error. SOLVED.

I was puzzled by this recently, code that uses pack(“H*”, $s) to compress a token into a few bytes would cause a warning to be displayed by php if the $s token was not a valid hexadecimal string, but still return a bogus result.  try { $p = pack(“H*”, $s); } catch (Exception $e) { } would not catch it, as it is emitted as a warning, not an error.

The warning looks like this:

pack(): Type H: illegal hex digit s in /my/fancy/webapp/problem.php on line 123

After a bunch of unsuccessful googling somebody from effnet reminded me to look up error handling specifics, but  all I  found was how to create error handlers that could catch that sort of thing. But I don’t want to introduce an error handler just yet, instead I am trying to find a simple way to detect failure of the function pack(), i.e. a way to query the error status, so I started experimenting with error_get_last() and came up with the following:

  1. <?php
  2.         function attemptpack($s) {
  3.                 @trigger_error(“”);
  4.                 $p=pack(“H*”, $s);
  5.                 $e = error_get_last();
  6.                 if ($e && !(strpos($e[“message”], “pack()”) === FALSE)) {
  7.                         print(“$s pack error detected:” . $e[“message”] . “\n”);
  8.                 }  else {
  9.                         print “$s packed ok\n”;
  10.                 }
  11.         }
  12.         attemptpack(“abcdef”);
  13.         attemptpack(“axbcdef”);
  14.         attemptpack(“abcdef”);
  15. ?>

Note I am paranoid and am verifying that the message contains pack() in case an older message was not cleared by @trigger. It should not be necessary at this point.

Turns out that does not work on php 5.1.6. And the more obvious way to do this is to validate the input anyways. So now my approach is now much more simple:

  1. <?php
  2. function attemptpack($s) {
  3.     if ( !ctype_xdigit($s))  {
  4.         print __FILE__ . “: $s is not a valid hex string.\n”;
  5.     } else {
  6.         $p=pack(“H*”, $s);
  7.     }
  8. }
  9. attemptpack(“abcdef”);
  10. attemptpack(“abxdef”);
  11. ?>
Advertisements

~ by MrMichaelWill on July 18, 2012.

One Response to “php pack(“H*, $s) does not throw exception or return false on error. SOLVED.”

  1. Thanks. I realize this is a WAY OLD post, but I just found and implemented this into my code, its been a problem for a while. I use RC4 encryption to pass url parameters, then decrypt them on the other end, and if a spam bot hit the site, and tried to hack the parameters it would flood the logs with errors.

    Well done!
    -Jon

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: