summaryrefslogtreecommitdiff
path: root/ext/spl
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2014-04-17 11:11:51 +0200
committerOndřej Surý <ondrej@sury.org>2014-04-17 11:11:51 +0200
commit9566c3fcaf4cfaa866ea395ee5d1a480785fef0d (patch)
treed053b8b66afe080ea2250d5fbcdfc21c243d54ab /ext/spl
parent30bdcf2392ef8cc7b8b4a07b49367571ae1db286 (diff)
downloadphp-9566c3fcaf4cfaa866ea395ee5d1a480785fef0d.tar.gz
New upstream version 5.6.0~beta1+dfsgupstream/5.6.0_beta1+dfsg
Diffstat (limited to 'ext/spl')
-rw-r--r--ext/spl/spl_array.c92
-rw-r--r--ext/spl/spl_directory.c27
-rw-r--r--ext/spl/spl_iterators.c3
-rw-r--r--ext/spl/tests/bug64782.phpt2
-rw-r--r--ext/spl/tests/bug65545.phpt28
-rw-r--r--ext/spl/tests/bug66702.phpt40
-rw-r--r--ext/spl/tests/bug66834.phpt163
7 files changed, 315 insertions, 40 deletions
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index f41d0fb9c..0611cfe38 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -593,64 +593,80 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o
{
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
long index;
- zval *rv, **tmp;
+ zval *rv, *value = NULL, **tmp;
if (check_inherited && intern->fptr_offset_has) {
- SEPARATE_ARG_IF_REF(offset);
- zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_has, "offsetExists", &rv, offset);
- zval_ptr_dtor(&offset);
+ zval *offset_tmp = offset;
+ SEPARATE_ARG_IF_REF(offset_tmp);
+ zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_has, "offsetExists", &rv, offset_tmp);
+ zval_ptr_dtor(&offset_tmp);
+
if (rv && zend_is_true(rv)) {
zval_ptr_dtor(&rv);
- return 1;
- }
- if (rv) {
- zval_ptr_dtor(&rv);
+ if (check_empty == 2) {
+ return 1;
+ } else if (intern->fptr_offset_get) {
+ value = spl_array_read_dimension_ex(1, object, offset, BP_VAR_R TSRMLS_CC);
+ }
+ } else {
+ if (rv) {
+ zval_ptr_dtor(&rv);
+ }
+ return 0;
}
- return 0;
}
- switch(Z_TYPE_P(offset)) {
- case IS_STRING:
- {
- HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
+ if (!value) {
+ HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
+
+ switch(Z_TYPE_P(offset)) {
+ case IS_STRING:
if (zend_symtable_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **) &tmp) != FAILURE) {
- switch (check_empty) {
- case 0:
- return Z_TYPE_PP(tmp) != IS_NULL;
- case 2:
- return 1;
- default:
- return zend_is_true(*tmp);
+ if (check_empty == 2) {
+ return 1;
}
+ } else {
+ return 0;
}
- }
- return 0;
- case IS_DOUBLE:
- case IS_RESOURCE:
- case IS_BOOL:
- case IS_LONG:
- {
- HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
+ break;
+ case IS_DOUBLE:
+ case IS_RESOURCE:
+ case IS_BOOL:
+ case IS_LONG:
if (offset->type == IS_DOUBLE) {
index = (long)Z_DVAL_P(offset);
} else {
index = Z_LVAL_P(offset);
}
if (zend_hash_index_find(ht, index, (void **)&tmp) != FAILURE) {
- switch (check_empty) {
- case 0:
- return Z_TYPE_PP(tmp) != IS_NULL;
- case 2:
- return 1;
- default:
- return zend_is_true(*tmp);
+ if (check_empty == 2) {
+ return 1;
}
+ } else {
+ return 0;
}
+ break;
+ default:
+ zend_error(E_WARNING, "Illegal offset type");
return 0;
- }
- default:
- zend_error(E_WARNING, "Illegal offset type");
+ }
+
+ if (check_inherited && intern->fptr_offset_get) {
+ value = spl_array_read_dimension_ex(1, object, offset, BP_VAR_R TSRMLS_CC);
+ } else {
+ value = *tmp;
+ }
+ }
+
+ switch (check_empty) {
+ case 0:
+ return Z_TYPE_P(value) != IS_NULL;
+ case 2:
+ return 1;
+ case 1:
+ return zend_is_true(value);
}
+
return 0;
} /* }}} */
diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
index 5f32feaaf..03315b7bb 100644
--- a/ext/spl/spl_directory.c
+++ b/ext/spl/spl_directory.c
@@ -2848,6 +2848,28 @@ SPL_METHOD(SplFileObject, fwrite)
RETURN_LONG(php_stream_write(intern->u.file.stream, str, str_len));
} /* }}} */
+SPL_METHOD(SplFileObject, fread)
+{
+ spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+ long length = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE) {
+ return;
+ }
+
+ if (length <= 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
+ RETURN_FALSE;
+ }
+
+ Z_STRVAL_P(return_value) = emalloc(length + 1);
+ Z_STRLEN_P(return_value) = php_stream_read(intern->u.file.stream, Z_STRVAL_P(return_value), length);
+
+ /* needed because recv/read/gzread doesnt put a null at the end*/
+ Z_STRVAL_P(return_value)[Z_STRLEN_P(return_value)] = 0;
+ Z_TYPE_P(return_value) = IS_STRING;
+}
+
/* {{{ proto bool SplFileObject::fstat()
Stat() on a filehandle */
FileFunction(fstat)
@@ -2948,6 +2970,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fwrite, 0, 0, 1)
ZEND_ARG_INFO(0, length)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fread, 0, 0, 1)
+ ZEND_ARG_INFO(0, length)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_ftruncate, 0, 0, 1)
ZEND_ARG_INFO(0, size)
ZEND_END_ARG_INFO()
@@ -2975,6 +3001,7 @@ static const zend_function_entry spl_SplFileObject_functions[] = {
SPL_ME(SplFileObject, fgetss, arginfo_file_object_fgetss, ZEND_ACC_PUBLIC)
SPL_ME(SplFileObject, fscanf, arginfo_file_object_fscanf, ZEND_ACC_PUBLIC)
SPL_ME(SplFileObject, fwrite, arginfo_file_object_fwrite, ZEND_ACC_PUBLIC)
+ SPL_ME(SplFileObject, fread, arginfo_file_object_fread, ZEND_ACC_PUBLIC)
SPL_ME(SplFileObject, fstat, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
SPL_ME(SplFileObject, ftruncate, arginfo_file_object_ftruncate, ZEND_ACC_PUBLIC)
SPL_ME(SplFileObject, current, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c
index a89fd548c..679fc85af 100644
--- a/ext/spl/spl_iterators.c
+++ b/ext/spl/spl_iterators.c
@@ -2055,7 +2055,7 @@ SPL_METHOD(RegexIterator, accept)
}
if (intern->u.regex.flags & REGIT_INVERTED) {
- RETVAL_BOOL(Z_LVAL_P(return_value));
+ RETVAL_BOOL(! Z_LVAL_P(return_value));
}
if (use_copy) {
@@ -3692,6 +3692,7 @@ PHP_MINIT_FUNCTION(spl_iterators)
#if HAVE_PCRE || HAVE_BUNDLED_PCRE
REGISTER_SPL_SUB_CLASS_EX(RegexIterator, FilterIterator, spl_dual_it_new, spl_funcs_RegexIterator);
REGISTER_SPL_CLASS_CONST_LONG(RegexIterator, "USE_KEY", REGIT_USE_KEY);
+ REGISTER_SPL_CLASS_CONST_LONG(RegexIterator, "INVERT_MATCH",REGIT_INVERTED);
REGISTER_SPL_CLASS_CONST_LONG(RegexIterator, "MATCH", REGIT_MODE_MATCH);
REGISTER_SPL_CLASS_CONST_LONG(RegexIterator, "GET_MATCH", REGIT_MODE_GET_MATCH);
REGISTER_SPL_CLASS_CONST_LONG(RegexIterator, "ALL_MATCHES", REGIT_MODE_ALL_MATCHES);
diff --git a/ext/spl/tests/bug64782.phpt b/ext/spl/tests/bug64782.phpt
index ac5d08d7d..ffe8a30b2 100644
--- a/ext/spl/tests/bug64782.phpt
+++ b/ext/spl/tests/bug64782.phpt
@@ -9,7 +9,7 @@ var_dump(new SplFileObject(__FILE__, "r", false, null));
--EXPECTF--
object(SplFileObject)#1 (%d) {
["pathName":"SplFileInfo":private]=>
- string(%d) "%s/bug64782.php"
+ string(%d) "%sbug64782.php"
["fileName":"SplFileInfo":private]=>
string(12) "bug64782.php"
["openMode":"SplFileObject":private]=>
diff --git a/ext/spl/tests/bug65545.phpt b/ext/spl/tests/bug65545.phpt
new file mode 100644
index 000000000..76c29cbf4
--- /dev/null
+++ b/ext/spl/tests/bug65545.phpt
@@ -0,0 +1,28 @@
+--TEST--
+SplFileObject::fread function
+--FILE--
+<?php
+$obj = new SplFileObject(__FILE__, 'r');
+$data = $obj->fread(5);
+var_dump($data);
+
+$data = $obj->fread();
+var_dump($data);
+
+$data = $obj->fread(0);
+var_dump($data);
+
+// read more data than is available
+$data = $obj->fread(filesize(__FILE__) + 32);
+var_dump(strlen($data) === filesize(__FILE__) - 5);
+
+?>
+--EXPECTF--
+string(5) "<?php"
+
+Warning: SplFileObject::fread() expects exactly 1 parameter, 0 given in %s on line %d
+NULL
+
+Warning: SplFileObject::fread(): Length parameter must be greater than 0 in %s on line %d
+bool(false)
+bool(true)
diff --git a/ext/spl/tests/bug66702.phpt b/ext/spl/tests/bug66702.phpt
new file mode 100644
index 000000000..fedfc869a
--- /dev/null
+++ b/ext/spl/tests/bug66702.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #66702 (RegexIterator inverted result works as expected)
+--FILE--
+<?php
+/**
+ * @author Joshua Thijssen <jthijssen+php@noxlogic.nl>
+ */
+
+$it = new \ArrayIterator(array("foo", "bar", "baz"));
+$it2 = new \RegexIterator($it, "/^ba/", \RegexIterator::MATCH);
+print_r(iterator_to_array($it2));
+$it2 = new \RegexIterator($it, "/^ba/", \RegexIterator::MATCH, \RegexIterator::INVERT_MATCH);
+print_r(iterator_to_array($it2));
+
+$it = new \ArrayIterator(array("foo" => 1, "bar" => 2, "baz" => 3));
+$it2 = new \RegexIterator($it, "/^ba/", \RegexIterator::MATCH, \RegexIterator::USE_KEY);
+print_r(iterator_to_array($it2));
+$it2 = new \RegexIterator($it, "/^ba/", \RegexIterator::MATCH, \RegexIterator::USE_KEY | \RegexIterator::INVERT_MATCH);
+print_r(iterator_to_array($it2));
+
+--EXPECTF--
+Array
+(
+ [1] => bar
+ [2] => baz
+)
+Array
+(
+ [0] => foo
+)
+Array
+(
+ [bar] => 2
+ [baz] => 3
+)
+Array
+(
+ [foo] => 1
+)
+
diff --git a/ext/spl/tests/bug66834.phpt b/ext/spl/tests/bug66834.phpt
new file mode 100644
index 000000000..6d944b274
--- /dev/null
+++ b/ext/spl/tests/bug66834.phpt
@@ -0,0 +1,163 @@
+--TEST--
+SPL: Bug #66834
+--FILE--
+<?php
+
+// overrides both offsetExists and offsetGet
+class ArrayObjectBoth extends ArrayObject
+{
+ public function offsetExists($offset) {
+ var_dump('Called: '.__METHOD__);
+ return parent::offsetExists($offset);
+ }
+
+ public function offsetGet($offset) {
+ var_dump('Called: '.__METHOD__);
+ return parent::offsetGet($offset);
+ }
+}
+
+// overrides only offsetExists
+class ArrayObjectExists extends ArrayObject
+{
+ public function offsetExists($offset) {
+ var_dump('Called: '.__METHOD__);
+ return parent::offsetExists($offset);
+ }
+}
+
+// overrides only offsetGet
+class ArrayObjectGet extends ArrayObject
+{
+ public function offsetGet($offset) {
+ var_dump('Called: '.__METHOD__);
+ return parent::offsetGet($offset);
+ }
+}
+
+// overrides only offsetGet and offsetSet
+class ArrayObjectGetSet extends ArrayObject
+{
+ public function offsetGet($offset)
+ {
+ return parent::offsetGet(str_rot13($offset));
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ return parent::offsetSet(str_rot13($offset), $value);
+ }
+}
+
+$values = ['foo' => '', 'bar' => null, 'baz' => 42];
+
+echo "==== class with offsetExists() and offsetGet() ====\n";
+$object = new ArrayObjectBoth($values);
+var_dump($object->offsetExists('foo'), isset($object['foo']), empty($object['foo']));
+var_dump($object->offsetExists('bar'), isset($object['bar']), empty($object['bar']));
+var_dump($object->offsetexists('baz'), isset($object['baz']), empty($object['baz']));
+var_dump($object->offsetexists('qux'), isset($object['qux']), empty($object['qux']));
+
+echo "==== class with offsetExists() ====\n";
+$object = new ArrayObjectExists($values);
+var_dump($object->offsetExists('foo'), isset($object['foo']), empty($object['foo']));
+var_dump($object->offsetExists('bar'), isset($object['bar']), empty($object['bar']));
+var_dump($object->offsetexists('baz'), isset($object['baz']), empty($object['baz']));
+var_dump($object->offsetexists('qux'), isset($object['qux']), empty($object['qux']));
+
+echo "==== class with offsetGet() ====\n";
+$object = new ArrayObjectGet($values);
+var_dump($object->offsetExists('foo'), isset($object['foo']), empty($object['foo']));
+var_dump($object->offsetExists('bar'), isset($object['bar']), empty($object['bar']));
+var_dump($object->offsetexists('baz'), isset($object['baz']), empty($object['baz']));
+var_dump($object->offsetexists('qux'), isset($object['qux']), empty($object['qux']));
+
+echo "==== class with offsetGet() and offsetSet() ====\n";
+$object = new ArrayObjectGetSet;
+$object['foo'] = 42;
+var_dump($object->offsetExists('foo'), $object->offsetExists('sbb'), isset($object['foo']), isset($object['sbb']));
+
+?>
+--EXPECTF--
+==== class with offsetExists() and offsetGet() ====
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(34) "Called: ArrayObjectBoth::offsetGet"
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(34) "Called: ArrayObjectBoth::offsetGet"
+bool(true)
+bool(true)
+bool(true)
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(34) "Called: ArrayObjectBoth::offsetGet"
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(34) "Called: ArrayObjectBoth::offsetGet"
+bool(true)
+bool(false)
+bool(true)
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(34) "Called: ArrayObjectBoth::offsetGet"
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(34) "Called: ArrayObjectBoth::offsetGet"
+bool(true)
+bool(true)
+bool(false)
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(37) "Called: ArrayObjectBoth::offsetExists"
+string(37) "Called: ArrayObjectBoth::offsetExists"
+bool(false)
+bool(false)
+bool(true)
+==== class with offsetExists() ====
+string(39) "Called: ArrayObjectExists::offsetExists"
+string(39) "Called: ArrayObjectExists::offsetExists"
+string(39) "Called: ArrayObjectExists::offsetExists"
+bool(true)
+bool(true)
+bool(true)
+string(39) "Called: ArrayObjectExists::offsetExists"
+string(39) "Called: ArrayObjectExists::offsetExists"
+string(39) "Called: ArrayObjectExists::offsetExists"
+bool(true)
+bool(false)
+bool(true)
+string(39) "Called: ArrayObjectExists::offsetExists"
+string(39) "Called: ArrayObjectExists::offsetExists"
+string(39) "Called: ArrayObjectExists::offsetExists"
+bool(true)
+bool(true)
+bool(false)
+string(39) "Called: ArrayObjectExists::offsetExists"
+string(39) "Called: ArrayObjectExists::offsetExists"
+string(39) "Called: ArrayObjectExists::offsetExists"
+bool(false)
+bool(false)
+bool(true)
+==== class with offsetGet() ====
+string(33) "Called: ArrayObjectGet::offsetGet"
+string(33) "Called: ArrayObjectGet::offsetGet"
+bool(true)
+bool(true)
+bool(true)
+string(33) "Called: ArrayObjectGet::offsetGet"
+string(33) "Called: ArrayObjectGet::offsetGet"
+bool(true)
+bool(false)
+bool(true)
+string(33) "Called: ArrayObjectGet::offsetGet"
+string(33) "Called: ArrayObjectGet::offsetGet"
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+bool(true)
+==== class with offsetGet() and offsetSet() ====
+
+Notice: Undefined index: foo in %s on line %d
+bool(false)
+bool(true)
+bool(false)
+bool(false)