note 108037 added to function.session-decode

From: Date: Fri, 23 Mar 2012 17:24:16 +0000
Subject: note 108037 added to function.session-decode
Groups: php.notes 
Request: Send a blank email to php-notes+get-186794@lists.php.net to get a copy of this message
I noticed that the posted solutions for manually decoding sessions are not perfect, so I've contributed a more robust solution. The preg_match solution can never work. It's not so hard to find a case that might break unserialization. In the case of jason-joeymail is breaks on: <?php $_SESSION["test"] = ";oops|"; ?> Below you can find my solution. It doesn't use a regular expression but rather the reversibility of the serialize operation and the 'feature' that serialize ignores all further input when it thinks it's done. It's by no means a beautiful or particularly fast solution but it is a more robust solution. I've added a deserializer for "php" and "php_binary". It should be trivial to add one for "wddx". <?php class Session { public static function unserialize($session_data) { $method = ini_get("session.serialize_handler"); switch ($method) { case "php": return self::unserialize_php($session_data); break; case "php_binary": return self::unserialize_phpbinary($session_data); break; default: throw new Exception("Unsupported session.serialize_handler: " . $method . ". Supported: php, php_binary"); } } private static function unserialize_php($session_data) { $return_data = array(); $offset = 0; while ($offset < strlen($session_data)) { if (!strstr(substr($session_data, $offset), "|")) { throw new Exception("invalid data, remaining: " . substr($session_data, $offset)); } $pos = strpos($session_data, "|", $offset); $num = $pos - $offset; $varname = substr($session_data, $offset, $num); $offset += $num + 1; $data = unserialize(substr($session_data, $offset)); $return_data[$varname] = $data; $offset += strlen(serialize($data)); } return $return_data; } private static function unserialize_phpbinary($session_data) { $return_data = array(); $offset = 0; while ($offset < strlen($session_data)) { $num = ord($session_data[$offset]); $offset += 1; $varname = substr($session_data, $offset, $num); $offset += $num; $data = unserialize(substr($session_data, $offset)); $return_data[$varname] = $data; $offset += strlen(serialize($data)); } return $return_data; } } ?> Usage: <?php Session::unserialize(session_encode()); ?> ---- Server IP: 91.199.167.223 Probable Submitter: 194.171.50.61 ---- Manual Page -- http://www.php.net/manual/en/function.session-decode.php Edit -- https://master.php.net/note/edit/108037 Del: integrated -- https://master.php.net/note/delete/108037/integrated Del: useless -- https://master.php.net/note/delete/108037/useless Del: bad code -- https://master.php.net/note/delete/108037/bad+code Del: spam -- https://master.php.net/note/delete/108037/spam Del: non-english -- https://master.php.net/note/delete/108037/non-english Del: in docs -- https://master.php.net/note/delete/108037/in+docs Del: other reasons-- https://master.php.net/note/delete/108037 Reject -- https://master.php.net/note/reject/108037 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#186794) next »