diff options
| author | Ondřej Surý <ondrej@sury.org> | 2014-04-17 11:11:51 +0200 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2014-04-17 11:11:51 +0200 |
| commit | 9566c3fcaf4cfaa866ea395ee5d1a480785fef0d (patch) | |
| tree | d053b8b66afe080ea2250d5fbcdfc21c243d54ab /ext/spl | |
| parent | 30bdcf2392ef8cc7b8b4a07b49367571ae1db286 (diff) | |
| download | php-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.c | 92 | ||||
| -rw-r--r-- | ext/spl/spl_directory.c | 27 | ||||
| -rw-r--r-- | ext/spl/spl_iterators.c | 3 | ||||
| -rw-r--r-- | ext/spl/tests/bug64782.phpt | 2 | ||||
| -rw-r--r-- | ext/spl/tests/bug65545.phpt | 28 | ||||
| -rw-r--r-- | ext/spl/tests/bug66702.phpt | 40 | ||||
| -rw-r--r-- | ext/spl/tests/bug66834.phpt | 163 |
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) |
