summaryrefslogtreecommitdiff
path: root/ext/spl
diff options
context:
space:
mode:
Diffstat (limited to 'ext/spl')
-rwxr-xr-xext/spl/spl_array.c31
-rwxr-xr-xext/spl/spl_directory.c12
-rwxr-xr-xext/spl/spl_sxe.c5
-rw-r--r--ext/spl/tests/bug41691.phpt31
-rw-r--r--ext/spl/tests/bug41692.phpt40
-rw-r--r--ext/spl/tests/bug42259.phpt49
-rw-r--r--ext/spl/tests/bug42364.phpt18
7 files changed, 168 insertions, 18 deletions
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 8079088d8..0ba3ff10a 100755
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: spl_array.c,v 1.71.2.17.2.11 2007/04/06 17:57:10 helly Exp $ */
+/* $Id: spl_array.c,v 1.71.2.17.2.13 2007/07/20 10:53:56 tony2001 Exp $ */
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -72,7 +72,7 @@ typedef struct _spl_array_object {
static inline HashTable *spl_array_get_hash_table(spl_array_object* intern, int check_std_props TSRMLS_DC) {
if ((intern->ar_flags & SPL_ARRAY_IS_SELF) != 0) {
return intern->std.properties;
- } else if ((intern->ar_flags & SPL_ARRAY_USE_OTHER) && (check_std_props == 0 || (intern->ar_flags & SPL_ARRAY_STD_PROP_LIST) == 0)) {
+ } else if ((intern->ar_flags & SPL_ARRAY_USE_OTHER) && (check_std_props == 0 || (intern->ar_flags & SPL_ARRAY_STD_PROP_LIST) == 0) && Z_TYPE_P(intern->array) == IS_OBJECT) {
spl_array_object *other = (spl_array_object*)zend_object_store_get_object(intern->array TSRMLS_CC);
return spl_array_get_hash_table(other, check_std_props TSRMLS_CC);
} else if ((intern->ar_flags & ((check_std_props ? SPL_ARRAY_STD_PROP_LIST : 0) | SPL_ARRAY_IS_SELF)) != 0) {
@@ -891,7 +891,7 @@ SPL_METHOD(Array, __construct)
{
zval *object = getThis();
spl_array_object *intern;
- zval *array;
+ zval **array;
long ar_flags = 0;
char *class_name;
int class_name_len;
@@ -904,11 +904,15 @@ SPL_METHOD(Array, __construct)
intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ls", &array, &ar_flags, &class_name, &class_name_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ls", &array, &ar_flags, &class_name, &class_name_len) == FAILURE) {
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
return;
}
+ if (Z_TYPE_PP(array) == IS_ARRAY) {
+ SEPARATE_ZVAL_IF_NOT_REF(array);
+ }
+
if (ZEND_NUM_ARGS() > 2) {
if (zend_lookup_class(class_name, class_name_len, &pce_get_iterator TSRMLS_CC) == FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException, "A class that implements Iterator must be specified", 0 TSRMLS_CC);
@@ -920,25 +924,25 @@ SPL_METHOD(Array, __construct)
ar_flags &= ~SPL_ARRAY_INT_MASK;
- if (Z_TYPE_P(array) == IS_OBJECT && (Z_OBJ_HT_P(array) == &spl_handler_ArrayObject || Z_OBJ_HT_P(array) == &spl_handler_ArrayIterator)) {
+ if (Z_TYPE_PP(array) == IS_OBJECT && (Z_OBJ_HT_PP(array) == &spl_handler_ArrayObject || Z_OBJ_HT_PP(array) == &spl_handler_ArrayIterator)) {
zval_ptr_dtor(&intern->array);
if (ZEND_NUM_ARGS() == 1)
{
- spl_array_object *other = (spl_array_object*)zend_object_store_get_object(array TSRMLS_CC);
+ spl_array_object *other = (spl_array_object*)zend_object_store_get_object(*array TSRMLS_CC);
ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK;
}
ar_flags |= SPL_ARRAY_USE_OTHER;
- intern->array = array;
+ intern->array = *array;
} else {
- if (Z_TYPE_P(array) != IS_OBJECT && Z_TYPE_P(array) != IS_ARRAY) {
+ if (Z_TYPE_PP(array) != IS_OBJECT && Z_TYPE_PP(array) != IS_ARRAY) {
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object, using empty array instead", 0 TSRMLS_CC);
return;
}
zval_ptr_dtor(&intern->array);
- intern->array = array;
+ intern->array = *array;
}
- if (object == array) {
+ if (object == *array) {
intern->ar_flags |= SPL_ARRAY_IS_SELF;
intern->ar_flags &= ~SPL_ARRAY_USE_OTHER;
} else {
@@ -946,12 +950,12 @@ SPL_METHOD(Array, __construct)
}
intern->ar_flags |= ar_flags;
ZVAL_ADDREF(intern->array);
- if (Z_TYPE_P(array) == IS_OBJECT) {
- zend_object_get_properties_t handler = Z_OBJ_HANDLER_P(array, get_properties);
+ if (Z_TYPE_PP(array) == IS_OBJECT) {
+ zend_object_get_properties_t handler = Z_OBJ_HANDLER_PP(array, get_properties);
if ((handler != std_object_handlers.get_properties && handler != spl_array_get_properties)
|| !spl_array_get_hash_table(intern, 0 TSRMLS_CC)) {
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
- zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Overloaded object of type %s is not compatible with %s", Z_OBJCE_P(array)->name, intern->std.ce->name);
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Overloaded object of type %s is not compatible with %s", Z_OBJCE_PP(array)->name, intern->std.ce->name);
return;
}
}
@@ -1052,6 +1056,7 @@ SPL_METHOD(Array, exchangeArray)
}
zval_ptr_dtor(&intern->array);
intern->array = *array;
+ intern->ar_flags &= ~SPL_ARRAY_USE_OTHER;
}
if (object == *array) {
intern->ar_flags |= SPL_ARRAY_IS_SELF;
diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
index 3d8fe6dc2..43f13a534 100755
--- a/ext/spl/spl_directory.c
+++ b/ext/spl/spl_directory.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: spl_directory.c,v 1.45.2.27.2.20 2007/04/09 15:34:55 dmitry Exp $ */
+/* $Id: spl_directory.c,v 1.45.2.27.2.22 2007/08/21 22:45:53 johannes Exp $ */
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -829,7 +829,11 @@ SPL_METHOD(SplFileInfo, getLinkTarget)
php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
+#ifdef HAVE_SYMLINK
ret = readlink(intern->file_name, buff, MAXPATHLEN-1);
+#else
+ ret = -1; /* always fail if not implemented */
+#endif
if (ret == -1) {
zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Unable to read link %s, error: %s", intern->file_name, strerror(errno));
@@ -854,7 +858,11 @@ SPL_METHOD(SplFileInfo, getRealPath)
php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
- if (VCWD_REALPATH(intern->file_name, buff)) {
+ if (intern->type == SPL_FS_DIR && !intern->file_name && intern->u.dir.entry.d_name[0]) {
+ spl_filesystem_object_get_file_name(intern TSRMLS_CC);
+ }
+
+ if (intern->file_name_len && VCWD_REALPATH(intern->file_name, buff)) {
#ifdef ZTS
if (VCWD_ACCESS(buff, F_OK)) {
RETVAL_FALSE;
diff --git a/ext/spl/spl_sxe.c b/ext/spl/spl_sxe.c
index 419ca5b46..b7a5eac99 100755
--- a/ext/spl/spl_sxe.c
+++ b/ext/spl/spl_sxe.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: spl_sxe.c,v 1.8.2.5.2.1 2007/01/01 09:36:07 sebastian Exp $ */
+/* $Id: spl_sxe.c,v 1.8.2.5.2.2 2007/08/14 12:10:46 rrichards Exp $ */
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -142,8 +142,7 @@ SPL_METHOD(SimpleXMLIterator, getChildren)
if (!sxe->iter.data || sxe->iter.type == SXE_ITER_ATTRLIST) {
return; /* return NULL */
}
- return_value->type = IS_OBJECT;
- return_value->value.obj = zend_objects_store_clone_obj(sxe->iter.data TSRMLS_CC);
+ RETURN_ZVAL(sxe->iter.data, 1, 0);
}
/* {{{ proto int SimpleXMLIterator::count()
diff --git a/ext/spl/tests/bug41691.phpt b/ext/spl/tests/bug41691.phpt
new file mode 100644
index 000000000..1527ca3bd
--- /dev/null
+++ b/ext/spl/tests/bug41691.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Bug #41691 (ArrayObject::exchangeArray hangs Apache)
+--SKIPIF--
+<?php if (!extension_loaded("spl")) print "skip"; ?>
+--FILE--
+<?php
+
+class A extends ArrayObject {
+ public function __construct($dummy, $flags) {
+ parent::__construct($this, $flags);
+ }
+ public $a;
+ public $b;
+ public $c;
+}
+
+$a = new A(null, ArrayObject::ARRAY_AS_PROPS );
+var_dump($a->exchangeArray(array('a'=>1,'b'=>1,'c'=>1)));
+
+echo "Done\n";
+?>
+--EXPECTF--
+array(3) {
+ ["a"]=>
+ NULL
+ ["b"]=>
+ NULL
+ ["c"]=>
+ NULL
+}
+Done
diff --git a/ext/spl/tests/bug41692.phpt b/ext/spl/tests/bug41692.phpt
new file mode 100644
index 000000000..8a2b958fc
--- /dev/null
+++ b/ext/spl/tests/bug41692.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #41692 (ArrayObject shows weird behaviour in respect to inheritance)
+--FILE--
+<?php
+
+class Bar extends ArrayObject {
+ private $foo = array( 1, 2, 3 );
+ function __construct()
+ {
+ parent::__construct($this->foo);
+ }
+}
+
+$foo = new Bar();
+var_dump($foo);
+$foo['foo'] = 23;
+
+$bar = new Bar();
+var_dump($bar);
+
+echo "Done\n";
+?>
+--EXPECTF--
+object(Bar)#%d (3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(2)
+ [2]=>
+ int(3)
+}
+object(Bar)#%d (3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(2)
+ [2]=>
+ int(3)
+}
+Done
diff --git a/ext/spl/tests/bug42259.phpt b/ext/spl/tests/bug42259.phpt
new file mode 100644
index 000000000..22c8bc5d6
--- /dev/null
+++ b/ext/spl/tests/bug42259.phpt
@@ -0,0 +1,49 @@
+--TEST--
+Bug #42259 (SimpleXMLIterator loses ancestry)
+--SKIPIF--
+if (!extension_loaded("spl")) print "skip";
+if (!extension_loaded('simplexml')) print 'skip';
+if (!extension_loaded("libxml")) print "skip LibXML not present";
+if (!class_exists('RecursiveIteratorIterator')) print 'skip RecursiveIteratorIterator not available';
+--FILE--
+<?php
+$xml =<<<EOF
+<xml>
+ <fieldset1>
+ <field1/>
+ <field2/>
+ </fieldset1>
+ <fieldset2>
+ <options>
+ <option1/>
+ <option2/>
+ <option3/>
+ </options>
+ <field1/>
+ <field2/>
+ </fieldset2>
+</xml>
+EOF;
+
+$sxe = new SimpleXMLIterator($xml);
+$rit = new RecursiveIteratorIterator($sxe, RecursiveIteratorIterator::LEAVES_ONLY);
+foreach ($rit as $child) {
+ $path = '';
+ $ancestry = $child->xpath('ancestor-or-self::*');
+ foreach ($ancestry as $ancestor) {
+ $path .= $ancestor->getName() . '/';
+ }
+ $path = substr($path, 0, strlen($path) - 1);
+ echo count($ancestry) . ' steps: ' . $path . PHP_EOL;
+}
+?>
+===DONE===
+--EXPECT--
+3 steps: xml/fieldset1/field1
+3 steps: xml/fieldset1/field2
+4 steps: xml/fieldset2/options/option1
+4 steps: xml/fieldset2/options/option2
+4 steps: xml/fieldset2/options/option3
+3 steps: xml/fieldset2/field1
+3 steps: xml/fieldset2/field2
+===DONE===
diff --git a/ext/spl/tests/bug42364.phpt b/ext/spl/tests/bug42364.phpt
new file mode 100644
index 000000000..b218be36a
--- /dev/null
+++ b/ext/spl/tests/bug42364.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #42364 (Crash when using getRealPath with DirectoryIterator)
+--SKIPIF--
+<?php if (!extension_loaded("spl")) print "skip"; ?>
+--FILE--
+<?php
+$it = new DirectoryIterator(dirname(__FILE__));
+
+foreach ($it as $e) {
+ if (gettype($e->getRealPath()) != "string") {
+ echo $e->getFilename(), " is a ", gettype($e->getRealPath()), "\n";
+ }
+}
+
+echo "===DONE==="
+?>
+--EXPECT--
+===DONE===