From c51f77fe83cea3a48d89423863e6916b77628e47 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Wed, 21 Aug 2013 10:51:51 +0900 Subject: [PATCH] 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. --- ext/session/session.c | 50 +++- .../tests/session_decode_basic_serialize.phpt | 274 ++++++++++++++++++ .../tests/session_encode_serialize.phpt | 24 ++ 3 files changed, 346 insertions(+), 2 deletions(-) create mode 100644 ext/session/tests/session_decode_basic_serialize.phpt create mode 100644 ext/session/tests/session_encode_serialize.phpt diff --git a/ext/session/session.c b/ext/session/session.c index 7c6672de52..1db20185f0 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 0000000000..dd88438e15 --- /dev/null +++ b/ext/session/tests/session_decode_basic_serialize.phpt @@ -0,0 +1,274 @@ +--TEST-- +Test session_decode() function : basic functionality +--SKIPIF-- + +--FILE-- + +--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 0000000000..41c79c3e51 --- /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-- + +--FILE-- + +--EXPECTF-- +bool(true) +string(51) "a:3:{i:-3;s:3:"foo";i:3;s:3:"bar";s:3:"var";i:123;}" +Done + -- 2.50.1