1
0
mirror of https://github.com/php/php-src.git synced 2026-04-03 22:22:18 +02:00

Merge branch 'PHP-7.0' of https://github.com/php/php-src into PHP-7.0

This commit is contained in:
Joe Watkins
2016-03-31 12:40:15 +01:00
12 changed files with 160 additions and 89 deletions

10
NEWS
View File

@@ -15,6 +15,7 @@ PHP NEWS
. Fixed bug #62059 (ArrayObject and isset are not friends). (Nikita)
. Fixed bug #71871 (Interfaces allow final and abstract functions). (Nikita)
. Fixed bug #71922 (Crash on assert(new class{})). (Nikita)
. Fixed bug #71334 (Cannot access array keys while uksort()). (Nikita)
- Curl:
. Fixed bug #71831 (CURLOPT_NOPROXY applied as long instead of string).
@@ -32,8 +33,8 @@ PHP NEWS
(Daniel kalaspuffar, Julien)
- Postgres:
. Fixed bug #71820 (pg_fetch_object binds parameters before
call constructor). (Anatol)
. Fixed bug #71820 (pg_fetch_object binds parameters before call
constructor). (Anatol)
- SPL:
. Fixed bug #71838 (Deserializing serialized SPLObjectStorage-Object can't
@@ -116,8 +117,7 @@ PHP NEWS
(steven dot lambeth at gmx dot de, Anatol)
- Phar:
. Fixed bug #71625 (Crash in php7.dll with bad phar filename).
(Anatol)
. Fixed bug #71625 (Crash in php7.dll with bad phar filename). (Anatol)
. Fixed bug #71317 (PharData fails to open specific file). (Jos Elstgeest)
. Fixed bug #71860 (Invalid memory write in phar on filename with \0 in
name). (Stas)
@@ -126,7 +126,7 @@ PHP NEWS
. Fixed crash when advancing (except step) inside an internal function. (Bob)
- Session:
. Fixed Bug #71683 (Null pointer dereference in zend_hash_str_find_bucket).
. Fixed bug #71683 (Null pointer dereference in zend_hash_str_find_bucket).
(Yasuo)
- SNMP:

View File

@@ -0,0 +1,16 @@
--TEST--
Closure::__invoke() is case insensitive
--FILE--
<?php
$inc = function(&$n) {
$n++;
};
$n = 1;
$inc->__INVOKE($n);
var_dump($n);
?>
--EXPECT--
int(2)

View File

@@ -297,14 +297,10 @@ ZEND_API zval* zend_get_closure_this_ptr(zval *obj) /* {{{ */
static zend_function *zend_closure_get_method(zend_object **object, zend_string *method, const zval *key) /* {{{ */
{
zend_string *lc_name;
lc_name = zend_string_tolower(method);
if (zend_string_equals_literal(method, ZEND_INVOKE_FUNC_NAME)) {
zend_string_release(lc_name);
if (zend_string_equals_literal_ci(method, ZEND_INVOKE_FUNC_NAME)) {
return zend_get_closure_invoke_method(*object);
}
zend_string_release(lc_name);
return std_object_handlers.get_method(object, method, key);
}
/* }}} */

View File

@@ -403,7 +403,7 @@ file_check_mem(struct magic_set *ms, unsigned int level)
size_t len;
if (level >= ms->c.len) {
len = (ms->c.len += 20 + level) * sizeof(*ms->c.li);
len = (ms->c.len = 20 + level) * sizeof(*ms->c.li);
ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
emalloc(len) :
erealloc(ms->c.li, len));

View File

@@ -1,11 +1,14 @@
--TEST--
Bug #68996 (Invalid free of CG(interned_empty_string))
--SKIPIF--
<?php
if (getenv("USE_ZEND_ALLOC") !== "0") {
print "skip Need Zend MM disabled";
}
?>
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
--INI--
html_errors=1
--ENV--
USE_ZEND_ALLOC=0
--FILE--
<?php
finfo_open(FILEINFO_MIME_TYPE, "\xfc\x63");

View File

@@ -203,6 +203,7 @@ PHP_FUNCTION(shmop_open)
}
if (shmctl(shmop->shmid, IPC_STAT, &shm)) {
/* please do not add coverage here: the segment would be leaked and impossible to delete via php */
php_error_docref(NULL, E_WARNING, "unable to get shared memory segment information '%s'", strerror(errno));
goto err;
}

View File

@@ -1,33 +0,0 @@
--TEST--
shmop extension error messages (non-root)
--SKIPIF--
<?php
if( substr(PHP_OS, 0, 3) == "WIN") {
die('skip not for Windows');
}
if (!extension_loaded("shmop")) {
die("skip shmop extension not available");
}
if (!extension_loaded("posix")) {
die("skip posix extension not available");
}
if (!posix_geteuid()) {
die("skip cannot run test as root");
}
?>
--FILE--
<?php
$hex_shm_id = function(){
return mt_rand(1338, 9999);
};
echo '## shmop_open function tests ##', PHP_EOL;
// warning outputs: unable to get shared memory segment information
var_dump(shmop_open($hex_shm_id(), 'n', 0, 1024));
?>
--EXPECTF--
## shmop_open function tests ##
Warning: shmop_open(): unable to get shared memory segment information 'Permission denied' in %s on line %d
bool(false)

View File

@@ -82,18 +82,18 @@ static inline spl_array_object *spl_array_from_obj(zend_object *obj) /* {{{ */ {
#define Z_SPLARRAY_P(zv) spl_array_from_obj(Z_OBJ_P((zv)))
static inline HashTable *spl_array_get_hash_table(spl_array_object* intern) { /* {{{ */
static inline HashTable **spl_array_get_hash_table_ptr(spl_array_object* intern) { /* {{{ */
//??? TODO: Delay duplication for arrays; only duplicate for write operations
if (intern->ar_flags & SPL_ARRAY_IS_SELF) {
if (!intern->std.properties) {
rebuild_object_properties(&intern->std);
}
return intern->std.properties;
return &intern->std.properties;
} else if (intern->ar_flags & SPL_ARRAY_USE_OTHER) {
spl_array_object *other = Z_SPLARRAY_P(&intern->array);
return spl_array_get_hash_table(other);
return spl_array_get_hash_table_ptr(other);
} else if (Z_TYPE(intern->array) == IS_ARRAY) {
return Z_ARRVAL(intern->array);
return &Z_ARRVAL(intern->array);
} else {
zend_object *obj = Z_OBJ(intern->array);
if (!obj->properties) {
@@ -104,9 +104,22 @@ static inline HashTable *spl_array_get_hash_table(spl_array_object* intern) { /*
}
obj->properties = zend_array_dup(obj->properties);
}
return obj->properties;
return &obj->properties;
}
} /* }}} */
}
/* }}} */
static inline HashTable *spl_array_get_hash_table(spl_array_object* intern) { /* {{{ */
return *spl_array_get_hash_table_ptr(intern);
}
/* }}} */
static inline void spl_array_replace_hash_table(spl_array_object* intern, HashTable *ht) { /* {{{ */
HashTable **ht_ptr = spl_array_get_hash_table_ptr(intern);
zend_array_destroy(*ht_ptr);
*ht_ptr = ht;
}
/* }}} */
static inline zend_bool spl_array_is_object(spl_array_object *intern) /* {{{ */
{
@@ -1432,16 +1445,12 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
spl_array_object *intern = Z_SPLARRAY_P(getThis());
HashTable *aht = spl_array_get_hash_table(intern);
zval function_name, params[2], *arg = NULL;
uint32_t old_refcount;
ZVAL_STRINGL(&function_name, fname, fname_len);
/* A tricky way to pass "aht" by reference, reset refcount */
//??? It may be not safe, if user comparison handler accesses "aht"
old_refcount = GC_REFCOUNT(aht);
GC_REFCOUNT(aht) = 1;
ZVAL_NEW_EMPTY_REF(&params[0]);
ZVAL_ARR(Z_REFVAL(params[0]), aht);
GC_REFCOUNT(aht)++;
if (!use_arg) {
intern->nApplyCount++;
@@ -1470,10 +1479,16 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
}
exit:
/* A tricky way to pass "aht" by reference, copy back and cleanup */
GC_REFCOUNT(aht) = old_refcount;
efree(Z_REF(params[0]));
zend_string_free(Z_STR(function_name));
{
HashTable *new_ht = Z_ARRVAL_P(Z_REFVAL(params[0]));
if (aht != new_ht) {
spl_array_replace_hash_table(intern, new_ht);
} else {
GC_REFCOUNT(aht)--;
}
efree(Z_REF(params[0]));
zend_string_free(Z_STR(function_name));
}
} /* }}} */
#define SPL_ARRAY_METHOD(cname, fname, use_arg) \

View File

@@ -1035,38 +1035,31 @@ static int php_array_user_compare(const void *a, const void *b) /* {{{ */
static void php_usort(INTERNAL_FUNCTION_PARAMETERS, compare_func_t compare_func, zend_bool renumber) /* {{{ */
{
zval *array;
zend_refcounted *arr;
zend_array *arr;
zend_bool retval;
PHP_ARRAY_CMP_FUNC_VARS;
PHP_ARRAY_CMP_FUNC_BACKUP();
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/f", &array, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "af", &array, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) {
PHP_ARRAY_CMP_FUNC_RESTORE();
return;
}
/* Increase reference counter, so the attempts to modify the array in user
* comparison function will create a copy of array and won't affect the
* original array. The fact of modification is detected by comparing the
* zend_array pointer. The result of sorting in such case is undefined and
* the function returns FALSE.
*/
Z_ADDREF_P(array);
arr = Z_COUNTED_P(array);
retval = zend_hash_sort(Z_ARRVAL_P(array), compare_func, renumber) != FAILURE;
if (arr != Z_COUNTED_P(array)) {
php_error_docref(NULL, E_WARNING, "Array was modified by the user comparison function");
if (--GC_REFCOUNT(arr) <= 0) {
_zval_dtor_func(arr ZEND_FILE_LINE_CC);
}
retval = 0;
} else {
Z_DELREF_P(array);
arr = Z_ARR_P(array);
if (zend_hash_num_elements(arr) == 0) {
PHP_ARRAY_CMP_FUNC_RESTORE();
RETURN_TRUE;
}
/* Copy array, so the in-place modifications will not be visible to the callback function */
arr = zend_array_dup(arr);
retval = zend_hash_sort(arr, compare_func, renumber) != FAILURE;
zval_ptr_dtor(array);
ZVAL_ARR(array, arr);
PHP_ARRAY_CMP_FUNC_RESTORE();
RETURN_BOOL(retval);
}

View File

@@ -0,0 +1,38 @@
--TEST--
Bug #71334: Cannot access array keys while uksort()
--FILE--
<?php
class myClass
{
private $a = [
'foo-test' => [1],
'-' => [2],
'bar-test' => [3]
];
private function _mySort($x, $y)
{
if (!isset($this->a[$x])) {
throw new Exception('Missing X: "' . $x . '"');
}
if (!isset($this->a[$y])) {
throw new Exception('Missing Y: "' . $y . '"');
}
return $x < $y;
}
public function __construct()
{
uksort($this->a, [$this, '_mySort']);
}
}
new myClass();
echo "Done";
?>
--EXPECT--
Done

View File

@@ -4,7 +4,7 @@ Crash when function parameter modified via reference
<?php
function usercompare($a,$b) {
unset($GLOBALS['my_var'][2]);
return 0;
return $a <=> $b;
}
$my_var = array(1 => "entry_1",
2 => "entry_2",
@@ -12,10 +12,19 @@ $my_var = array(1 => "entry_1",
4 => "entry_4",
5 => "entry_5");
usort($my_var, "usercompare");
var_dump($my_var);
echo "Done.\n";
?>
--EXPECTF--
Warning: usort(): Array was modified by the user comparison function in %s on line %d
Done.
--EXPECT--
array(5) {
[0]=>
string(7) "entry_1"
[1]=>
string(7) "entry_2"
[2]=>
string(7) "entry_3"
[3]=>
string(7) "entry_4"
[4]=>
string(7) "entry_5"
}

View File

@@ -0,0 +1,33 @@
--TEST--
Crash when function parameter modified via reference while keeping orig refcount
--FILE--
<?php
$array = array(
1 => "entry_1",
2 => "entry_2",
3 => "entry_3",
4 => "entry_4",
5 => "entry_5"
);
usort($array, function($a, $b) use (&$array, &$ref) {
unset($array[2]);
$ref = $array;
return $a <=> $b;
});
var_dump($array);
?>
--EXPECT--
array(5) {
[0]=>
string(7) "entry_1"
[1]=>
string(7) "entry_2"
[2]=>
string(7) "entry_3"
[3]=>
string(7) "entry_4"
[4]=>
string(7) "entry_5"
}