1--TEST--
2Check for unbuffered streaming unserialization
3--SKIPIF--
4<?php
5if ((version_compare(PHP_VERSION, '5.2.13') <= 0) ||
6    (version_compare(PHP_VERSION, '5.3.0') >= 0 &&
7     version_compare(PHP_VERSION, '5.3.2') <= 0)) {
8    echo "skip tests in PHP 5.2.14/5.3.3 or newer";
9}
10--FILE--
11<?php
12if(!extension_loaded('msgpack')) {
13    dl('msgpack.' . PHP_SHLIB_SUFFIX);
14}
15
16function test($type, $variable, $test = null) {
17    $serialized = msgpack_serialize($variable);
18
19    $unpacker = new MessagePackUnpacker();
20
21    $length = strlen($serialized);
22
23    $str = "";
24    $offset = 0;
25
26    for ($i = 0; $i < $length;) {
27        $len = rand(1, 10);
28        $str .= substr($serialized, $i, $len);
29
30        if ($unpacker->execute($str, $offset))
31        {
32            $unserialized = $unpacker->data();
33            var_dump($unserialized);
34
35            $unpacker->reset();
36            $str = "";
37            $offset = 0;
38        }
39
40        $i += $len;
41    }
42
43    if (!is_bool($test))
44    {
45        echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL;
46    }
47    else
48    {
49        echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL;
50    }
51}
52
53test('null', null);
54
55test('bool: true', true);
56test('bool: false', false);
57
58test('zero: 0', 0);
59test('small: 1', 1);
60test('small: -1', -1);
61test('medium: 1000', 1000);
62test('medium: -1000', -1000);
63test('large: 100000', 100000);
64test('large: -100000', -100000);
65
66test('double: 123.456', 123.456);
67
68test('empty: ""', "");
69test('string: "foobar"', "foobar");
70
71test('array: empty', array(), false);
72test('array(1, 2, 3)', array(1, 2, 3), false);
73test('array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false);
74
75test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false);
76test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false);
77test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false);
78test('array("" => "empty")', array("" => "empty"), false);
79
80$a = array('foo');
81test('array($a, $a)', array($a, $a), false);
82test('array(&$a, &$a)', array(&$a, &$a), false);
83
84$a = array(null);
85$b = array(&$a);
86$a[0] = &$b;
87
88test('cyclic', $a, true);
89
90$a = array(
91    'a' => array(
92        'b' => 'c',
93        'd' => 'e'
94        ),
95    'f' => array(
96        'g' => 'h'
97        )
98    );
99
100test('array', $a, false);
101
102class Obj {
103    public $a;
104    protected $b;
105    private $c;
106
107    function __construct($a, $b, $c) {
108        $this->a = $a;
109        $this->b = $b;
110        $this->c = $c;
111    }
112}
113
114test('object', new Obj(1, 2, 3), false);
115
116test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false);
117
118$o = new Obj(1, 2, 3);
119
120test('object', array(&$o, &$o), false);
121--EXPECTF--
122NULL
123OK
124bool(true)
125OK
126bool(false)
127OK
128int(0)
129OK
130int(1)
131OK
132int(-1)
133OK
134int(1000)
135OK
136int(-1000)
137OK
138int(100000)
139OK
140int(-100000)
141OK
142float(123.456)
143OK
144string(0) ""
145OK
146string(6) "foobar"
147OK
148array(0) {
149}
150OK
151array(3) {
152  [0]=>
153  int(1)
154  [1]=>
155  int(2)
156  [2]=>
157  int(3)
158}
159OK
160array(3) {
161  [0]=>
162  array(3) {
163    [0]=>
164    int(1)
165    [1]=>
166    int(2)
167    [2]=>
168    int(3)
169  }
170  [1]=>
171  array(3) {
172    [0]=>
173    int(4)
174    [1]=>
175    int(5)
176    [2]=>
177    int(6)
178  }
179  [2]=>
180  array(3) {
181    [0]=>
182    int(7)
183    [1]=>
184    int(8)
185    [2]=>
186    int(9)
187  }
188}
189OK
190array(3) {
191  [0]=>
192  string(3) "foo"
193  [1]=>
194  string(3) "foo"
195  [2]=>
196  string(3) "foo"
197}
198OK
199array(2) {
200  ["one"]=>
201  int(1)
202  ["two"]=>
203  int(2)
204}
205OK
206array(2) {
207  ["kek"]=>
208  string(3) "lol"
209  ["lol"]=>
210  string(3) "kek"
211}
212OK
213array(1) {
214  [""]=>
215  string(5) "empty"
216}
217OK
218array(2) {
219  [0]=>
220  array(1) {
221    [0]=>
222    string(3) "foo"
223  }
224  [1]=>
225  array(1) {
226    [0]=>
227    string(3) "foo"
228  }
229}
230OK
231array(2) {
232  [0]=>
233  &array(1) {
234    [0]=>
235    string(3) "foo"
236  }
237  [1]=>
238  &array(1) {
239    [0]=>
240    string(3) "foo"
241  }
242}
243OK
244array(1) {
245  [0]=>
246  &array(1) {
247    [0]=>
248    array(1) {
249      [0]=>
250      *RECURSION*
251    }
252  }
253}
254OK
255array(2) {
256  ["a"]=>
257  array(2) {
258    ["b"]=>
259    string(1) "c"
260    ["d"]=>
261    string(1) "e"
262  }
263  ["f"]=>
264  array(1) {
265    ["g"]=>
266    string(1) "h"
267  }
268}
269OK
270object(Obj)#%d (3) {
271  ["a"]=>
272  int(1)
273  [%r"?b"?:protected"?%r]=>
274  int(2)
275  [%r"?c"?:("Obj":)?private"?%r]=>
276  int(3)
277}
278OK
279array(2) {
280  [0]=>
281  object(Obj)#%d (3) {
282    ["a"]=>
283    int(1)
284    [%r"?b"?:protected"?%r]=>
285    int(2)
286    [%r"?c"?:("Obj":)?private"?%r]=>
287    int(3)
288  }
289  [1]=>
290  object(Obj)#%d (3) {
291    ["a"]=>
292    int(4)
293    [%r"?b"?:protected"?%r]=>
294    int(5)
295    [%r"?c"?:("Obj":)?private"?%r]=>
296    int(6)
297  }
298}
299OK
300array(2) {
301  [0]=>
302  &object(Obj)#%d (3) {
303    ["a"]=>
304    int(1)
305    [%r"?b"?:protected"?%r]=>
306    int(2)
307    [%r"?c"?:("Obj":)?private"?%r]=>
308    int(3)
309  }
310  [1]=>
311  &object(Obj)#%d (3) {
312    ["a"]=>
313    int(1)
314    [%r"?b"?:protected"?%r]=>
315    int(2)
316    [%r"?c"?:("Obj":)?private"?%r]=>
317    int(3)
318  }
319}
320OK
321