Annotation of embedaddon/php/ext/spl/tests/bug65328.phpt, revision 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>