Commit: c51f77fe83cea3a48d89423863e6916b77628e47 Author: Yasuo Ohgaki <yohg...@php.net> Wed, 21 Aug 2013 10:51:51 +0900 Parents: 7318b857aace976086e4fabde90b45facdcb15e7 Branches: PHP-5.5
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=c51f77fe83cea3a48d89423863e6916b77628e47 Log: Add php_serialize session.serialize_handler. This patch closes Request #25630 Request #43980 Request #54383 Bug #65359 and many others similar to these that are closed as "wont fix" or "not a bug". Current serializers have limitations due to register_globals support that are no longer supported. Changing existing serializer may cause compatibility issue. Therefore, new handler is needed to remove needless limitations. php_serialize does not have special characters and allow numerical index in $_SESSION. $_SESSION can be used as ordinary array. Bugs: https://bugs.php.net/25630 https://bugs.php.net/43980 https://bugs.php.net/54383 https://bugs.php.net/65359 Changed paths: M ext/session/session.c A ext/session/tests/session_decode_basic_serialize.phpt A ext/session/tests/session_encode_serialize.phpt Diff: diff --git a/ext/session/session.c b/ext/session/session.c index 7c6672d..1db2018 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -827,6 +827,51 @@ PHP_INI_END() /* *************** * Serializers * *************** */ +PS_SERIALIZER_ENCODE_FUNC(php_serialize) /* {{{ */ +{ + smart_str buf = {0}; + php_serialize_data_t var_hash; + HashTable *_ht = Z_ARRVAL_P(PS(http_session_vars)); + int key_type; + PS_ENCODE_VARS; + + PHP_VAR_SERIALIZE_INIT(var_hash); + php_var_serialize(&buf, &PS(http_session_vars), &var_hash TSRMLS_CC); + PHP_VAR_SERIALIZE_DESTROY(var_hash); + if (newlen) { + *newlen = buf.len; + } + smart_str_0(&buf); + *newstr = buf.c; + return SUCCESS; +} +/* }}} */ + +PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */ +{ + const char *p; + char *name; + const char *endptr = val + vallen; + zval *session_vars; + int namelen; + int has_value; + php_unserialize_data_t var_hash; + + PHP_VAR_UNSERIALIZE_INIT(var_hash); + ALLOC_INIT_ZVAL(session_vars); + php_var_unserialize(&session_vars, &val, endptr, &var_hash TSRMLS_CC); + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + if (PS(http_session_vars)) { + zval_ptr_dtor(&PS(http_session_vars)); + } + if (Z_TYPE_P(session_vars) == IS_NULL) { + array_init(session_vars); + } + PS(http_session_vars) = session_vars; + ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 2, 1); + return SUCCESS; +} +/* }}} */ #define PS_BIN_NR_OF_BITS 8 #define PS_BIN_UNDEF (1<<(PS_BIN_NR_OF_BITS-1)) @@ -1008,10 +1053,11 @@ break_outer_loop: } /* }}} */ -#define MAX_SERIALIZERS 10 -#define PREDEFINED_SERIALIZERS 2 +#define MAX_SERIALIZERS 32 +#define PREDEFINED_SERIALIZERS 3 static ps_serializer ps_serializers[MAX_SERIALIZERS + 1] = { + PS_SERIALIZER_ENTRY(php_serialize), PS_SERIALIZER_ENTRY(php), PS_SERIALIZER_ENTRY(php_binary) }; diff --git a/ext/session/tests/session_decode_basic_serialize.phpt b/ext/session/tests/session_decode_basic_serialize.phpt new file mode 100644 index 0000000..dd88438 --- /dev/null +++ b/ext/session/tests/session_decode_basic_serialize.phpt @@ -0,0 +1,274 @@ +--TEST-- +Test session_decode() function : basic functionality +--SKIPIF-- +<?php include('skipif.inc'); ?> +--FILE-- +<?php + +ob_start(); + +/* + * Prototype : string session_decode(void) + * Description : Decodes session data from a string + * Source code : ext/session/session.c + */ + +echo "*** Testing session_decode() : basic functionality ***\n"; + +// Get an unset variable +$unset_var = 10; +unset($unset_var); + +class classA +{ + public function __toString() { + return "Hello World!"; + } +} + +$heredoc = <<<EOT +Hello World! +EOT; + +$fp = fopen(__FILE__, "r"); + +// Unexpected values to be passed as arguments +$inputs = array( + + // Integer data +/*1*/ 0, + 1, + 12345, + -2345, + + // Float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // Null data +/*10*/ NULL, + null, + + // Boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // Empty strings +/*16*/ "", + '', + + // Invalid string data +/*18*/ "Nothing", + 'Nothing', + $heredoc, + + // Object data +/*21*/ new classA(), + + // Undefined data +/*22*/ @$undefined_var, + + // Unset data +/*23*/ @$unset_var, + + // Resource variable +/*24*/ $fp +); + +ini_set('session.serialize_handler', 'php_serialize'); +var_dump(session_start()); +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + $_SESSION["data"] = $input; + $encoded = session_encode(); + var_dump(session_decode($encoded)); + var_dump($_SESSION); + $iterator++; +}; + +var_dump(session_destroy()); +fclose($fp); +echo "Done"; +ob_end_flush(); +?> +--EXPECTF-- +*** Testing session_decode() : basic functionality *** +bool(true) + +-- Iteration 1 -- +bool(true) +array(1) { + ["data"]=> + int(0) +} + +-- Iteration 2 -- +bool(true) +array(1) { + ["data"]=> + int(1) +} + +-- Iteration 3 -- +bool(true) +array(1) { + ["data"]=> + int(12345) +} + +-- Iteration 4 -- +bool(true) +array(1) { + ["data"]=> + int(-2345) +} + +-- Iteration 5 -- +bool(true) +array(1) { + ["data"]=> + float(10.5) +} + +-- Iteration 6 -- +bool(true) +array(1) { + ["data"]=> + float(-10.5) +} + +-- Iteration 7 -- +bool(true) +array(1) { + ["data"]=> + float(123456789000) +} + +-- Iteration 8 -- +bool(true) +array(1) { + ["data"]=> + float(1.23456789E-9) +} + +-- Iteration 9 -- +bool(true) +array(1) { + ["data"]=> + float(0.5) +} + +-- Iteration 10 -- +bool(true) +array(1) { + ["data"]=> + NULL +} + +-- Iteration 11 -- +bool(true) +array(1) { + ["data"]=> + NULL +} + +-- Iteration 12 -- +bool(true) +array(1) { + ["data"]=> + bool(true) +} + +-- Iteration 13 -- +bool(true) +array(1) { + ["data"]=> + bool(false) +} + +-- Iteration 14 -- +bool(true) +array(1) { + ["data"]=> + bool(true) +} + +-- Iteration 15 -- +bool(true) +array(1) { + ["data"]=> + bool(false) +} + +-- Iteration 16 -- +bool(true) +array(1) { + ["data"]=> + string(0) "" +} + +-- Iteration 17 -- +bool(true) +array(1) { + ["data"]=> + string(0) "" +} + +-- Iteration 18 -- +bool(true) +array(1) { + ["data"]=> + string(7) "Nothing" +} + +-- Iteration 19 -- +bool(true) +array(1) { + ["data"]=> + string(7) "Nothing" +} + +-- Iteration 20 -- +bool(true) +array(1) { + ["data"]=> + string(12) "Hello World!" +} + +-- Iteration 21 -- +bool(true) +array(1) { + ["data"]=> + object(classA)#2 (0) { + } +} + +-- Iteration 22 -- +bool(true) +array(1) { + ["data"]=> + NULL +} + +-- Iteration 23 -- +bool(true) +array(1) { + ["data"]=> + NULL +} + +-- Iteration 24 -- +bool(true) +array(1) { + ["data"]=> + int(0) +} +bool(true) +Done + diff --git a/ext/session/tests/session_encode_serialize.phpt b/ext/session/tests/session_encode_serialize.phpt new file mode 100644 index 0000000..41c79c3 --- /dev/null +++ b/ext/session/tests/session_encode_serialize.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test session_encode() function : Numeric key raise error. bug65359 +--SKIPIF-- +<?php include('skipif.inc'); ?> +--FILE-- +<?php +ob_start(); + +ini_set('session.serialize_handler', 'php_serialize'); +var_dump(session_start()); +$_SESSION[-3] = 'foo'; +$_SESSION[3] = 'bar'; +$_SESSION['var'] = 123; +var_dump(session_encode()); +session_write_close(); + +// Should finish without errors +echo 'Done'.PHP_EOL; +?> +--EXPECTF-- +bool(true) +string(51) "a:3:{i:-3;s:3:"foo";i:3;s:3:"bar";s:3:"var";i:123;}" +Done + -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php