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