Skip to content

Commit

Permalink
Merge pull request #1 from php/master
Browse files Browse the repository at this point in the history
Merging upstream
  • Loading branch information
EvgeniySpinov committed Jun 28, 2015
2 parents a2c461d + b811885 commit 2edf296
Show file tree
Hide file tree
Showing 42 changed files with 646 additions and 122 deletions.
15 changes: 13 additions & 2 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
PHP NEWS
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
09 Jul 2015, PHP 7.0.0 Beta 1

- Core:
. Fixed bug #69768 (escapeshell*() doesn't cater to !). (cmb)

- CLI server:
. Fixed bug #69655 (php -S changes MKCALENDAR request method to MKCOL). (cmb)
. Fixed bug #64878 (304 responses return Content-Type header). (cmb)

- COM:
. Fixed bug #69939 (Casting object to bool returns false). (Kalle)

- PCRE:
. Fixed Bug #53823 (preg_replace: * qualifier on unicode replace garbles the
. Fixed bug #53823 (preg_replace: * qualifier on unicode replace garbles the
string). (cmb)

- OpenSSL:
. Fixed bug #69882 (OpenSSL error "key values mismatch" after
openssl_pkcs12_read with extra cert) (Tomasz Sawicki)

25 Jun 2015, PHP 7.0.0 Alpha 2

- Core:
Expand Down
2 changes: 1 addition & 1 deletion README.RELEASE_PROCESS
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ to upgrade.

8. Commit all the changes to their respective git repos

9. Please note down the md5, sha245 and the PGP signature (.asc). These *must* be
9. Please note down the sha256 and the PGP signature (.asc). These *must* be
included in the release mail.
10. Wait an hour or two, then send a mail to php-announce@lists.php.net,
php-general@lists.php.net and internals@lists.php.net with a text similar to
Expand Down
5 changes: 5 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,11 @@ Other
hardcoded value of 16. This limit is now removed and the number of pipes is
effectively limited by the amount of memory available to PHP.

- array_column():
The function now supports an array of objects as well as two-dimensional
arrays. Only public properties are considered, and objects that make use of
__get() for dynamic properties must also implement __isset().

========================================
6. New Functions
========================================
Expand Down
File renamed without changes.
21 changes: 0 additions & 21 deletions Zend/tests/call_static_005.phpt

This file was deleted.

14 changes: 14 additions & 0 deletions Zend/tests/closure_call_leak_with_exception.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
Closure must not leak during a dynamic call interrupted by an exception
--FILE--
<?php

(function() {
$closure = function($foo) { var_dump($foo); };
$closure(yield);
})()->valid(); // start

?>
==DONE==
--EXPECT--
==DONE==
27 changes: 27 additions & 0 deletions Zend/tests/indirect_call_from_constant.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--TEST--
Indirect call with constants.
--FILE--
<?php

class Test
{
public static function method()
{
echo "Method called!\n";
}
}

['Test', 'method']();

'Test::method'();

(['Test', 'method'])();

('Test::method')();

?>
--EXPECT--
Method called!
Method called!
Method called!
Method called!
45 changes: 45 additions & 0 deletions Zend/tests/indirect_call_string_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
--TEST--
Indirect call with 'Class::method' syntax with class in namespace
--FILE--
<?php
namespace TestNamespace
{
class TestClass
{
public static function staticMethod()
{
echo "Static method called!\n";
}

public static function staticMethodWithArgs($arg1, $arg2, $arg3)
{
printf("Static method called with args: %s, %s, %s\n", $arg1, $arg2, $arg3);
}
}
}

namespace CallNamespace
{
// Test basic call using Class::method syntax.
$callback = 'TestNamespace\TestClass::staticMethod';
$callback();

// Case should not matter.
$callback = 'testnamespace\testclass::staticmethod';
$callback();

$args = ['arg1', 'arg2', 'arg3'];
$callback = 'TestNamespace\TestClass::staticMethodWithArgs';

// Test call with args.
$callback($args[0], $args[1], $args[2]);

// Test call with splat operator.
$callback(...$args);
}
?>
--EXPECT--
Static method called!
Static method called!
Static method called with args: arg1, arg2, arg3
Static method called with args: arg1, arg2, arg3
86 changes: 86 additions & 0 deletions Zend/tests/indirect_call_string_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
--TEST--
Indirect call with empty class and/or method name.
--FILE--
<?php
class TestClass
{
public static function __callStatic($method, array $args)
{
var_dump($method);
}
}

// Test call using array syntax
$callback = ['TestClass', ''];
$callback();

// Test call using Class::method syntax.
$callback = 'TestClass::';
$callback();

// Test array syntax with empty class name
$callback = ['', 'method'];
try {
$callback();
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

// Test Class::method syntax with empty class name
$callback = '::method';
try {
$callback();
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

// Test array syntax with empty class and method name
$callback = ['', ''];
try {
$callback();
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

// Test Class::method syntax with empty class and method name
$callback = '::';
try {
$callback();
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

// Test string ending in single colon
$callback = 'Class:';
try {
$callback();
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

// Test string beginning in single colon
$callback = ':method';
try {
$callback();
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

// Test single colon
$callback = ':';
try {
$callback();
} catch (Error $e) {
echo $e->getMessage() . "\n";
}
?>
--EXPECT--
string(0) ""
string(0) ""
Class '' not found
Class '' not found
Class '' not found
Class '' not found
Call to undefined function Class:()
Call to undefined function :method()
Call to undefined function :()
2 changes: 1 addition & 1 deletion Zend/zend_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ ZEND_API size_t ZEND_FASTCALL _zend_mem_block_size(void *ptr ZEND_FILE_LINE_DC Z
#include "zend_alloc_sizes.h"

/* _emalloc() & _efree() specialization */
#if !ZEND_DEBUG && !defined(_WIN32)
#if !ZEND_DEBUG && defined(HAVE_BUILTIN_CONSTANT_P)

# define _ZEND_BIN_ALLOCATOR_DEF(_num, _size, _elements, _pages, x, y) \
ZEND_API void* ZEND_FASTCALL _emalloc_ ## _size(void) ZEND_ATTRIBUTE_MALLOC;
Expand Down
26 changes: 20 additions & 6 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -2866,16 +2866,30 @@ void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_a
{
zend_op *opline = get_next_op(CG(active_op_array));
if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) {
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
Z_STR(name_node->u.constant));
zend_alloc_cache_slot(opline->op2.constant);
const char *colon;
zend_string *str = Z_STR(name_node->u.constant);
if ((colon = zend_memrchr(str->val, ':', str->len)) != NULL && colon > str->val && *(colon - 1) == ':') {
zend_string *class = zend_string_init(str->val, colon - str->val - 1, 0);
zend_string *method = zend_string_init(colon + 1, str->len - (colon - str->val) - 1, 0);
opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
opline->op1_type = IS_CONST;
opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), class);
opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), method);
zend_alloc_cache_slot(opline->op2.constant);
zval_ptr_dtor(&name_node->u.constant);
} else {
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
SET_UNUSED(opline->op1);
opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), str);
zend_alloc_cache_slot(opline->op2.constant);
}
} else {
opline->opcode = ZEND_INIT_DYNAMIC_CALL;
SET_UNUSED(opline->op1);
SET_NODE(opline->op2, name_node);
}
SET_UNUSED(opline->op1);

zend_compile_call_common(result, args_ast, NULL);
}
Expand Down
3 changes: 3 additions & 0 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -2486,6 +2486,9 @@ static zend_always_inline void i_cleanup_unfinished_execution(zend_execute_data
}
OBJ_RELEASE(Z_OBJ(call->This));
}
if (call->func->common.fn_flags & ZEND_ACC_CLOSURE) {
zend_object_release((zend_object *) call->func->common.prototype);
}
if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
zend_string_release(call->func->common.function_name);
zend_free_trampoline(call->func);
Expand Down
8 changes: 4 additions & 4 deletions Zend/zend_execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
{
zend_refcounted *ref = NULL;

if ((value_type & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
if (ZEND_CONST_COND(value_type & (IS_VAR|IS_CV), 1) && Z_ISREF_P(value)) {
ref = Z_COUNTED_P(value);
value = Z_REFVAL_P(value);
}
Expand All @@ -78,7 +78,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value);
return variable_ptr;
}
if ((value_type & (IS_VAR|IS_CV)) && variable_ptr == value) {
if (ZEND_CONST_COND(value_type & (IS_VAR|IS_CV), 1) && variable_ptr == value) {
return variable_ptr;
}
garbage = Z_COUNTED_P(variable_ptr);
Expand All @@ -93,7 +93,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) {
Z_ADDREF_P(variable_ptr);
}
} else if (/* value_type == IS_VAR && */ UNEXPECTED(ref)) {
} else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) {
if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) {
efree_size(ref, sizeof(zend_reference));
} else if (Z_OPT_REFCOUNTED_P(variable_ptr)) {
Expand Down Expand Up @@ -122,7 +122,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) {
Z_ADDREF_P(variable_ptr);
}
} else if (/* value_type == IS_VAR && */ UNEXPECTED(ref)) {
} else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) {
if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) {
efree_size(ref, sizeof(zend_reference));
} else if (Z_OPT_REFCOUNTED_P(variable_ptr)) {
Expand Down
12 changes: 12 additions & 0 deletions Zend/zend_portability.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,18 @@ char *alloca();
# define HAVE_ATTRIBUTE_WEAK
#endif

#if ZEND_GCC_VERSION >= 3001 || __has_builtin(__builtin_constant_p)
# define HAVE_BUILTIN_CONSTANT_P
#endif

#ifdef HAVE_BUILTIN_CONSTANT_P
# define ZEND_CONST_COND(_condition, _default) \
(__builtin_constant_p(_condition) ? (_condition) : (_default))
#else
# define ZEND_CONST_COND(_condition, _default) \
(_default)
#endif

#if ZEND_DEBUG
# define zend_always_inline inline
# define zend_never_inline
Expand Down
6 changes: 0 additions & 6 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -3237,12 +3237,6 @@ ZEND_VM_C_LABEL(try_function_name):
size_t cname_length = colon - Z_STRVAL_P(function_name) - 1;
size_t mname_length = Z_STRLEN_P(function_name) - cname_length - (sizeof("::") - 1);

if (!mname_length) {
zend_error(E_EXCEPTION | E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
FREE_OP2();
HANDLE_EXCEPTION();
}

lcname = zend_string_init(Z_STRVAL_P(function_name), cname_length, 0);

called_scope = zend_fetch_class_by_name(lcname, NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
Expand Down
Loading

0 comments on commit 2edf296

Please sign in to comment.