Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ PHP NEWS
(ilutov)
. Prohibit pipe & arrow function combination that leads to confusing parse
trees. (ilutov)
. The disable_classes INI directive has been removed. (Girgias)
. The locally predefined variable $http_response_header is deprecated.
(Girgias)

- Filter:
. Added support for configuring the URI parser for FILTER_VALIDATE_URL
Expand Down
18 changes: 12 additions & 6 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ PHP 8.5 UPGRADE NOTES
1. Backward Incompatible Changes
========================================

- BZ2:
. bzcompress() now throws a ValueError when $block_size is not between
1 and 9.
. bzcompress() now throws a ValueError when $work_factor is not between
0 and 250.

- Core:
. It is no longer possible to use "array" and "callable" as class alias names
in class_alias().
Expand Down Expand Up @@ -55,6 +49,15 @@ PHP 8.5 UPGRADE NOTES
ReflectionAttribute::newInstance() was called an error would be thrown.
The error can be delayed from compilation to runtime using the new
#[\DelayedTargetValidation] attribute.
. The disable_classes INI setting has been removed as it causes various
engine assumptions to be broken.
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#remove_disable_classes_ini_setting

- BZ2:
. bzcompress() now throws a ValueError when $block_size is not between
1 and 9.
. bzcompress() now throws a ValueError when $work_factor is not between
0 and 250.

- DOM:
. Cloning a DOMNamedNodeMap, DOMNodeList, Dom\NamedNodeMap, Dom\NodeList,
Expand Down Expand Up @@ -461,6 +464,9 @@ PHP 8.5 UPGRADE NOTES
. Passing integers outside the interval [0, 255] to chr() is now deprecated.
This is because a byte can only hold a value within this interval.
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_integers_outside_the_interval_0_255_to_chr
. Relying locally predefined variable $http_response_header is deprecated.
Instead one should call the http_get_last_response_headers() function.
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable

- XML:
. The xml_parser_free() function has been deprecated, as XMLParser objects
Expand Down
23 changes: 0 additions & 23 deletions Zend/tests/bug77494.phpt

This file was deleted.

27 changes: 27 additions & 0 deletions Zend/tests/disable_classes_warning.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--TEST--
Check that warning is emitted when disabling classes
--INI--
disable_classes=Exception
--FILE--
<?php
$o = new Exception();
var_dump($o);
?>
--EXPECTF--
object(Exception)#1 (7) {
["message":protected]=>
string(0) ""
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(0)
["file":protected]=>
string(%d) "%s"
["line":protected]=>
int(2)
["trace":"Exception":private]=>
array(0) {
}
["previous":"Exception":private]=>
NULL
}
17 changes: 0 additions & 17 deletions Zend/tests/errmsg/errmsg_021.phpt

This file was deleted.

71 changes: 0 additions & 71 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -3692,77 +3692,6 @@ ZEND_API void zend_disable_functions(const char *function_list) /* {{{ */
}
/* }}} */

#ifdef ZEND_WIN32
#pragma optimize("", off)
#endif
static ZEND_COLD zend_object *display_disabled_class(zend_class_entry *class_type) /* {{{ */
{
zend_object *intern;

intern = zend_objects_new(class_type);

/* Initialize default properties */
if (EXPECTED(class_type->default_properties_count != 0)) {
zval *p = intern->properties_table;
zval *end = p + class_type->default_properties_count;
do {
ZVAL_UNDEF(p);
p++;
} while (p != end);
}

zend_error(E_WARNING, "%s() has been disabled for security reasons", ZSTR_VAL(class_type->name));
return intern;
}
#ifdef ZEND_WIN32
#pragma optimize("", on)
#endif
/* }}} */

static const zend_function_entry disabled_class_new[] = {
ZEND_FE_END
};

ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_name_length) /* {{{ */
{
zend_class_entry *disabled_class;
zend_string *key;
zend_function *fn;
zend_property_info *prop;

key = zend_string_alloc(class_name_length, 0);
zend_str_tolower_copy(ZSTR_VAL(key), class_name, class_name_length);
disabled_class = zend_hash_find_ptr(CG(class_table), key);
zend_string_release_ex(key, 0);
if (!disabled_class) {
return FAILURE;
}

/* Will be reset by INIT_CLASS_ENTRY. */
free(disabled_class->interfaces);

INIT_CLASS_ENTRY_INIT_METHODS((*disabled_class), disabled_class_new);
disabled_class->create_object = display_disabled_class;

ZEND_HASH_MAP_FOREACH_PTR(&disabled_class->function_table, fn) {
if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
fn->common.scope == disabled_class) {
zend_free_internal_arg_info(&fn->internal_function);
}
} ZEND_HASH_FOREACH_END();
zend_hash_clean(&disabled_class->function_table);
ZEND_HASH_MAP_FOREACH_PTR(&disabled_class->properties_info, prop) {
if (prop->ce == disabled_class) {
zend_string_release(prop->name);
zend_type_release(prop->type, /* persistent */ 1);
free(prop);
}
} ZEND_HASH_FOREACH_END();
zend_hash_clean(&disabled_class->properties_info);
return SUCCESS;
}
/* }}} */

static zend_always_inline zend_class_entry *get_scope(zend_execute_data *frame)
{
return frame && frame->func ? frame->func->common.scope : NULL;
Expand Down
1 change: 0 additions & 1 deletion Zend/zend_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,6 @@ static zend_always_inline zend_result zend_register_class_alias(const char *name
zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce, 1)

ZEND_API void zend_disable_functions(const char *function_list);
ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_name_length);

ZEND_API ZEND_COLD void zend_wrong_param_count(void);
ZEND_API ZEND_COLD void zend_wrong_property_read(zval *object, zval *property);
Expand Down
37 changes: 28 additions & 9 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ void zend_oparray_context_begin(zend_oparray_context *prev_context, zend_op_arra
CG(context).try_catch_offset = -1;
CG(context).current_brk_cont = -1;
CG(context).last_brk_cont = 0;
CG(context).has_assigned_to_http_response_header = false;
CG(context).brk_cont_array = NULL;
CG(context).labels = NULL;
CG(context).in_jmp_frameless_branch = false;
Expand Down Expand Up @@ -2867,7 +2868,7 @@ static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t f
}
/* }}} */

static zend_result zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */
static zend_result zend_try_compile_cv(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
{
zend_ast *name_ast = ast->child[0];
if (name_ast->kind == ZEND_AST_ZVAL) {
Expand All @@ -2884,6 +2885,16 @@ static zend_result zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */
return FAILURE;
}

if (!CG(context).has_assigned_to_http_response_header && zend_string_equals_literal(name, "http_response_header")) {
if (type == BP_VAR_R) {
zend_error(E_DEPRECATED,
"The predefined locally scoped $http_response_header variable is deprecated,"
" call http_get_last_response_headers() instead");
} else if (type == BP_VAR_W) {
CG(context).has_assigned_to_http_response_header = true;
}
}

result->op_type = IS_CV;
result->u.op.var = lookup_cv(name);

Expand Down Expand Up @@ -2920,6 +2931,14 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint

opline->extended_value = ZEND_FETCH_GLOBAL;
} else {
// TODO: Have a test case for this?
if (name_node.op_type == IS_CONST
&& type == BP_VAR_R
&& zend_string_equals_literal(Z_STR(name_node.u.constant), "http_response_header")) {
zend_error(E_DEPRECATED,
"The predefined locally scoped $http_response_header variable is deprecated,"
" call http_get_last_response_headers() instead");
}
opline->extended_value = ZEND_FETCH_LOCAL;
}

Expand Down Expand Up @@ -2991,7 +3010,7 @@ static zend_op *zend_compile_simple_var(znode *result, zend_ast *ast, uint32_t t
result->op_type = IS_TMP_VAR;
}
return opline;
} else if (zend_try_compile_cv(result, ast) == FAILURE) {
} else if (zend_try_compile_cv(result, ast, type) == FAILURE) {
return zend_compile_simple_var_no_cv(result, ast, type, delayed);
}
return NULL;
Expand Down Expand Up @@ -3417,7 +3436,7 @@ static void zend_compile_expr_with_potential_assign_to_self(
/* $a[0] = $a should evaluate the right $a first */
znode cv_node;

if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) {
if (zend_try_compile_cv(&cv_node, expr_ast, BP_VAR_R) == FAILURE) {
zend_compile_simple_var_no_cv(expr_node, expr_ast, BP_VAR_R, 0);
} else {
zend_emit_op_tmp(expr_node, ZEND_QM_ASSIGN, &cv_node, NULL);
Expand Down Expand Up @@ -3507,7 +3526,7 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
/* list($a, $b) = $a should evaluate the right $a first */
znode cv_node;

if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) {
if (zend_try_compile_cv(&cv_node, expr_ast, BP_VAR_R) == FAILURE) {
zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0);
} else {
zend_emit_op_tmp(&expr_node, ZEND_QM_ASSIGN, &cv_node, NULL);
Expand Down Expand Up @@ -3822,7 +3841,7 @@ static uint32_t zend_compile_args(
opcode = ZEND_SEND_VAR_EX;
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
break;
} else if (zend_try_compile_cv(&arg_node, arg) == SUCCESS) {
} else if (zend_try_compile_cv(&arg_node, arg, BP_VAR_R) == SUCCESS) {
opcode = ZEND_SEND_VAR_EX;
break;
}
Expand Down Expand Up @@ -5427,7 +5446,7 @@ static void zend_compile_global_var(zend_ast *ast) /* {{{ */
// TODO(GLOBALS) Forbid "global $GLOBALS"?
if (is_this_fetch(var_ast)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as global variable");
} else if (zend_try_compile_cv(&result, var_ast) == SUCCESS) {
} else if (zend_try_compile_cv(&result, var_ast, BP_VAR_R) == SUCCESS) {
zend_op *opline = zend_emit_op(NULL, ZEND_BIND_GLOBAL, &result, &name_node);
opline->extended_value = zend_alloc_cache_slot();
} else {
Expand Down Expand Up @@ -5553,7 +5572,7 @@ static void zend_compile_unset(zend_ast *ast) /* {{{ */
case ZEND_AST_VAR:
if (is_this_fetch(var_ast)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot unset $this");
} else if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
} else if (zend_try_compile_cv(&var_node, var_ast, BP_VAR_UNSET) == SUCCESS) {
opline = zend_emit_op(NULL, ZEND_UNSET_CV, &var_node, NULL);
} else {
opline = zend_compile_simple_var_no_cv(NULL, var_ast, BP_VAR_UNSET, 0);
Expand Down Expand Up @@ -6116,7 +6135,7 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */
if (is_this_fetch(value_ast)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
} else if (value_ast->kind == ZEND_AST_VAR &&
zend_try_compile_cv(&value_node, value_ast) == SUCCESS) {
zend_try_compile_cv(&value_node, value_ast, BP_VAR_R) == SUCCESS) {
SET_NODE(opline->op2, &value_node);
} else {
opline->op2_type = IS_VAR;
Expand Down Expand Up @@ -10842,7 +10861,7 @@ static void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */
if (is_this_fetch(var_ast)) {
opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_THIS, NULL, NULL);
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
} else if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
} else if (zend_try_compile_cv(&var_node, var_ast, BP_VAR_IS) == SUCCESS) {
opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_CV, &var_node, NULL);
} else {
opline = zend_compile_simple_var_no_cv(result, var_ast, BP_VAR_IS, 0);
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ typedef struct _zend_oparray_context {
zend_string *active_property_info_name;
zend_property_hook_kind active_property_hook_kind;
bool in_jmp_frameless_branch;
bool has_assigned_to_http_response_header;
} zend_oparray_context;

/* Class, property and method flags class|meth.|prop.|const*/
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/tests/http/bug75535.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ $responses = array(
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);

var_dump(file_get_contents($uri));
var_dump($http_response_header);
var_dump(http_get_last_response_headers());

http_server_kill($pid);

Expand Down
3 changes: 2 additions & 1 deletion ext/standard/tests/http/bug80838.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ var_dump(http_get_last_response_headers());
http_server_kill($pid);

?>
--EXPECT--
--EXPECTF--
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 23
NULL
array(3) {
[0]=>
Expand Down
3 changes: 2 additions & 1 deletion ext/standard/tests/http/gh9316.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ for ($i = 0; $i < count($responses); ++$i) {
http_server_kill($pid);

?>
--EXPECT--
--EXPECTF--
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 17
http_get_last_response_headers() before stream layer call:
NULL
$http_response_header
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ $clientCode = <<<'CODE'
$ctx = stream_context_create();
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx)));
var_dump($http_response_header);
var_dump(http_get_last_response_headers());
CODE;

include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ $clientCode = <<<'CODE'
$ctx = stream_context_create();
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx)));
var_dump($http_response_header);
var_dump(http_get_last_response_headers());
CODE;

include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/tests/http/ghsa-hgf5-96fm-v528-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ $clientCode = <<<'CODE'
];
$ctx = stream_context_create($opts);
var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx))));
var_dump($http_response_header);
var_dump(http_get_last_response_headers());
CODE;

include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/tests/http/ghsa-hgf5-96fm-v528-002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ $clientCode = <<<'CODE'
];
$ctx = stream_context_create($opts);
var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx))));
var_dump($http_response_header);
var_dump(http_get_last_response_headers());
CODE;

include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
Expand Down
Loading