]> granicus.if.org Git - php/commitdiff
Adding more tests for serialize() and unserialize().
authorRobin Fernandes <robinf@php.net>
Tue, 18 Mar 2008 15:11:48 +0000 (15:11 +0000)
committerRobin Fernandes <robinf@php.net>
Tue, 18 Mar 2008 15:11:48 +0000 (15:11 +0000)
26 files changed:
ext/standard/tests/serialize/005.phpt
ext/standard/tests/serialize/serialization_arrays_001.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_arrays_002.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_arrays_003.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_arrays_004.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_arrays_005.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_error_001.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_miscTypes_001.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_001.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_002.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_003.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_004.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_005.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_006.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_007.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_008.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_009.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_010.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_011.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_012.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_013.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_014.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_objects_015.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_precision_001.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_precision_002.phpt [new file with mode: 0644]
ext/standard/tests/serialize/serialization_resources_001.phpt [new file with mode: 0644]

index d67f6fbf702621b27e9d4064a43b6175871d6687..e7b23db7016cc87f47c8b02528e7af9fd92b7066 100755 (executable)
@@ -179,7 +179,7 @@ do_autoload(autoload_not_available)
 do_autoload(autoload_not_available)
 
 Warning: unserialize(): Function unserializer() hasn't defined the class it was called for in %s005.php on line %d
-object(__PHP_Incomplete_Class)#1 (1) {
+object(__PHP_Incomplete_Class)#%d (1) {
   ["__PHP_Incomplete_Class_Name"]=>
   string(22) "autoload_not_available"
 }
diff --git a/ext/standard/tests/serialize/serialization_arrays_001.phpt b/ext/standard/tests/serialize/serialization_arrays_001.phpt
new file mode 100644 (file)
index 0000000..f62f698
--- /dev/null
@@ -0,0 +1,106 @@
+--TEST--
+Test serialize() & unserialize() functions: arrays (circular references)
+--FILE--
+<?php 
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+echo "\n--- Testing Circular reference of an array ---\n";
+
+echo "-- Normal array --\n";
+$arr_circ = array(0, 1, -2, 3.333333, "a", array(), &$arr_circ);
+$serialize_data = serialize($arr_circ);
+var_dump( $serialize_data );
+$arr_circ = unserialize($serialize_data);
+var_dump( $arr_circ );
+
+echo "\n-- Associative array --\n";
+$arr_asso = array("a" => "test");
+$arr_asso[ "b" ] = &$arr_asso[ "a" ];
+var_dump($arr_asso);
+$serialize_data = serialize($arr_asso);
+var_dump($serialize_data);
+$arr_asso = unserialize($serialize_data);
+var_dump($arr_asso);
+
+echo "\nDone";
+?>
+--EXPECTF--
+
+--- Testing Circular reference of an array ---
+-- Normal array --
+string(238) "a:7:{i:0;i:0;i:1;i:1;i:2;i:-2;i:3;d:3.333333000000000101437080957111902534961700439453125;i:4;s:1:"a";i:5;a:0:{}i:6;a:7:{i:0;i:0;i:1;i:1;i:2;i:-2;i:3;d:3.333333000000000101437080957111902534961700439453125;i:4;s:1:"a";i:5;a:0:{}i:6;R:8;}}"
+array(7) {
+  [0]=>
+  int(0)
+  [1]=>
+  int(1)
+  [2]=>
+  int(-2)
+  [3]=>
+  float(3.333333)
+  [4]=>
+  string(1) "a"
+  [5]=>
+  array(0) {
+  }
+  [6]=>
+  &array(7) {
+    [0]=>
+    int(0)
+    [1]=>
+    int(1)
+    [2]=>
+    int(-2)
+    [3]=>
+    float(3.333333)
+    [4]=>
+    string(1) "a"
+    [5]=>
+    array(0) {
+    }
+    [6]=>
+    &array(7) {
+      [0]=>
+      int(0)
+      [1]=>
+      int(1)
+      [2]=>
+      int(-2)
+      [3]=>
+      float(3.333333)
+      [4]=>
+      string(1) "a"
+      [5]=>
+      array(0) {
+      }
+      [6]=>
+      *RECURSION*
+    }
+  }
+}
+
+-- Associative array --
+array(2) {
+  ["a"]=>
+  &string(4) "test"
+  ["b"]=>
+  &string(4) "test"
+}
+string(37) "a:2:{s:1:"a";s:4:"test";s:1:"b";R:2;}"
+array(2) {
+  ["a"]=>
+  &string(4) "test"
+  ["b"]=>
+  &string(4) "test"
+}
+
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_arrays_002.phpt b/ext/standard/tests/serialize/serialization_arrays_002.phpt
new file mode 100644 (file)
index 0000000..f8cef78
--- /dev/null
@@ -0,0 +1,544 @@
+--TEST--
+serialization: arrays with references amonst elements
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+function check(&$a) {
+       var_dump($a);
+       $ser = serialize($a);
+       var_dump($ser);
+       
+       $b = unserialize($ser);
+       var_dump($b);
+       $b[0] = "b0.changed";
+       var_dump($b);
+       $b[1] = "b1.changed";
+       var_dump($b);
+       $b[2] = "b2.changed";
+       var_dump($b);   
+}
+
+echo "\n\n--- No references:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 0 refs 1:\n";
+$a = array();
+$a[0] = &$a[1];
+$a[1] = 1;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 0 refs 2:\n";
+$a = array();
+$a[0] = &$a[2];
+$a[1] = 1;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1 refs 0:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = &$a[0];
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1 refs 2:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = &$a[2];
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 2 refs 0:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$a[2] = &$a[0];
+check($a);
+
+echo "\n\n--- 2 refs 1:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$a[2] = &$a[1];
+check($a);
+
+echo "\n\n--- 0,1 ref 2:\n";
+$a = array();
+$a[0] = &$a[2];
+$a[1] = &$a[2];
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 0,2 ref 1:\n";
+$a = array();
+$a[0] = &$a[1];
+$a[1] = 1;
+$a[2] = &$a[1];
+check($a);
+
+echo "\n\n--- 1,2 ref 0:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = &$a[0];
+$a[2] = &$a[0];
+check($a);
+
+echo "Done";
+?>
+--EXPECTF--
+
+
+--- No references:
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;i:1;}"
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  string(10) "b2.changed"
+}
+
+
+--- 0 refs 1:
+array(3) {
+  [1]=>
+  &int(1)
+  [0]=>
+  &int(1)
+  [2]=>
+  int(1)
+}
+string(30) "a:3:{i:1;i:1;i:0;R:2;i:2;i:1;}"
+array(3) {
+  [1]=>
+  &int(1)
+  [0]=>
+  &int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [1]=>
+  &string(10) "b0.changed"
+  [0]=>
+  &string(10) "b0.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [1]=>
+  &string(10) "b1.changed"
+  [0]=>
+  &string(10) "b1.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [1]=>
+  &string(10) "b1.changed"
+  [0]=>
+  &string(10) "b1.changed"
+  [2]=>
+  string(10) "b2.changed"
+}
+
+
+--- 0 refs 2:
+array(3) {
+  [2]=>
+  &int(1)
+  [0]=>
+  &int(1)
+  [1]=>
+  int(1)
+}
+string(30) "a:3:{i:2;i:1;i:0;R:2;i:1;i:1;}"
+array(3) {
+  [2]=>
+  &int(1)
+  [0]=>
+  &int(1)
+  [1]=>
+  int(1)
+}
+array(3) {
+  [2]=>
+  &string(10) "b0.changed"
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  int(1)
+}
+array(3) {
+  [2]=>
+  &string(10) "b0.changed"
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+}
+array(3) {
+  [2]=>
+  &string(10) "b2.changed"
+  [0]=>
+  &string(10) "b2.changed"
+  [1]=>
+  string(10) "b1.changed"
+}
+
+
+--- 1 refs 0:
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;R:2;i:2;i:1;}"
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &string(10) "b0.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  string(10) "b2.changed"
+}
+
+
+--- 1 refs 2:
+array(3) {
+  [0]=>
+  int(1)
+  [2]=>
+  &int(1)
+  [1]=>
+  &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:2;i:1;i:1;R:3;}"
+array(3) {
+  [0]=>
+  int(1)
+  [2]=>
+  &int(1)
+  [1]=>
+  &int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [2]=>
+  &int(1)
+  [1]=>
+  &int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [2]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [2]=>
+  &string(10) "b2.changed"
+  [1]=>
+  &string(10) "b2.changed"
+}
+
+
+--- 2 refs 0:
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;R:2;}"
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  &int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  int(1)
+  [2]=>
+  &string(10) "b0.changed"
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  &string(10) "b0.changed"
+}
+array(3) {
+  [0]=>
+  &string(10) "b2.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  &string(10) "b2.changed"
+}
+
+
+--- 2 refs 1:
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;R:3;}"
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  &int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  &int(1)
+  [2]=>
+  &int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  &string(10) "b1.changed"
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  &string(10) "b2.changed"
+  [2]=>
+  &string(10) "b2.changed"
+}
+
+
+--- 0,1 ref 2:
+array(3) {
+  [2]=>
+  &int(1)
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+}
+string(30) "a:3:{i:2;i:1;i:0;R:2;i:1;R:2;}"
+array(3) {
+  [2]=>
+  &int(1)
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+}
+array(3) {
+  [2]=>
+  &string(10) "b0.changed"
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &string(10) "b0.changed"
+}
+array(3) {
+  [2]=>
+  &string(10) "b1.changed"
+  [0]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+}
+array(3) {
+  [2]=>
+  &string(10) "b2.changed"
+  [0]=>
+  &string(10) "b2.changed"
+  [1]=>
+  &string(10) "b2.changed"
+}
+
+
+--- 0,2 ref 1:
+array(3) {
+  [1]=>
+  &int(1)
+  [0]=>
+  &int(1)
+  [2]=>
+  &int(1)
+}
+string(30) "a:3:{i:1;i:1;i:0;R:2;i:2;R:2;}"
+array(3) {
+  [1]=>
+  &int(1)
+  [0]=>
+  &int(1)
+  [2]=>
+  &int(1)
+}
+array(3) {
+  [1]=>
+  &string(10) "b0.changed"
+  [0]=>
+  &string(10) "b0.changed"
+  [2]=>
+  &string(10) "b0.changed"
+}
+array(3) {
+  [1]=>
+  &string(10) "b1.changed"
+  [0]=>
+  &string(10) "b1.changed"
+  [2]=>
+  &string(10) "b1.changed"
+}
+array(3) {
+  [1]=>
+  &string(10) "b2.changed"
+  [0]=>
+  &string(10) "b2.changed"
+  [2]=>
+  &string(10) "b2.changed"
+}
+
+
+--- 1,2 ref 0:
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;R:2;i:2;R:2;}"
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  &int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &string(10) "b0.changed"
+  [2]=>
+  &string(10) "b0.changed"
+}
+array(3) {
+  [0]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  &string(10) "b1.changed"
+}
+array(3) {
+  [0]=>
+  &string(10) "b2.changed"
+  [1]=>
+  &string(10) "b2.changed"
+  [2]=>
+  &string(10) "b2.changed"
+}
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_arrays_003.phpt b/ext/standard/tests/serialize/serialization_arrays_003.phpt
new file mode 100644 (file)
index 0000000..8d664fc
--- /dev/null
@@ -0,0 +1,294 @@
+--TEST--
+serialization: arrays with references to an external variable
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+function check(&$a) {
+       var_dump($a);
+       $ser = serialize($a);
+       var_dump($ser);
+       
+       $b = unserialize($ser);
+       var_dump($b);
+       $b[0] = "b0.changed";
+       var_dump($b);
+       $b[1] = "b1.changed";
+       var_dump($b);
+       $b[2] = "b2.changed";
+       var_dump($b);   
+}
+
+echo "\n\n--- 0 refs external:\n";
+$ext = 1;
+$a = array();
+$a[0] = &$ext;
+$a[1] = 1;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1 refs external:\n";
+$ext = 1;
+$a = array();
+$a[0] = 1;
+$a[1] = &$ext;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 2 refs external:\n";
+$ext = 1;
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$a[2] = &$ext;
+check($a);
+
+echo "\n\n--- 1,2 ref external:\n";
+$ext = 1;
+$a = array();
+$a[0] = &$ext;
+$a[1] = &$ext;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1,2,3 ref external:\n";
+$ext = 1;
+$a = array();
+$a[0] = &$ext;
+$a[1] = &$ext;
+$a[2] = &$ext;
+check($a);
+
+echo "Done";
+?>
+--EXPECTF--
+
+
+--- 0 refs external:
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;i:1;}"
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  string(10) "b2.changed"
+}
+
+
+--- 1 refs external:
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;i:1;}"
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  string(10) "b2.changed"
+}
+
+
+--- 2 refs external:
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;i:1;}"
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  string(10) "b2.changed"
+}
+
+
+--- 1,2 ref external:
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;R:2;i:2;i:1;}"
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &string(10) "b0.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  string(10) "b2.changed"
+}
+
+
+--- 1,2,3 ref external:
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;R:2;i:2;R:2;}"
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  &int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &string(10) "b0.changed"
+  [2]=>
+  &string(10) "b0.changed"
+}
+array(3) {
+  [0]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  &string(10) "b1.changed"
+}
+array(3) {
+  [0]=>
+  &string(10) "b2.changed"
+  [1]=>
+  &string(10) "b2.changed"
+  [2]=>
+  &string(10) "b2.changed"
+}
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_arrays_004.phpt b/ext/standard/tests/serialize/serialization_arrays_004.phpt
new file mode 100644 (file)
index 0000000..942afdf
--- /dev/null
@@ -0,0 +1,467 @@
+--TEST--
+serialization: arrays with references to the containing array
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+function check(&$a) {
+       var_dump($a);
+       $ser = serialize($a);
+       var_dump($ser);
+       
+       $b = unserialize($ser);
+       var_dump($b);
+       $b[0] = "b0.changed";
+       var_dump($b);
+       $b[1] = "b1.changed";
+       var_dump($b);
+       $b[2] = "b2.changed";
+       var_dump($b);   
+}
+
+echo "\n\n--- 1 refs container:\n";
+$a = array();
+$a[0] = &$a;
+$a[1] = 1;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1,2 ref container:\n";
+$a = array();
+$a[0] = &$a;
+$a[1] = &$a;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1,2,3 ref container:\n";
+$a = array();
+$a[0] = &$a;
+$a[1] = &$a;
+$a[2] = &$a;
+check($a);
+
+echo "Done";
+?>
+--EXPECTF--
+
+
+--- 1 refs container:
+array(3) {
+  [0]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      int(1)
+      [2]=>
+      int(1)
+    }
+    [1]=>
+    int(1)
+    [2]=>
+    int(1)
+  }
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+string(56) "a:3:{i:0;a:3:{i:0;R:2;i:1;i:1;i:2;i:1;}i:1;i:1;i:2;i:1;}"
+array(3) {
+  [0]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      int(1)
+      [2]=>
+      int(1)
+    }
+    [1]=>
+    int(1)
+    [2]=>
+    int(1)
+  }
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  %string(10) "b0.changed"
+  [1]=>
+  int(1)
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  %string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  %string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  string(10) "b2.changed"
+}
+
+
+--- 1,2 ref container:
+array(3) {
+  [0]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      int(1)
+    }
+    [1]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      int(1)
+    }
+    [2]=>
+    int(1)
+  }
+  [1]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      int(1)
+    }
+    [1]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      int(1)
+    }
+    [2]=>
+    int(1)
+  }
+  [2]=>
+  int(1)
+}
+string(56) "a:3:{i:0;a:3:{i:0;R:2;i:1;R:2;i:2;i:1;}i:1;R:2;i:2;i:1;}"
+array(3) {
+  [0]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      int(1)
+    }
+    [1]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      int(1)
+    }
+    [2]=>
+    int(1)
+  }
+  [1]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      int(1)
+    }
+    [1]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      int(1)
+    }
+    [2]=>
+    int(1)
+  }
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &string(10) "b0.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  string(10) "b2.changed"
+}
+
+
+--- 1,2,3 ref container:
+array(3) {
+  [0]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [1]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+  [1]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [1]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+  [2]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [1]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+}
+string(56) "a:3:{i:0;a:3:{i:0;R:2;i:1;R:2;i:2;R:2;}i:1;R:2;i:2;R:2;}"
+array(3) {
+  [0]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [1]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+  [1]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [1]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+  [2]=>
+  &array(3) {
+    [0]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [1]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      *RECURSION*
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &string(10) "b0.changed"
+  [2]=>
+  &string(10) "b0.changed"
+}
+array(3) {
+  [0]=>
+  &string(10) "b1.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  &string(10) "b1.changed"
+}
+array(3) {
+  [0]=>
+  &string(10) "b2.changed"
+  [1]=>
+  &string(10) "b2.changed"
+  [2]=>
+  &string(10) "b2.changed"
+}
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_arrays_005.phpt b/ext/standard/tests/serialize/serialization_arrays_005.phpt
new file mode 100644 (file)
index 0000000..dd3e436
--- /dev/null
@@ -0,0 +1,571 @@
+--TEST--
+serialization: arrays with references, nested
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+function check(&$a) {
+       var_dump($a);
+       $ser = serialize($a);
+       var_dump($ser);
+       
+       $b = unserialize($ser);
+       
+       // Change each element and dump result. 
+       foreach($b as $k=>$v) {
+               if (is_array($v)){
+                       foreach($b[$k] as $sk=>$sv) {
+                               $b[$k][$sk] = "b$k.$sk.changed";
+                               var_dump($b);
+                       }
+               } else {
+                       $b[$k] = "b$k.changed";
+                       var_dump($b);
+               }
+       }
+}
+
+echo "\n\n--- Nested array references 1 element in containing array:\n";
+$a = array();
+$c = array(1,1,&$a);
+$a[0] = &$c[0];
+$a[1] = 1;
+check($c);
+
+echo "\n\n--- Nested array references 1 element in containing array (slightly different):\n";
+$a = array();
+$c = array(1,&$a,1);
+$a[0] = 1;
+$a[1] = &$c[0];
+check($c);
+
+echo "\n\n--- Nested array references 2 elements in containing array:\n";
+$a = array();
+$c = array(1,1,&$a);
+$a[0] = &$c[0];
+$a[1] = &$c[1];
+check($c);
+
+
+echo "\n\n--- Containing array references 1 element in nested array:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$c = array(1,&$a[0],&$a);
+check($c);
+
+echo "\n\n--- Containing array references 2 elements in nested array:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$c = array(&$a[0],&$a[1],&$a);
+check($c);
+
+echo "\n\n--- Nested array references container:\n";
+$a = array();
+$c = array(1,1,&$a);
+$a[0] = 1;
+$a[1] = &$c;
+check($c);
+
+?>
+--EXPECTF--
+
+
+--- Nested array references 1 element in containing array:
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  &array(2) {
+    [0]=>
+    &int(1)
+    [1]=>
+    int(1)
+  }
+}
+string(48) "a:3:{i:0;i:1;i:1;i:1;i:2;a:2:{i:0;R:2;i:1;i:1;}}"
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  int(1)
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(10) "b0.changed"
+    [1]=>
+    int(1)
+  }
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(10) "b0.changed"
+    [1]=>
+    int(1)
+  }
+}
+array(3) {
+  [0]=>
+  &string(12) "b2.0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(12) "b2.0.changed"
+    [1]=>
+    int(1)
+  }
+}
+array(3) {
+  [0]=>
+  &string(12) "b2.0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(12) "b2.0.changed"
+    [1]=>
+    string(12) "b2.1.changed"
+  }
+}
+
+
+--- Nested array references 1 element in containing array (slightly different):
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &array(2) {
+    [0]=>
+    int(1)
+    [1]=>
+    &int(1)
+  }
+  [2]=>
+  int(1)
+}
+string(48) "a:3:{i:0;i:1;i:1;a:2:{i:0;i:1;i:1;R:2;}i:2;i:1;}"
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  array(2) {
+    [0]=>
+    int(1)
+    [1]=>
+    &string(10) "b0.changed"
+  }
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  array(2) {
+    [0]=>
+    string(12) "b1.0.changed"
+    [1]=>
+    &string(10) "b0.changed"
+  }
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(12) "b1.1.changed"
+  [1]=>
+  array(2) {
+    [0]=>
+    string(12) "b1.0.changed"
+    [1]=>
+    &string(12) "b1.1.changed"
+  }
+  [2]=>
+  int(1)
+}
+array(3) {
+  [0]=>
+  &string(12) "b1.1.changed"
+  [1]=>
+  array(2) {
+    [0]=>
+    string(12) "b1.0.changed"
+    [1]=>
+    &string(12) "b1.1.changed"
+  }
+  [2]=>
+  string(10) "b2.changed"
+}
+
+
+--- Nested array references 2 elements in containing array:
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  &array(2) {
+    [0]=>
+    &int(1)
+    [1]=>
+    &int(1)
+  }
+}
+string(48) "a:3:{i:0;i:1;i:1;i:1;i:2;a:2:{i:0;R:2;i:1;R:3;}}"
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &int(1)
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(10) "b0.changed"
+    [1]=>
+    &int(1)
+  }
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(10) "b0.changed"
+    [1]=>
+    &string(10) "b1.changed"
+  }
+}
+array(3) {
+  [0]=>
+  &string(12) "b2.0.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(12) "b2.0.changed"
+    [1]=>
+    &string(10) "b1.changed"
+  }
+}
+array(3) {
+  [0]=>
+  &string(12) "b2.0.changed"
+  [1]=>
+  &string(12) "b2.1.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(12) "b2.0.changed"
+    [1]=>
+    &string(12) "b2.1.changed"
+  }
+}
+
+
+--- Containing array references 1 element in nested array:
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  &array(2) {
+    [0]=>
+    &int(1)
+    [1]=>
+    int(1)
+  }
+}
+string(48) "a:3:{i:0;i:1;i:1;i:1;i:2;a:2:{i:0;R:3;i:1;i:1;}}"
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  &int(1)
+  [2]=>
+  array(2) {
+    [0]=>
+    &int(1)
+    [1]=>
+    int(1)
+  }
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(10) "b1.changed"
+    [1]=>
+    int(1)
+  }
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  &string(12) "b2.0.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(12) "b2.0.changed"
+    [1]=>
+    int(1)
+  }
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  &string(12) "b2.0.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(12) "b2.0.changed"
+    [1]=>
+    string(12) "b2.1.changed"
+  }
+}
+
+
+--- Containing array references 2 elements in nested array:
+array(3) {
+  [0]=>
+  &int(1)
+  [1]=>
+  &int(1)
+  [2]=>
+  &array(2) {
+    [0]=>
+    &int(1)
+    [1]=>
+    &int(1)
+  }
+}
+string(48) "a:3:{i:0;i:1;i:1;i:1;i:2;a:2:{i:0;R:2;i:1;R:3;}}"
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &int(1)
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(10) "b0.changed"
+    [1]=>
+    &int(1)
+  }
+}
+array(3) {
+  [0]=>
+  &string(10) "b0.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(10) "b0.changed"
+    [1]=>
+    &string(10) "b1.changed"
+  }
+}
+array(3) {
+  [0]=>
+  &string(12) "b2.0.changed"
+  [1]=>
+  &string(10) "b1.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(12) "b2.0.changed"
+    [1]=>
+    &string(10) "b1.changed"
+  }
+}
+array(3) {
+  [0]=>
+  &string(12) "b2.0.changed"
+  [1]=>
+  &string(12) "b2.1.changed"
+  [2]=>
+  array(2) {
+    [0]=>
+    &string(12) "b2.0.changed"
+    [1]=>
+    &string(12) "b2.1.changed"
+  }
+}
+
+
+--- Nested array references container:
+array(3) {
+  [0]=>
+  int(1)
+  [1]=>
+  int(1)
+  [2]=>
+  &array(2) {
+    [0]=>
+    int(1)
+    [1]=>
+    &array(3) {
+      [0]=>
+      int(1)
+      [1]=>
+      int(1)
+      [2]=>
+      &array(2) {
+        [0]=>
+        int(1)
+        [1]=>
+        &array(3) {
+          [0]=>
+          int(1)
+          [1]=>
+          int(1)
+          [2]=>
+          *RECURSION*
+        }
+      }
+    }
+  }
+}
+string(74) "a:3:{i:0;i:1;i:1;i:1;i:2;a:2:{i:0;i:1;i:1;a:3:{i:0;i:1;i:1;i:1;i:2;R:4;}}}"
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  int(1)
+  [2]=>
+  &array(2) {
+    [0]=>
+    int(1)
+    [1]=>
+    array(3) {
+      [0]=>
+      int(1)
+      [1]=>
+      int(1)
+      [2]=>
+      &array(2) {
+        [0]=>
+        int(1)
+        [1]=>
+        array(3) {
+          [0]=>
+          int(1)
+          [1]=>
+          int(1)
+          [2]=>
+          *RECURSION*
+        }
+      }
+    }
+  }
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  &array(2) {
+    [0]=>
+    int(1)
+    [1]=>
+    array(3) {
+      [0]=>
+      int(1)
+      [1]=>
+      int(1)
+      [2]=>
+      &array(2) {
+        [0]=>
+        int(1)
+        [1]=>
+        array(3) {
+          [0]=>
+          int(1)
+          [1]=>
+          int(1)
+          [2]=>
+          *RECURSION*
+        }
+      }
+    }
+  }
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  &array(2) {
+    [0]=>
+    string(12) "b2.0.changed"
+    [1]=>
+    array(3) {
+      [0]=>
+      int(1)
+      [1]=>
+      int(1)
+      [2]=>
+      &array(2) {
+        [0]=>
+        string(12) "b2.0.changed"
+        [1]=>
+        array(3) {
+          [0]=>
+          int(1)
+          [1]=>
+          int(1)
+          [2]=>
+          *RECURSION*
+        }
+      }
+    }
+  }
+}
+array(3) {
+  [0]=>
+  string(10) "b0.changed"
+  [1]=>
+  string(10) "b1.changed"
+  [2]=>
+  &array(2) {
+    [0]=>
+    string(12) "b2.0.changed"
+    [1]=>
+    string(12) "b2.1.changed"
+  }
+}
diff --git a/ext/standard/tests/serialize/serialization_error_001.phpt b/ext/standard/tests/serialize/serialization_error_001.phpt
new file mode 100644 (file)
index 0000000..3f53058
--- /dev/null
@@ -0,0 +1,42 @@
+--TEST--
+Test serialize() & unserialize() functions: error conditions - wrong number of args. 
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+echo "*** Testing serialize()/unserialize() : error conditions ***\n";
+
+// Zero arguments
+var_dump( serialize() );
+var_dump( unserialize() );
+
+//Test serialize with one more than the expected number of arguments
+var_dump( serialize(1,2) );
+var_dump( unserialize(1,2) );
+
+echo "Done";
+?>
+--EXPECTF--
+*** Testing serialize()/unserialize() : error conditions ***
+
+Warning: Wrong parameter count for serialize() in %s on line 16
+NULL
+
+Warning: unserialize() expects exactly 1 parameter, 0 given in %s on line 17
+bool(false)
+
+Warning: Wrong parameter count for serialize() in %s on line 20
+NULL
+
+Warning: unserialize() expects exactly 1 parameter, 2 given in %s on line 21
+bool(false)
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_miscTypes_001.phpt b/ext/standard/tests/serialize/serialization_miscTypes_001.phpt
new file mode 100644 (file)
index 0000000..c38b0bb
Binary files /dev/null and b/ext/standard/tests/serialize/serialization_miscTypes_001.phpt differ
diff --git a/ext/standard/tests/serialize/serialization_objects_001.phpt b/ext/standard/tests/serialize/serialization_objects_001.phpt
new file mode 100644 (file)
index 0000000..aafb266
Binary files /dev/null and b/ext/standard/tests/serialize/serialization_objects_001.phpt differ
diff --git a/ext/standard/tests/serialize/serialization_objects_002.phpt b/ext/standard/tests/serialize/serialization_objects_002.phpt
new file mode 100644 (file)
index 0000000..95c2dfb
Binary files /dev/null and b/ext/standard/tests/serialize/serialization_objects_002.phpt differ
diff --git a/ext/standard/tests/serialize/serialization_objects_003.phpt b/ext/standard/tests/serialize/serialization_objects_003.phpt
new file mode 100644 (file)
index 0000000..c20590b
--- /dev/null
@@ -0,0 +1,67 @@
+--TEST--
+Test serialize() & unserialize() functions: objects (abstract classes)
+--FILE--
+<?php 
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+echo "\n--- Testing Abstract Class ---\n";
+// abstract class
+abstract class Name 
+{
+  public function Name() {
+    $this->a = 10;
+    $this->b = 12.222;
+    $this->c = "string";
+  }
+  abstract protected function getClassName();
+  public function printClassName () {
+    return $this->getClassName();
+  } 
+}
+// implement abstract class
+class extendName extends Name 
+{
+  var $a, $b, $c;
+
+  protected function getClassName() {
+    return "extendName";
+  }
+}
+
+$obj_extendName = new extendName();
+$serialize_data = serialize($obj_extendName);
+var_dump( $serialize_data );
+$unserialize_data = unserialize($serialize_data);
+var_dump( $unserialize_data );
+
+$serialize_data = serialize($obj_extendName->printClassName());
+var_dump( $serialize_data );
+$unserialize_data = unserialize($serialize_data);
+var_dump( $unserialize_data );
+
+echo "\nDone";
+?>
+--EXPECTF--
+--- Testing Abstract Class ---
+string(119) "O:10:"extendName":3:{s:1:"a";i:10;s:1:"b";d:12.2219999999999995310417943983338773250579833984375;s:1:"c";s:6:"string";}"
+object(extendName)#%d (3) {
+  ["a"]=>
+  int(10)
+  ["b"]=>
+  float(12.222)
+  ["c"]=>
+  string(6) "string"
+}
+string(18) "s:10:"extendName";"
+string(10) "extendName"
+
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_004.phpt b/ext/standard/tests/serialize/serialization_objects_004.phpt
new file mode 100644 (file)
index 0000000..6b826a3
--- /dev/null
@@ -0,0 +1,49 @@
+--TEST--
+Test serialize() & unserialize() functions: objects - ensure that COW references of objects are not serialized separately (unlike other types). 
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+$x = new stdClass;
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+$x = 1;
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+$x = "a";
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+$x = true;
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+$x = null;
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+$x = array();
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+echo "Done";
+?>
+--EXPECTF--
+string(37) "a:2:{i:0;O:8:"stdClass":0:{}i:1;r:2;}"
+string(22) "a:2:{i:0;i:1;i:1;i:1;}"
+string(30) "a:2:{i:0;s:1:"a";i:1;s:1:"a";}"
+string(22) "a:2:{i:0;b:1;i:1;b:1;}"
+string(18) "a:2:{i:0;N;i:1;N;}"
+string(26) "a:2:{i:0;a:0:{}i:1;a:0:{}}"
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_005.phpt b/ext/standard/tests/serialize/serialization_objects_005.phpt
new file mode 100644 (file)
index 0000000..35b1593
--- /dev/null
@@ -0,0 +1,120 @@
+--TEST--
+Check behaviour of incomplete class
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+$serialized = 'O:1:"C":1:{s:1:"p";i:1;}';
+
+$incomplete = unserialize($serialized);
+eval('Class C {}');
+$complete   = unserialize($serialized);
+
+
+echo "\n\n---> Various types of access on complete class:\n" ;
+var_dump($complete);
+var_dump(is_object($complete));
+var_dump($complete->p);
+
+$ref1 = "ref1.original";
+$complete->p = &$ref1;
+var_dump($complete->p);
+$ref1 = "ref1.changed";
+var_dump($complete->p);
+$complete->p = "p.changed";
+var_dump($ref1);
+
+var_dump(isset($complete->x));
+$complete->x = "x.new";
+var_dump(isset($complete->x));
+unset($complete->x);
+var_dump($complete->x);
+
+
+echo "\n\n---> Same types of access on incomplete class:\n" ;
+var_dump($incomplete);
+var_dump(is_object($incomplete));
+var_dump($incomplete->p);
+
+$ref2 = "ref1.original";
+$incomplete->p = &$ref2;
+var_dump($incomplete->p);
+$ref2 = "ref1.changed";
+var_dump($incomplete->p);
+$incomplete->p = "p.changed";
+var_dump($ref1);
+
+var_dump(isset($incomplete->x));
+$incomplete->x = "x.new";
+var_dump(isset($incomplete->x));
+unset($incomplete->x);
+var_dump($incomplete->x);
+
+$incomplete->f();
+
+echo "Done";
+?>
+--EXPECTF--
+---> Various types of access on complete class:
+object(C)#%d (1) {
+  ["p"]=>
+  int(1)
+}
+bool(true)
+int(1)
+string(13) "ref1.original"
+string(12) "ref1.changed"
+string(9) "p.changed"
+bool(false)
+bool(true)
+
+Notice: Undefined property: C::$x in %s on line 37
+NULL
+
+
+---> Same types of access on incomplete class:
+object(__PHP_Incomplete_Class)#%d (2) {
+  ["__PHP_Incomplete_Class_Name"]=>
+  string(1) "C"
+  ["p"]=>
+  int(1)
+}
+bool(false)
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 43
+NULL
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 46
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 47
+NULL
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 49
+NULL
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 50
+string(9) "p.changed"
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 53
+bool(false)
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 54
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 55
+bool(false)
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 56
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 57
+NULL
+
+Fatal error: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 59
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_006.phpt b/ext/standard/tests/serialize/serialization_objects_006.phpt
new file mode 100644 (file)
index 0000000..e223f4e
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Behaviour of incomplete class is preserved even when it was not created by unserialize().
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+$a = new __PHP_Incomplete_Class;
+var_dump($a);
+var_dump($a->p);
+
+echo "Done";
+?>
+--EXPECTF--
+object(__PHP_Incomplete_Class)#%d (0) {
+}
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "unknown" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition  in %s on line 15
+NULL
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_007.phpt b/ext/standard/tests/serialize/serialization_objects_007.phpt
new file mode 100644 (file)
index 0000000..9cba9d1
--- /dev/null
@@ -0,0 +1,42 @@
+--TEST--
+Ensure __autoload is called twice if unserialize_callback_func is defined.
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+function __autoload($name) {
+       echo "in __autoload($name)\n";
+}
+
+ini_set('unserialize_callback_func','check');
+
+function check($name) {
+       echo "in check($name)\n"; 
+}
+
+$o = unserialize('O:3:"FOO":0:{}');
+
+var_dump($o);
+
+echo "Done";
+?>
+--EXPECTF--
+in __autoload(FOO)
+in check(FOO)
+in __autoload(FOO)
+
+Warning: unserialize(): Function check() hasn't defined the class it was called for in %s on line 23
+object(__PHP_Incomplete_Class)#%d (1) {
+  ["__PHP_Incomplete_Class_Name"]=>
+  string(3) "FOO"
+}
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_008.phpt b/ext/standard/tests/serialize/serialization_objects_008.phpt
new file mode 100644 (file)
index 0000000..b963872
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Bad unserialize_callback_func
+--FILE--
+<?php 
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+ini_set('unserialize_callback_func','Nonexistent');
+$o = unserialize('O:3:"FOO":0:{}');
+var_dump($o);
+echo "Done";
+?>
+--EXPECTF--
+
+Warning: unserialize(): defined (Nonexistent) but not found in %s on line 14
+object(__PHP_Incomplete_Class)#%d (1) {
+  ["__PHP_Incomplete_Class_Name"]=>
+  string(3) "FOO"
+}
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_009.phpt b/ext/standard/tests/serialize/serialization_objects_009.phpt
new file mode 100644 (file)
index 0000000..2e8b2dc
--- /dev/null
@@ -0,0 +1,36 @@
+--TEST--
+Custom unserialization of classes with no custom unserializer.
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+$ser = 'C:1:"C":6:{dasdas}';
+$a = unserialize($ser);
+eval('class C {}');
+$b = unserialize($ser);
+
+var_dump($a, $b);
+
+echo "Done";
+?>
+--EXPECTF--
+
+Warning: Class __PHP_Incomplete_Class has no unserializer in %s on line 14
+
+Notice: unserialize(): Error at offset 6 of 18 bytes in %s on line 14
+
+Warning: Class C has no unserializer in %s on line 16
+
+Notice: unserialize(): Error at offset 6 of 18 bytes in %s on line 16
+bool(false)
+bool(false)
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_010.phpt b/ext/standard/tests/serialize/serialization_objects_010.phpt
new file mode 100644 (file)
index 0000000..0fbf072
--- /dev/null
@@ -0,0 +1,37 @@
+--TEST--
+Serialize() must return a string or NULL
+--SKIPIF--
+<?php if (!interface_exists('Serializable')) die('skip Interface Serialzable not defined'); ?>
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+Class C implements Serializable {
+       public function serialize() { 
+               return $this;
+       }
+       
+       public function unserialize($blah) {
+       }
+}
+
+try {
+       var_dump(serialize(new C));
+} catch (Exception $e) {
+       echo $e->getMessage(). "\n";
+}
+
+echo "Done";
+?>
+--EXPECTF--
+C::serialize() must return a string or NULL
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_011.phpt b/ext/standard/tests/serialize/serialization_objects_011.phpt
new file mode 100644 (file)
index 0000000..1dc4839
--- /dev/null
@@ -0,0 +1,196 @@
+--TEST--
+Object serialization / unserialization with inherited and hidden properties.
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+Class A {
+       private $APriv = "A.APriv";
+       protected $AProt = "A.AProt";
+       public $APub = "A.APub";
+       
+       function audit() {
+               return isset($this->APriv, $this->AProt, $this->APub); 
+       }               
+}
+
+Class B extends A {
+       private $BPriv = "B.BPriv";
+       protected $BProt = "B.BProt";
+       public $BPub = "B.BPub";
+       
+       function audit() {
+               return  parent::audit() && isset($this->AProt, $this->APub,
+                                        $this->BPriv, $this->BProt, $this->BPub); 
+       }       
+}
+
+Class C extends B {
+       private $APriv = "C.APriv";
+       protected $AProt = "C.AProt";
+       public $APub = "C.APub";
+       
+       private $CPriv = "C.CPriv";
+       protected $CProt = "C.BProt";
+       public $CPub = "C.CPub";
+       
+       function audit() {
+               return parent::audit() && isset($this->APriv, $this->AProt, $this->APub, 
+                                        $this->BProt, $this->BPub, 
+                                        $this->CPriv, $this->CProt, $this->CPub); 
+       }
+}
+
+function prettyPrint($obj) {
+       echo "\n\nBefore serialization:\n";
+       var_dump($obj);
+
+       echo "Serialized form:\n";
+       $ser = serialize($obj);
+       $serPrintable = str_replace("\0", '\0', $ser);
+       var_dump($serPrintable);
+       
+       echo "Unserialized:\n";
+       $uobj = unserialize($ser);
+       var_dump($uobj);
+       
+       echo "Sanity check: ";
+       var_dump($uobj->audit());
+}
+
+echo "-- Test instance of A --\n";
+prettyPrint(new A);
+echo "\n\n-- Test instance of B --\n";
+prettyPrint(new B);
+echo "\n\n-- Test instance of C --\n";
+prettyPrint(new C);
+
+echo "Done";
+?>
+--EXPECTF--
+-- Test instance of A --
+
+
+Before serialization:
+object(A)#%d (3) {
+  ["APriv":"A":private]=>
+  string(7) "A.APriv"
+  ["AProt":protected]=>
+  string(7) "A.AProt"
+  ["APub"]=>
+  string(6) "A.APub"
+}
+Serialized form:
+string(98) "O:1:"A":3:{s:8:"\0A\0APriv";s:7:"A.APriv";s:8:"\0*\0AProt";s:7:"A.AProt";s:4:"APub";s:6:"A.APub";}"
+Unserialized:
+object(A)#%d (3) {
+  ["APriv":"A":private]=>
+  string(7) "A.APriv"
+  ["AProt":protected]=>
+  string(7) "A.AProt"
+  ["APub"]=>
+  string(6) "A.APub"
+}
+Sanity check: bool(true)
+
+
+-- Test instance of B --
+
+
+Before serialization:
+object(B)#%d (6) {
+  ["BPriv":"B":private]=>
+  string(7) "B.BPriv"
+  ["BProt":protected]=>
+  string(7) "B.BProt"
+  ["BPub"]=>
+  string(6) "B.BPub"
+  ["APriv":"A":private]=>
+  string(7) "A.APriv"
+  ["AProt":protected]=>
+  string(7) "A.AProt"
+  ["APub"]=>
+  string(6) "A.APub"
+}
+Serialized form:
+string(184) "O:1:"B":6:{s:8:"\0B\0BPriv";s:7:"B.BPriv";s:8:"\0*\0BProt";s:7:"B.BProt";s:4:"BPub";s:6:"B.BPub";s:8:"\0A\0APriv";s:7:"A.APriv";s:8:"\0*\0AProt";s:7:"A.AProt";s:4:"APub";s:6:"A.APub";}"
+Unserialized:
+object(B)#%d (6) {
+  ["BPriv":"B":private]=>
+  string(7) "B.BPriv"
+  ["BProt":protected]=>
+  string(7) "B.BProt"
+  ["BPub"]=>
+  string(6) "B.BPub"
+  ["APriv":"A":private]=>
+  string(7) "A.APriv"
+  ["AProt":protected]=>
+  string(7) "A.AProt"
+  ["APub"]=>
+  string(6) "A.APub"
+}
+Sanity check: bool(true)
+
+
+-- Test instance of C --
+
+
+Before serialization:
+object(C)#%d (10) {
+  ["APriv":"C":private]=>
+  string(7) "C.APriv"
+  ["AProt":protected]=>
+  string(7) "C.AProt"
+  ["APub"]=>
+  string(6) "C.APub"
+  ["CPriv":"C":private]=>
+  string(7) "C.CPriv"
+  ["CProt":protected]=>
+  string(7) "C.BProt"
+  ["CPub"]=>
+  string(6) "C.CPub"
+  ["BPriv":"B":private]=>
+  string(7) "B.BPriv"
+  ["BProt":protected]=>
+  string(7) "B.BProt"
+  ["BPub"]=>
+  string(6) "B.BPub"
+  ["APriv":"A":private]=>
+  string(7) "A.APriv"
+}
+Serialized form:
+string(302) "O:1:"C":10:{s:8:"\0C\0APriv";s:7:"C.APriv";s:8:"\0*\0AProt";s:7:"C.AProt";s:4:"APub";s:6:"C.APub";s:8:"\0C\0CPriv";s:7:"C.CPriv";s:8:"\0*\0CProt";s:7:"C.BProt";s:4:"CPub";s:6:"C.CPub";s:8:"\0B\0BPriv";s:7:"B.BPriv";s:8:"\0*\0BProt";s:7:"B.BProt";s:4:"BPub";s:6:"B.BPub";s:8:"\0A\0APriv";s:7:"A.APriv";}"
+Unserialized:
+object(C)#%d (10) {
+  ["APriv":"C":private]=>
+  string(7) "C.APriv"
+  ["AProt":protected]=>
+  string(7) "C.AProt"
+  ["APub"]=>
+  string(6) "C.APub"
+  ["CPriv":"C":private]=>
+  string(7) "C.CPriv"
+  ["CProt":protected]=>
+  string(7) "C.BProt"
+  ["CPub"]=>
+  string(6) "C.CPub"
+  ["BPriv":"B":private]=>
+  string(7) "B.BPriv"
+  ["BProt":protected]=>
+  string(7) "B.BProt"
+  ["BPub"]=>
+  string(6) "B.BPub"
+  ["APriv":"A":private]=>
+  string(7) "A.APriv"
+}
+Sanity check: bool(true)
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_012.phpt b/ext/standard/tests/serialize/serialization_objects_012.phpt
new file mode 100644 (file)
index 0000000..f994d8e
--- /dev/null
@@ -0,0 +1,244 @@
+--TEST--
+Object serialization / unserialization: real references and COW references
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+echo "\n\nArray containing same object twice:\n";
+$obj = new stdclass;
+$a[0] = $obj;
+$a[1] = $a[0];
+var_dump($a);
+
+$ser = serialize($a);
+var_dump($ser); 
+
+$ua = unserialize($ser);
+var_dump($ua);
+$ua[0]->a = "newProp";
+var_dump($ua);
+$ua[0] = "a0.changed";
+var_dump($ua);
+
+
+echo "\n\nArray containing object and reference to that object:\n";
+$obj = new stdclass;
+$a[0] = $obj;
+$a[1] = &$a[0];
+var_dump($a);
+
+$ser = serialize($a);
+var_dump($ser); 
+
+$ua = unserialize($ser);
+var_dump($ua);
+$ua[0]->a = "newProp";
+var_dump($ua);
+$ua[0] = "a0.changed";
+var_dump($ua);
+
+echo "\n\nObject containing same object twice:";
+$obj = new stdclass;
+$contaner = new stdclass;
+$contaner->a = $obj;
+$contaner->b = $contaner->a; 
+var_dump($contaner);
+
+$ser = serialize($contaner);
+var_dump($ser); 
+
+$ucontainer = unserialize($ser);
+var_dump($ucontainer);
+$ucontainer->a->a = "newProp";
+var_dump($ucontainer);
+$ucontainer->a = "container->a.changed";
+var_dump($ucontainer);
+
+
+echo "\n\nObject containing object and reference to that object:\n";
+$obj = new stdclass;
+$contaner = new stdclass;
+$contaner->a = $obj;
+$contaner->b = &$contaner->a; 
+var_dump($contaner);
+
+$ser = serialize($contaner);
+var_dump($ser); 
+
+$ucontainer = unserialize($ser);
+var_dump($ucontainer);
+$ucontainer->a->a = "newProp";
+var_dump($ucontainer);
+$ucontainer->b = "container->a.changed";
+var_dump($ucontainer);
+
+echo "Done";
+?>
+--EXPECTF--
+
+
+Array containing same object twice:
+array(2) {
+  [0]=>
+  object(stdClass)#%d (0) {
+  }
+  [1]=>
+  object(stdClass)#%d (0) {
+  }
+}
+string(37) "a:2:{i:0;O:8:"stdClass":0:{}i:1;r:2;}"
+array(2) {
+  [0]=>
+  object(stdClass)#%d (0) {
+  }
+  [1]=>
+  object(stdClass)#%d (0) {
+  }
+}
+array(2) {
+  [0]=>
+  object(stdClass)#%d (1) {
+    ["a"]=>
+    string(7) "newProp"
+  }
+  [1]=>
+  object(stdClass)#%d (1) {
+    ["a"]=>
+    string(7) "newProp"
+  }
+}
+array(2) {
+  [0]=>
+  string(10) "a0.changed"
+  [1]=>
+  object(stdClass)#%d (1) {
+    ["a"]=>
+    string(7) "newProp"
+  }
+}
+
+
+Array containing object and reference to that object:
+array(2) {
+  [0]=>
+  &object(stdClass)#%d (0) {
+  }
+  [1]=>
+  &object(stdClass)#%d (0) {
+  }
+}
+string(37) "a:2:{i:0;O:8:"stdClass":0:{}i:1;R:2;}"
+array(2) {
+  [0]=>
+  &object(stdClass)#%d (0) {
+  }
+  [1]=>
+  &object(stdClass)#%d (0) {
+  }
+}
+array(2) {
+  [0]=>
+  &object(stdClass)#%d (1) {
+    ["a"]=>
+    string(7) "newProp"
+  }
+  [1]=>
+  &object(stdClass)#%d (1) {
+    ["a"]=>
+    string(7) "newProp"
+  }
+}
+array(2) {
+  [0]=>
+  &string(10) "a0.changed"
+  [1]=>
+  &string(10) "a0.changed"
+}
+
+
+Object containing same object twice:object(stdClass)#%d (2) {
+  ["a"]=>
+  object(stdClass)#%d (0) {
+  }
+  ["b"]=>
+  object(stdClass)#%d (0) {
+  }
+}
+string(58) "O:8:"stdClass":2:{s:1:"a";O:8:"stdClass":0:{}s:1:"b";r:2;}"
+object(stdClass)#%d (2) {
+  ["a"]=>
+  object(stdClass)#%d (0) {
+  }
+  ["b"]=>
+  object(stdClass)#%d (0) {
+  }
+}
+object(stdClass)#%d (2) {
+  ["a"]=>
+  object(stdClass)#%d (1) {
+    ["a"]=>
+    string(7) "newProp"
+  }
+  ["b"]=>
+  object(stdClass)#%d (1) {
+    ["a"]=>
+    string(7) "newProp"
+  }
+}
+object(stdClass)#%d (2) {
+  ["a"]=>
+  string(20) "container->a.changed"
+  ["b"]=>
+  object(stdClass)#%d (1) {
+    ["a"]=>
+    string(7) "newProp"
+  }
+}
+
+
+Object containing object and reference to that object:
+object(stdClass)#%d (2) {
+  ["a"]=>
+  &object(stdClass)#%d (0) {
+  }
+  ["b"]=>
+  &object(stdClass)#%d (0) {
+  }
+}
+string(58) "O:8:"stdClass":2:{s:1:"a";O:8:"stdClass":0:{}s:1:"b";R:2;}"
+object(stdClass)#%d (2) {
+  ["a"]=>
+  &object(stdClass)#%d (0) {
+  }
+  ["b"]=>
+  &object(stdClass)#%d (0) {
+  }
+}
+object(stdClass)#%d (2) {
+  ["a"]=>
+  &object(stdClass)#%d (1) {
+    ["a"]=>
+    string(7) "newProp"
+  }
+  ["b"]=>
+  &object(stdClass)#%d (1) {
+    ["a"]=>
+    string(7) "newProp"
+  }
+}
+object(stdClass)#%d (2) {
+  ["a"]=>
+  &string(20) "container->a.changed"
+  ["b"]=>
+  &string(20) "container->a.changed"
+}
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_013.phpt b/ext/standard/tests/serialize/serialization_objects_013.phpt
new file mode 100644 (file)
index 0000000..01b623c
--- /dev/null
@@ -0,0 +1,494 @@
+--TEST--
+Object serialization / unserialization: references amongst properties 
+--INI--
+error_reporting = E_ALL & ~E_STRICT
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+function check(&$obj) {
+       var_dump($obj);
+       $ser = serialize($obj);
+       var_dump($ser);
+       
+       $uobj = unserialize($ser);
+       var_dump($uobj);
+       $uobj->a = "obj->a.changed";
+       var_dump($uobj);
+       $uobj->b = "obj->b.changed";
+       var_dump($uobj);
+       $uobj->c = "obj->c.changed";
+       var_dump($uobj);        
+}
+
+echo "\n\n--- a refs b:\n";
+$obj = new stdClass;
+$obj->a = &$obj->b;
+$obj->b = 1;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a refs c:\n";
+$obj = new stdClass;
+$obj->a = &$obj->c;
+$obj->b = 1;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- b refs a:\n";
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = &$obj->a;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- b refs c:\n";
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = &$obj->c;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- c refs a:\n";
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = 1;
+$obj->c = &$obj->a;
+check($obj);
+
+echo "\n\n--- c refs b:\n";
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = 1;
+$obj->c = &$obj->b;
+check($obj);
+
+echo "\n\n--- a,b refs c:\n";
+$obj = new stdClass;
+$obj->a = &$obj->c;
+$obj->b = &$obj->c;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a,c refs b:\n";
+$obj = new stdClass;
+$obj->a = &$obj->b;
+$obj->b = 1;
+$obj->c = &$obj->b;
+check($obj);
+
+echo "\n\n--- b,c refs a:\n";
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = &$obj->a;
+$obj->c = &$obj->a;
+check($obj);
+
+echo "Done";
+?>
+--EXPECTF--
+
+--- a refs b:
+object(stdClass)#%d (3) {
+  ["b"]=>
+  &int(1)
+  ["a"]=>
+  &int(1)
+  ["c"]=>
+  int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"b";i:1;s:1:"a";R:2;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+  ["b"]=>
+  &int(1)
+  ["a"]=>
+  &int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["b"]=>
+  &string(14) "obj->a.changed"
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+
+
+--- a refs c:
+object(stdClass)#%d (3) {
+  ["c"]=>
+  &int(1)
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"c";i:1;s:1:"a";R:2;s:1:"b";i:1;}"
+object(stdClass)#%d (3) {
+  ["c"]=>
+  &int(1)
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["c"]=>
+  &string(14) "obj->a.changed"
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["c"]=>
+  &string(14) "obj->a.changed"
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+  ["c"]=>
+  &string(14) "obj->c.changed"
+  ["a"]=>
+  &string(14) "obj->c.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+}
+
+
+--- b refs a:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";R:2;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  &string(14) "obj->a.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+
+
+--- b refs c:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  int(1)
+  ["c"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"c";i:1;s:1:"b";R:3;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  int(1)
+  ["c"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["c"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["c"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["c"]=>
+  &string(14) "obj->c.changed"
+  ["b"]=>
+  &string(14) "obj->c.changed"
+}
+
+
+--- c refs a:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";i:1;s:1:"c";R:2;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  &int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->c.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  &string(14) "obj->c.changed"
+}
+
+
+--- c refs b:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";i:1;s:1:"c";R:3;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  &int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  &int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  &string(14) "obj->c.changed"
+  ["c"]=>
+  &string(14) "obj->c.changed"
+}
+
+
+--- a,b refs c:
+object(stdClass)#%d (3) {
+  ["c"]=>
+  &int(1)
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"c";i:1;s:1:"a";R:2;s:1:"b";R:2;}"
+object(stdClass)#%d (3) {
+  ["c"]=>
+  &int(1)
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+}
+object(stdClass)#%d (3) {
+  ["c"]=>
+  &string(14) "obj->a.changed"
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+  ["c"]=>
+  &string(14) "obj->b.changed"
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+  ["c"]=>
+  &string(14) "obj->c.changed"
+  ["a"]=>
+  &string(14) "obj->c.changed"
+  ["b"]=>
+  &string(14) "obj->c.changed"
+}
+
+
+--- a,c refs b:
+object(stdClass)#%d (3) {
+  ["b"]=>
+  &int(1)
+  ["a"]=>
+  &int(1)
+  ["c"]=>
+  &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"b";i:1;s:1:"a";R:2;s:1:"c";R:2;}"
+object(stdClass)#%d (3) {
+  ["b"]=>
+  &int(1)
+  ["a"]=>
+  &int(1)
+  ["c"]=>
+  &int(1)
+}
+object(stdClass)#%d (3) {
+  ["b"]=>
+  &string(14) "obj->a.changed"
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["c"]=>
+  &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+  ["b"]=>
+  &string(14) "obj->c.changed"
+  ["a"]=>
+  &string(14) "obj->c.changed"
+  ["c"]=>
+  &string(14) "obj->c.changed"
+}
+
+
+--- b,c refs a:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";R:2;s:1:"c";R:2;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  &int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  &string(14) "obj->a.changed"
+  ["c"]=>
+  &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->c.changed"
+  ["b"]=>
+  &string(14) "obj->c.changed"
+  ["c"]=>
+  &string(14) "obj->c.changed"
+}
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_014.phpt b/ext/standard/tests/serialize/serialization_objects_014.phpt
new file mode 100644 (file)
index 0000000..234f5e0
--- /dev/null
@@ -0,0 +1,295 @@
+--TEST--
+Object serialization / unserialization: references to external values 
+--INI--
+error_reporting = E_ALL & ~E_STRICT
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+function check(&$obj) {
+       var_dump($obj);
+       $ser = serialize($obj);
+       var_dump($ser);
+       
+       $uobj = unserialize($ser);
+       var_dump($uobj);
+       $uobj->a = "obj->a.changed";
+       var_dump($uobj);
+       $uobj->b = "obj->b.changed";
+       var_dump($uobj);
+       $uobj->c = "obj->c.changed";
+       var_dump($uobj);        
+}
+
+echo "\n\n--- a refs external:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$ext;
+$obj->b = 1;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- b refs external:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = &$ext;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- c refs external:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = 1;
+$obj->c = &$ext;
+check($obj);
+
+echo "\n\n--- a,b ref external:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$ext;
+$obj->b = &$ext;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a,b,c ref external:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$ext;
+$obj->b = &$ext;
+$obj->c = &$ext;
+check($obj);
+
+echo "Done";
+?>
+--EXPECTF--
+
+--- a refs external:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";i:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  int(1)
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+
+
+--- b refs external:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";i:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  int(1)
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+
+
+--- c refs external:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  int(1)
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";i:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  int(1)
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+
+
+--- a,b ref external:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";R:2;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  &string(14) "obj->a.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+
+
+--- a,b,c ref external:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";R:2;s:1:"c";R:2;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &int(1)
+  ["b"]=>
+  &int(1)
+  ["c"]=>
+  &int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  &string(14) "obj->a.changed"
+  ["c"]=>
+  &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->c.changed"
+  ["b"]=>
+  &string(14) "obj->c.changed"
+  ["c"]=>
+  &string(14) "obj->c.changed"
+}
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_015.phpt b/ext/standard/tests/serialize/serialization_objects_015.phpt
new file mode 100644 (file)
index 0000000..02e8279
--- /dev/null
@@ -0,0 +1,532 @@
+--TEST--
+Object serialization / unserialization: properties reference containing object 
+--INI--
+error_reporting = E_ALL & ~E_STRICT
+--FILE--
+<?php
+
+function check(&$obj) {
+       var_dump($obj);
+       $ser = serialize($obj);
+       var_dump($ser);
+       
+       $uobj = unserialize($ser);
+       var_dump($uobj);
+       $uobj->a = "obj->a.changed";
+       var_dump($uobj);
+       $uobj->b = "obj->b.changed";
+       var_dump($uobj);
+       $uobj->c = "obj->c.changed";
+       var_dump($uobj);        
+}
+
+echo "\n\n--- a refs container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$obj;
+$obj->b = 1;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a eqs container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = $obj;
+$obj->b = 1;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a,b ref container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$obj;
+$obj->b = &$obj;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a,b eq container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = $obj;
+$obj->b = $obj;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a,b,c ref container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$obj;
+$obj->b = &$obj;
+$obj->c = &$obj;
+check($obj);
+
+echo "\n\n--- a,b,c eq container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = $obj;
+$obj->b = $obj;
+$obj->c = $obj;
+check($obj);
+
+echo "Done";
+?>
+--EXPECTF--
+--- a refs container:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    int(1)
+    ["c"]=>
+    int(1)
+  }
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";R:1;s:1:"b";i:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    int(1)
+    ["c"]=>
+    int(1)
+  }
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+
+
+--- a eqs container:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    int(1)
+    ["c"]=>
+    int(1)
+  }
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";r:1;s:1:"b";i:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    int(1)
+    ["c"]=>
+    int(1)
+  }
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  int(1)
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+
+
+--- a,b ref container:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    int(1)
+  }
+  ["b"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    int(1)
+  }
+  ["c"]=>
+  int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";R:1;s:1:"b";R:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    int(1)
+  }
+  ["b"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    int(1)
+  }
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  &string(14) "obj->a.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+
+
+--- a,b eq container:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    int(1)
+  }
+  ["b"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    int(1)
+  }
+  ["c"]=>
+  int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";r:1;s:1:"b";r:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    int(1)
+  }
+  ["b"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    int(1)
+  }
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    string(14) "obj->a.changed"
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    int(1)
+  }
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  int(1)
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+
+
+--- a,b,c ref container:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+  ["b"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+  ["c"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";R:1;s:1:"b";R:1;s:1:"c";R:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+  ["b"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+  ["c"]=>
+  &object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->a.changed"
+  ["b"]=>
+  &string(14) "obj->a.changed"
+  ["c"]=>
+  &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->b.changed"
+  ["b"]=>
+  &string(14) "obj->b.changed"
+  ["c"]=>
+  &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  &string(14) "obj->c.changed"
+  ["b"]=>
+  &string(14) "obj->c.changed"
+  ["c"]=>
+  &string(14) "obj->c.changed"
+}
+
+
+--- a,b,c eq container:
+object(stdClass)#%d (3) {
+  ["a"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+  ["b"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+  ["c"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";r:1;s:1:"b";r:1;s:1:"c";r:1;}"
+object(stdClass)#%d (3) {
+  ["a"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+  ["b"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+  ["c"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    *RECURSION*
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    string(14) "obj->a.changed"
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+  ["c"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    string(14) "obj->a.changed"
+    ["b"]=>
+    *RECURSION*
+    ["c"]=>
+    *RECURSION*
+  }
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  object(stdClass)#%d (3) {
+    ["a"]=>
+    string(14) "obj->a.changed"
+    ["b"]=>
+    string(14) "obj->b.changed"
+    ["c"]=>
+    *RECURSION*
+  }
+}
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(14) "obj->a.changed"
+  ["b"]=>
+  string(14) "obj->b.changed"
+  ["c"]=>
+  string(14) "obj->c.changed"
+}
+Done
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_precision_001.phpt b/ext/standard/tests/serialize/serialization_precision_001.phpt
new file mode 100644 (file)
index 0000000..eb633be
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Test serialize_precision (part 1)
+--INI--
+serialize_precision=10
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+var_dump(serialize(0.1));
+?>
+--EXPECTF--
+string(6) "d:0.1;"
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_precision_002.phpt b/ext/standard/tests/serialize/serialization_precision_002.phpt
new file mode 100644 (file)
index 0000000..653fabe
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Test serialize_precision (part 2)
+--INI--
+serialize_precision=75
+--FILE--
+<?php
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+var_dump(serialize(0.1));
+?>
+--EXPECTF--
+string(60) "d:0.1000000000000000055511151231257827021181583404541015625;"
\ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_resources_001.phpt b/ext/standard/tests/serialize/serialization_resources_001.phpt
new file mode 100644 (file)
index 0000000..dbb7d3d
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+Test serialize() & unserialize() functions: resources
+--FILE--
+<?php 
+/* Prototype  : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized) 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+/* Prototype  : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it 
+ * Source code: ext/standard/var.c
+ * Alias to functions: 
+ */
+
+echo "\n--- Testing Resource ---\n";
+$file_handle = fopen( __FILE__, "r" );
+$serialized_data = serialize( $file_handle );
+fclose($file_handle);
+var_dump($serialized_data);
+var_dump(unserialize($serialized_data));
+
+echo "\nDone";
+?>
+--EXPECTF--
+--- Testing Resource ---
+string(4) "i:%d;"
+int(%d)
+
+Done
\ No newline at end of file