Annotation of embedaddon/php/ext/spl/tests/bug65328.phpt, revision 1.1.1.1
1.1 misho 1: --TEST--
2: Bug #65328 (Segfault when getting SplStack object Value)
3: --FILE--
4: <?php
5: /**
6: * @author AlexanderC
7: */
8:
9: class Tree
10: {
11: /**
12: * @var Node
13: */
14: protected $head;
15:
16: /**
17: * @param Node $head
18: */
19: public function __construct(Node $head = null)
20: {
21: $this->head = $head ? : new Node('HEAD');
22: }
23:
24: /**
25: * @return Node
26: */
27: public function getHead()
28: {
29: return $this->head;
30: }
31:
32: /**
33: * @param mixed $uid
34: * @return Node|bool
35: */
36: public function find($uid)
37: {
38: $iterator = $this->getIterator();
39:
40: /** @var Node $node */
41: foreach($iterator as $node) {
42: if($node->getUid() === $uid) {
43: return $node;
44: }
45: }
46:
47: return false;
48: }
49:
50: /**
51: * @param mixed $uid
52: * @return \SplStack
53: */
54: public function & findAll($uid)
55: {
56: $result = new \SplStack();
57:
58: /** @var Node $node */
59: foreach($this->getIterator() as $node) {
60: if($node->getUid() == $uid) {
61: $result->push($node);
62: }
63: }
64:
65: return $result;
66: }
67:
68: /**
69: * @return \RecursiveIteratorIterator
70: */
71: public function getIterator()
72: {
73: return new \RecursiveIteratorIterator(
74: $this->head->getChildren(),
75: \RecursiveIteratorIterator::SELF_FIRST
76: );
77: }
78: }
79:
80: class Node extends \RecursiveArrayIterator implements \Countable
81: {
82: /**
83: * @var array
84: */
85: protected $children = [];
86:
87: /**
88: * @var Node
89: */
90: protected $parent;
91:
92: /**
93: * @var mixed
94: */
95: protected $data;
96:
97: /**
98: * @var mixed
99: */
100: protected $uid;
101:
102: /**
103: * @var int
104: */
105: protected $index = 0;
106:
107: /**
108: * @var bool
109: */
110: protected $assureUnique;
111:
112: /**
113: * @param mixed $data
114: * @param mixed $uid
115: * @param Node $parent
116: * @param bool $assureUnique
117: */
118: public function __construct($data, $uid = null, Node $parent = null, $assureUnique = false)
119: {
120: if(null !== $parent) {
121: $this->parent = $parent;
122: }
123:
124: $this->data = $data;
125: $this->uid = $uid ? : uniqid(sha1(serialize($data)), true);
126: $this->assureUnique = $assureUnique;
127: }
128:
129: /**
130: * @param mixed $uid
131: */
132: public function setUid($uid)
133: {
134: $this->uid = $uid;
135: }
136:
137: /**
138: * @return mixed
139: */
140: public function getUid()
141: {
142: return $this->uid;
143: }
144:
145: /**
146: * @param Node $child
147: */
148: public function addChild(Node $child)
149: {
150: $child->setParent($this);
151: $this->children[] = $child;
152: }
153:
154: /**
155: * @param array $children
156: */
157: public function setChildren(array $children)
158: {
159: $this->children = $children;
160: }
161:
162: /**
163: * @return array
164: */
165: public function getChildrenArray()
166: {
167: return $this->children;
168: }
169:
170: /**
171: * @param mixed $data
172: */
173: public function setData($data)
174: {
175: $this->data = $data;
176: }
177:
178: /**
179: * @return mixed
180: */
181: public function getData()
182: {
183: return $this->data;
184: }
185:
186: /**
187: * @param Node $parent
188: * @throws \RuntimeException
189: */
190: public function setParent(Node $parent)
191: {
192: if(true === $this->assureUnique && !self::checkUnique($parent, $this->uid)) {
193: throw new \RuntimeException("Node uid is not unique in assigned node tree");
194: }
195:
196: $this->parent = $parent;
197: }
198:
199: /**
200: * @param Node $node
201: * @param mixed $uid
202: * @return bool
203: */
204: protected static function checkUnique(Node $node, $uid)
205: {
206: $headNode = $node;
207: do {
208: $headNode = $node;
209: } while($node = $node->getParent());
210:
211: $tree = new Tree($headNode);
212:
213: return !$tree->find($uid);
214: }
215:
216: /**
217: * @return \IJsonRPC\Helpers\Tree\Node
218: */
219: public function getParent()
220: {
221: return $this->parent;
222: }
223:
224: /**
225: * @return Node
226: */
227: public function current()
228: {
229: return $this->children[$this->index];
230: }
231:
232: /**
233: * @return scalar
234: */
235: public function key()
236: {
237: return $this->index;
238: }
239:
240: /**
241: * @return void
242: */
243: public function next()
244: {
245: ++$this->index;
246: }
247:
248: /**
249: * @return void
250: */
251: public function rewind()
252: {
253: $this->index = 0;
254: }
255:
256: /**
257: * @return bool
258: */
259: public function valid()
260: {
261: return array_key_exists($this->index, $this->children);
262: }
263:
264: /**
265: * @return int
266: */
267: public function count()
268: {
269: return count($this->children);
270: }
271:
272: /**
273: * @return bool
274: */
275: public function hasChildren()
276: {
277: return !empty($this->children);
278: }
279:
280: /**
281: * @return \RecursiveArrayIterator
282: */
283: public function getChildren()
284: {
285: return new \RecursiveArrayIterator($this->children);
286: }
287: }
288:
289: $tree = new Tree();
290: $node1 = new Node('value1', 1);
291: $tree->getHead()->addChild($node1);
292: $node2 = new Node('value2', 2);
293: $node1->addChild($node2);
294:
295: print_r($tree->findAll(2)->offsetGet(0));
296: --EXPECTF--
297: Node Object
298: (
299: [children:protected] => Array
300: (
301: )
302:
303: [parent:protected] => Node Object
304: (
305: [children:protected] => Array
306: (
307: [0] => Node Object
308: *RECURSION*
309: )
310:
311: [parent:protected] => Node Object
312: (
313: [children:protected] => Array
314: (
315: [0] => Node Object
316: *RECURSION*
317: )
318:
319: [parent:protected] =>
320: [data:protected] => HEAD
321: [uid:protected] => %s
322: [index:protected] => 0
323: [assureUnique:protected] =>
324: [storage:ArrayIterator:private] => Array
325: (
326: )
327:
328: )
329:
330: [data:protected] => value1
331: [uid:protected] => 1
332: [index:protected] => 1
333: [assureUnique:protected] =>
334: [storage:ArrayIterator:private] => Array
335: (
336: )
337:
338: )
339:
340: [data:protected] => value2
341: [uid:protected] => 2
342: [index:protected] => 0
343: [assureUnique:protected] =>
344: [storage:ArrayIterator:private] => Array
345: (
346: )
347:
348: )
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>