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

Reply via email to