mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Deprecate case-insensitive constants
RFC: https://wiki.php.net/rfc/case_insensitive_constant_deprecation
This commit is contained in:
2
NEWS
2
NEWS
@@ -7,6 +7,8 @@ PHP NEWS
|
||||
arguments). (cmb)
|
||||
. Fixed bug #76392 (Error relocating sapi/cli/php: unsupported relocation
|
||||
type 37). (Peter Kokot)
|
||||
. The declaration and use of case-insensitive constants has been deprecated.
|
||||
(Nikita)
|
||||
|
||||
- Filter:
|
||||
. Added the 'add_slashes' sanitization mode (FILTER_SANITIZE_ADD_SLASHES).
|
||||
|
||||
@@ -258,6 +258,13 @@ FPM:
|
||||
4. Deprecated Functionality
|
||||
========================================
|
||||
|
||||
Core:
|
||||
. The declaration of case-insensitive constants has been deprecate. Passing
|
||||
true as the third argument to define() will now generate a deprecation
|
||||
warning. The use of case-insensitive constants with a case that differs from
|
||||
the declaration is also deprecated.
|
||||
(RFC: https://wiki.php.net/rfc/case_insensitive_constant_deprecation)
|
||||
|
||||
GD:
|
||||
. image2wbmp() has been deprecated.
|
||||
|
||||
|
||||
@@ -40,6 +40,11 @@ print ns1\ns2\coNSt6 . "\n";
|
||||
print NS1\ns2\coNSt1 . "\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: define(): Declaration of case-insensitive constants is deprecated in %s on line 6
|
||||
|
||||
Deprecated: define(): Declaration of case-insensitive constants is deprecated in %s on line 7
|
||||
|
||||
Deprecated: define(): Declaration of case-insensitive constants is deprecated in %s on line 8
|
||||
value1
|
||||
value1
|
||||
value1
|
||||
@@ -52,13 +57,23 @@ value3
|
||||
value4
|
||||
value4
|
||||
value4
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "NS1\ns2\const4" in %s on line 25
|
||||
value4
|
||||
value5
|
||||
value5
|
||||
value5
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "ns1\ns2\const5" in %s on line 30
|
||||
value5
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "ns1\NS2\coNSt6" in %s on line 32
|
||||
value6
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "ns1\NS2\coNSt6" in %s on line 33
|
||||
value6
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "ns1\NS2\coNSt6" in %s on line 34
|
||||
value6
|
||||
value6
|
||||
|
||||
|
||||
127
Zend/tests/case_insensitive_constant_deprecation.phpt
Normal file
127
Zend/tests/case_insensitive_constant_deprecation.phpt
Normal file
@@ -0,0 +1,127 @@
|
||||
--TEST--
|
||||
Case-insensitive constants are deprecated
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
define('FOO', 42, true); // Deprecated
|
||||
define('NS\FOO', 24, true); // Deprecated
|
||||
|
||||
var_dump(FOO); // Ok
|
||||
var_dump(foo); // Deprecated
|
||||
|
||||
var_dump(NS\FOO); // Ok
|
||||
var_dump(ns\FOO); // Ok
|
||||
var_dump(ns\foo); // Deprecated
|
||||
|
||||
var_dump(defined('FOO')); // Ok
|
||||
var_dump(defined('foo')); // Ok
|
||||
var_dump(defined('NS\FOO')); // Ok
|
||||
var_dump(defined('ns\FOO')); // Ok
|
||||
var_dump(defined('ns\foo')); // Ok
|
||||
|
||||
var_dump(constant('FOO')); // Ok
|
||||
var_dump(constant('foo')); // Deprecated
|
||||
var_dump(constant('NS\FOO')); // Ok
|
||||
var_dump(constant('ns\FOO')); // Ok
|
||||
var_dump(constant('ns\foo')); // Deprecated
|
||||
}
|
||||
|
||||
namespace NS {
|
||||
var_dump(FOO); // Ok
|
||||
var_dump(foo); // Deprecated
|
||||
}
|
||||
|
||||
namespace ns {
|
||||
var_dump(FOO); // Ok
|
||||
var_dump(foo); // Deprecated
|
||||
}
|
||||
|
||||
namespace Other {
|
||||
var_dump(FOO); // Ok
|
||||
var_dump(foo); // Deprecated
|
||||
|
||||
var_dump(defined('FOO')); // Ok
|
||||
var_dump(defined('foo')); // Ok
|
||||
var_dump(defined('NS\FOO')); // Ok
|
||||
var_dump(defined('ns\FOO')); // Ok
|
||||
var_dump(defined('ns\foo')); // Ok
|
||||
|
||||
var_dump(constant('FOO')); // Ok
|
||||
var_dump(constant('foo')); // Deprecated
|
||||
var_dump(constant('NS\FOO')); // Ok
|
||||
var_dump(constant('ns\FOO')); // Ok
|
||||
var_dump(constant('ns\foo')); // Deprecated
|
||||
|
||||
const C1 = FOO; // Ok
|
||||
var_dump(C1);
|
||||
const C2 = foo; // Deprecated
|
||||
var_dump(C2);
|
||||
const C3 = 1 + FOO; // Ok
|
||||
var_dump(C3);
|
||||
const C4 = 1 + foo; // Deprecated
|
||||
var_dump(C4);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: define(): Declaration of case-insensitive constants is deprecated in %s on line 4
|
||||
|
||||
Deprecated: define(): Declaration of case-insensitive constants is deprecated in %s on line 5
|
||||
int(42)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "FOO" in %s on line 8
|
||||
int(42)
|
||||
int(24)
|
||||
int(24)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "NS\FOO" in %s on line 12
|
||||
int(24)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
int(42)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "FOO" in %s on line 21
|
||||
int(42)
|
||||
int(24)
|
||||
int(24)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "NS\FOO" in %s on line 24
|
||||
int(24)
|
||||
int(24)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "NS\FOO" in %s on line 29
|
||||
int(24)
|
||||
int(24)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "NS\FOO" in %s on line 34
|
||||
int(24)
|
||||
int(42)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "FOO" in %s on line 39
|
||||
int(42)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
int(42)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "FOO" in %s on line 48
|
||||
int(42)
|
||||
int(24)
|
||||
int(24)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "NS\FOO" in %s on line 51
|
||||
int(24)
|
||||
int(42)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "FOO" in %s on line 55
|
||||
int(42)
|
||||
int(43)
|
||||
|
||||
Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "FOO" in %s on line 59
|
||||
int(43)
|
||||
@@ -854,7 +854,6 @@ ZEND_FUNCTION(define)
|
||||
case_sensitive = 0;
|
||||
}
|
||||
|
||||
/* class constant, check if there is name and make sure class is valid & exists */
|
||||
if (zend_memnstr(ZSTR_VAL(name), "::", sizeof("::") - 1, ZSTR_VAL(name) + ZSTR_LEN(name))) {
|
||||
zend_error(E_WARNING, "Class constants cannot be defined or redefined");
|
||||
RETURN_FALSE;
|
||||
@@ -905,7 +904,13 @@ repeat:
|
||||
|
||||
ZVAL_COPY(&c.value, val);
|
||||
zval_ptr_dtor(&val_free);
|
||||
|
||||
register_constant:
|
||||
if (non_cs) {
|
||||
zend_error(E_DEPRECATED,
|
||||
"define(): Declaration of case-insensitive constants is deprecated");
|
||||
}
|
||||
|
||||
c.flags = case_sensitive; /* non persistent */
|
||||
c.name = zend_string_copy(name);
|
||||
c.module_number = PHP_USER_CONSTANT;
|
||||
@@ -928,7 +933,7 @@ ZEND_FUNCTION(defined)
|
||||
Z_PARAM_STR(name)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT)) {
|
||||
if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT | ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK)) {
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
|
||||
@@ -250,7 +250,7 @@ ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry *
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len)
|
||||
static inline zend_constant *zend_get_constant_str_impl(const char *name, size_t name_len)
|
||||
{
|
||||
zend_constant *c;
|
||||
ALLOCA_FLAG(use_heap)
|
||||
@@ -268,10 +268,16 @@ ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len)
|
||||
free_alloca(lcname, use_heap);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len)
|
||||
{
|
||||
zend_constant *c = zend_get_constant_str_impl(name, name_len);
|
||||
return c ? &c->value : NULL;
|
||||
}
|
||||
|
||||
ZEND_API zval *zend_get_constant(zend_string *name)
|
||||
static inline zend_constant *zend_get_constant_impl(zend_string *name)
|
||||
{
|
||||
zval *zv;
|
||||
zend_constant *c;
|
||||
@@ -291,9 +297,32 @@ ZEND_API zval *zend_get_constant(zend_string *name)
|
||||
c = zend_get_special_constant(ZSTR_VAL(name), ZSTR_LEN(name));
|
||||
}
|
||||
free_alloca(lcname, use_heap);
|
||||
return c ? &c->value : NULL;
|
||||
return c;
|
||||
} else {
|
||||
return &((zend_constant*)Z_PTR_P(zv))->value;
|
||||
return (zend_constant *) Z_PTR_P(zv);
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API zval *zend_get_constant(zend_string *name)
|
||||
{
|
||||
zend_constant *c = zend_get_constant_impl(name);
|
||||
return c ? &c->value : NULL;
|
||||
}
|
||||
|
||||
static zend_bool is_access_deprecated(const zend_constant *c, const char *access_name) {
|
||||
const char *ns_sep = zend_memrchr(ZSTR_VAL(c->name), '\\', ZSTR_LEN(c->name));
|
||||
if (ns_sep) {
|
||||
/* Namespaces are always case-insensitive. Only compare shortname. */
|
||||
size_t shortname_offset = ns_sep - ZSTR_VAL(c->name) + 1;
|
||||
size_t shortname_len = ZSTR_LEN(c->name) - shortname_offset;
|
||||
return memcmp(
|
||||
access_name + shortname_offset,
|
||||
ZSTR_VAL(c->name) + shortname_offset,
|
||||
shortname_len
|
||||
) != 0;
|
||||
} else {
|
||||
/* No namespace, compare whole name */
|
||||
return memcmp(access_name, ZSTR_VAL(c->name), ZSTR_LEN(c->name)) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,26 +444,45 @@ failure:
|
||||
}
|
||||
}
|
||||
free_alloca(lcname, use_heap);
|
||||
if (c) {
|
||||
return &c->value;
|
||||
|
||||
if (!c) {
|
||||
if (!(flags & IS_CONSTANT_UNQUALIFIED)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* name requires runtime resolution, need to check non-namespaced name */
|
||||
c = zend_get_constant_str_impl(constant_name, const_name_len);
|
||||
name = constant_name;
|
||||
}
|
||||
/* name requires runtime resolution, need to check non-namespaced name */
|
||||
if ((flags & IS_CONSTANT_UNQUALIFIED) != 0) {
|
||||
return zend_get_constant_str(constant_name, const_name_len);
|
||||
} else {
|
||||
if (cname) {
|
||||
c = zend_get_constant_impl(cname);
|
||||
} else {
|
||||
c = zend_get_constant_str_impl(name, name_len);
|
||||
}
|
||||
}
|
||||
|
||||
if (!c) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cname) {
|
||||
return zend_get_constant(cname);
|
||||
} else {
|
||||
return zend_get_constant_str(name, name_len);
|
||||
if (!(flags & ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK)) {
|
||||
if (!(c->flags & (CONST_CS|CONST_CT_SUBST)) && is_access_deprecated(c, name)) {
|
||||
zend_error(E_DEPRECATED,
|
||||
"Case-insensitive constants are deprecated. "
|
||||
"The correct casing for this constant is \"%s\"",
|
||||
ZSTR_VAL(c->name));
|
||||
}
|
||||
}
|
||||
|
||||
return &c->value;
|
||||
}
|
||||
|
||||
ZEND_API zend_constant* ZEND_FASTCALL zend_quick_get_constant(const zval *key, uint32_t flags)
|
||||
ZEND_API zend_constant* ZEND_FASTCALL zend_quick_get_constant(
|
||||
const zval *key, uint32_t flags, zend_bool *is_deprecated)
|
||||
{
|
||||
zval *zv;
|
||||
const zval *orig_key = key;
|
||||
zend_constant *c = NULL;
|
||||
|
||||
zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
|
||||
@@ -461,6 +509,22 @@ ZEND_API zend_constant* ZEND_FASTCALL zend_quick_get_constant(const zval *key, u
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!c) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (is_deprecated) {
|
||||
if (c->flags & (CONST_CS|CONST_CT_SUBST)) {
|
||||
/* Constant is case-sensitive or true/false/null */
|
||||
*is_deprecated = 0;
|
||||
} else {
|
||||
zend_bool ns_fallback = key >= orig_key + 2;
|
||||
const zval *access_key = ns_fallback ? orig_key + 2 : orig_key - 1;
|
||||
*is_deprecated = is_access_deprecated(c, Z_STRVAL_P(access_key));
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
|
||||
#define PHP_USER_CONSTANT INT_MAX /* a constant defined in user space */
|
||||
|
||||
/* Flag for zend_get_constant_ex(). Must not class with ZEND_FETCH_CLASS_* flags. */
|
||||
#define ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK 0x1000
|
||||
|
||||
typedef struct _zend_constant {
|
||||
zval value;
|
||||
zend_string *name;
|
||||
@@ -79,7 +82,8 @@ ZEND_API int zend_register_constant(zend_constant *c);
|
||||
#ifdef ZTS
|
||||
void zend_copy_constants(HashTable *target, HashTable *sourc);
|
||||
#endif
|
||||
ZEND_API zend_constant* ZEND_FASTCALL zend_quick_get_constant(const zval *key, uint32_t flags);
|
||||
ZEND_API zend_constant* ZEND_FASTCALL zend_quick_get_constant(
|
||||
const zval *key, uint32_t flags, zend_bool *is_deprecated);
|
||||
END_EXTERN_C()
|
||||
|
||||
#define ZEND_CONSTANT_DTOR free_zend_constant
|
||||
|
||||
@@ -5045,11 +5045,12 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED|CONST_FETCH, CONST, CACHE_SLOT)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_constant *c;
|
||||
zend_bool is_deprecated;
|
||||
|
||||
c = CACHED_PTR(opline->extended_value);
|
||||
if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
|
||||
/* pass */
|
||||
} else if (UNEXPECTED((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num)) == NULL)) {
|
||||
} else if (UNEXPECTED((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num, &is_deprecated)) == NULL)) {
|
||||
SAVE_OPLINE();
|
||||
|
||||
if ((opline->op1.num & IS_CONSTANT_UNQUALIFIED) != 0) {
|
||||
@@ -5070,6 +5071,14 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED|CONST_FETCH, CONST, CACHE_SLOT)
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
} else if (is_deprecated) {
|
||||
SAVE_OPLINE();
|
||||
zend_error(E_DEPRECATED,
|
||||
"Case-insensitive constants are deprecated. "
|
||||
"The correct casing for this constant is \"%s\"",
|
||||
ZSTR_VAL(c->name));
|
||||
ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
} else {
|
||||
CACHE_PTR(opline->extended_value, c);
|
||||
}
|
||||
@@ -7611,7 +7620,7 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY, CACHE_SLOT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) {
|
||||
if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0, NULL)) == NULL) {
|
||||
CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
|
||||
result = 0;
|
||||
} else {
|
||||
|
||||
@@ -3883,7 +3883,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEN
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) {
|
||||
if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0, NULL)) == NULL) {
|
||||
CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
|
||||
result = 0;
|
||||
} else {
|
||||
@@ -31965,11 +31965,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_constant *c;
|
||||
zend_bool is_deprecated;
|
||||
|
||||
c = CACHED_PTR(opline->extended_value);
|
||||
if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
|
||||
/* pass */
|
||||
} else if (UNEXPECTED((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num)) == NULL)) {
|
||||
} else if (UNEXPECTED((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num, &is_deprecated)) == NULL)) {
|
||||
SAVE_OPLINE();
|
||||
|
||||
if ((opline->op1.num & IS_CONSTANT_UNQUALIFIED) != 0) {
|
||||
@@ -31990,6 +31991,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
} else if (is_deprecated) {
|
||||
SAVE_OPLINE();
|
||||
zend_error(E_DEPRECATED,
|
||||
"Case-insensitive constants are deprecated. "
|
||||
"The correct casing for this constant is \"%s\"",
|
||||
ZSTR_VAL(c->name));
|
||||
ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
} else {
|
||||
CACHE_PTR(opline->extended_value, c);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user