|
21 | 21 | #include "Zend/zend_exceptions.h" |
22 | 22 | #include "Zend/zend_attributes.h" |
23 | 23 | #include "Zend/zend_enum.h" |
| 24 | +#include "Zend/zend_ast.h" |
24 | 25 | #include "ext/standard/info.h" |
25 | 26 |
|
26 | 27 | #include "php_uri.h" |
@@ -1111,6 +1112,69 @@ PHPAPI zend_result php_uri_parser_register(const php_uri_parser *uri_parser) |
1111 | 1112 | return result; |
1112 | 1113 | } |
1113 | 1114 |
|
| 1115 | +/* Registers the deprecated, misspelled "InvalidReverseSoldius" class constant as |
| 1116 | + * an alias of the correctly spelled UrlValidationErrorType::InvalidReverseSolidus |
| 1117 | + * enum case. The typo was shipped in PHP 8.5, so the alias is kept for backwards |
| 1118 | + * compatibility. |
| 1119 | + * |
| 1120 | + * The value is stored as a lazy "self::InvalidReverseSolidus" constant AST instead |
| 1121 | + * of an eager enum case object: enum case objects are materialized lazily (the case |
| 1122 | + * constants are still IS_CONSTANT_AST during module startup), so resolving the case |
| 1123 | + * eagerly here would crash. The AST is allocated persistently and flagged immutable, |
| 1124 | + * mirroring how the engine stores internal enum case constants. */ |
| 1125 | +static void php_uri_register_invalid_reverse_solidus_alias(zend_class_entry *ce) |
| 1126 | +{ |
| 1127 | + zend_string *self_name = ZSTR_KNOWN(ZEND_STR_SELF); |
| 1128 | + zend_string *case_name = zend_string_init_interned("InvalidReverseSolidus", sizeof("InvalidReverseSolidus") - 1, true); |
| 1129 | + |
| 1130 | + /* Build a persistent AST equivalent to "self::InvalidReverseSolidus": |
| 1131 | + * ZEND_AST_CLASS_CONST(child[0] = "self", child[1] = "InvalidReverseSolidus"). */ |
| 1132 | + const uint32_t num_children = 2; |
| 1133 | + size_t size = sizeof(zend_ast_ref) + zend_ast_size(num_children) |
| 1134 | + + num_children * sizeof(zend_ast_zval); |
| 1135 | + char *p = pemalloc(size, 1); |
| 1136 | + |
| 1137 | + zend_ast_ref *ref = (zend_ast_ref *) p; |
| 1138 | + p += sizeof(zend_ast_ref); |
| 1139 | + GC_SET_REFCOUNT(ref, 1); |
| 1140 | + GC_TYPE_INFO(ref) = GC_CONSTANT_AST | GC_PERSISTENT | GC_IMMUTABLE; |
| 1141 | + |
| 1142 | + zend_ast *ast = (zend_ast *) p; |
| 1143 | + p += zend_ast_size(num_children); |
| 1144 | + ast->kind = ZEND_AST_CLASS_CONST; |
| 1145 | + ast->attr = ZEND_FETCH_CLASS_EXCEPTION; |
| 1146 | + ast->lineno = 0; |
| 1147 | + |
| 1148 | + ast->child[0] = (zend_ast *) p; |
| 1149 | + p += sizeof(zend_ast_zval); |
| 1150 | + ast->child[0]->kind = ZEND_AST_ZVAL; |
| 1151 | + ast->child[0]->attr = 0; |
| 1152 | + ZVAL_STR(zend_ast_get_zval(ast->child[0]), self_name); |
| 1153 | + Z_LINENO_P(zend_ast_get_zval(ast->child[0])) = 0; |
| 1154 | + |
| 1155 | + ast->child[1] = (zend_ast *) p; |
| 1156 | + ast->child[1]->kind = ZEND_AST_ZVAL; |
| 1157 | + ast->child[1]->attr = 0; |
| 1158 | + ZVAL_STR(zend_ast_get_zval(ast->child[1]), case_name); |
| 1159 | + Z_LINENO_P(zend_ast_get_zval(ast->child[1])) = 0; |
| 1160 | + |
| 1161 | + zval alias_value; |
| 1162 | + Z_TYPE_INFO(alias_value) = IS_CONSTANT_AST; |
| 1163 | + Z_AST(alias_value) = ref; |
| 1164 | + |
| 1165 | + zend_string *alias_name = zend_string_init_interned("InvalidReverseSoldius", sizeof("InvalidReverseSoldius") - 1, true); |
| 1166 | + zend_class_constant *alias = zend_declare_class_constant_ex( |
| 1167 | + ce, alias_name, &alias_value, ZEND_ACC_PUBLIC | ZEND_ACC_DEPRECATED, NULL); |
| 1168 | + |
| 1169 | + /* Attach #[\Deprecated(since: "8.6", message: "...")] so the deprecation notice |
| 1170 | + * directs users to the correctly spelled enum case. */ |
| 1171 | + zend_attribute *attr = zend_add_class_constant_attribute(ce, alias, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); |
| 1172 | + ZVAL_STR(&attr->args[0].value, zend_string_init("8.6", strlen("8.6"), 1)); |
| 1173 | + attr->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); |
| 1174 | + ZVAL_STR(&attr->args[1].value, zend_string_init("use Uri\\WhatWg\\UrlValidationErrorType::InvalidReverseSolidus instead", strlen("use Uri\\WhatWg\\UrlValidationErrorType::InvalidReverseSolidus instead"), 1)); |
| 1175 | + attr->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); |
| 1176 | +} |
| 1177 | + |
1114 | 1178 | static PHP_MINIT_FUNCTION(uri) |
1115 | 1179 | { |
1116 | 1180 | php_uri_ce_rfc3986_uri = register_class_Uri_Rfc3986_Uri(); |
@@ -1140,6 +1204,7 @@ static PHP_MINIT_FUNCTION(uri) |
1140 | 1204 | php_uri_ce_whatwg_url_host_type = register_class_Uri_WhatWg_UrlHostType(); |
1141 | 1205 | php_uri_ce_whatwg_url_validation_error = register_class_Uri_WhatWg_UrlValidationError(); |
1142 | 1206 | php_uri_ce_whatwg_url_validation_error_type = register_class_Uri_WhatWg_UrlValidationErrorType(); |
| 1207 | + php_uri_register_invalid_reverse_solidus_alias(php_uri_ce_whatwg_url_validation_error_type); |
1143 | 1208 |
|
1144 | 1209 | zend_hash_init(&uri_parsers, 4, NULL, NULL, true); |
1145 | 1210 |
|
|
0 commit comments