diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 70b7e2e7453..a248c0fd7c9 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -14,6 +14,10 @@ PHP 8.6 INTERNALS UPGRADE NOTES 1. Internal API changes ======================== + . ZSTR_INIT_LITERAL(), zend_string_starts_with_literal(), and + zend_string_starts_with_literal_ci() now support strings containing NUL + bytes. Passing non-literal char* is no longer supported. + ======================== 2. Build system changes ======================== diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 87f22112520..fc7705ff786 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -123,7 +123,7 @@ END_EXTERN_C() #define ZSTR_ALLOCA_FREE(str, use_heap) free_alloca(str, use_heap) -#define ZSTR_INIT_LITERAL(s, persistent) (zend_string_init((s), strlen(s), (persistent))) +#define ZSTR_INIT_LITERAL(s, persistent) (zend_string_init(("" s), sizeof(s) - 1, (persistent))) /*---*/ @@ -402,7 +402,7 @@ static zend_always_inline bool zend_string_starts_with(const zend_string *str, c } #define zend_string_starts_with_literal(str, prefix) \ - zend_string_starts_with_cstr(str, prefix, strlen(prefix)) + zend_string_starts_with_cstr(str, "" prefix, sizeof(prefix) - 1) static zend_always_inline bool zend_string_starts_with_cstr_ci(const zend_string *str, const char *prefix, size_t prefix_length) { @@ -415,7 +415,7 @@ static zend_always_inline bool zend_string_starts_with_ci(const zend_string *str } #define zend_string_starts_with_literal_ci(str, prefix) \ - zend_string_starts_with_cstr_ci(str, prefix, strlen(prefix)) + zend_string_starts_with_cstr_ci(str, "" prefix, sizeof(prefix) - 1) /* * DJBX33A (Daniel J. Bernstein, Times 33 with Addition) diff --git a/ext/dom/element.c b/ext/dom/element.c index 9f4e6d357c0..f9aee10802f 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -180,7 +180,7 @@ zend_result dom_element_class_name_write(dom_object *obj, zval *newval) zval *dom_get_prop_checked_offset(dom_object *obj, uint32_t offset, const char *name) { #if ZEND_DEBUG - zend_string *name_zstr = ZSTR_INIT_LITERAL(name, false); + zend_string *name_zstr = zend_string_init(name, strlen(name), false); const zend_property_info *prop_info = zend_get_property_info(obj->std.ce, name_zstr, 0); zend_string_release_ex(name_zstr, false); ZEND_ASSERT(OBJ_PROP_TO_NUM(prop_info->offset) == offset); diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index bdbd2f52f0f..50c0a57ae8e 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -594,6 +594,13 @@ static ZEND_FUNCTION(zend_test_zend_ini_str) RETURN_STR(ZT_G(str_test)); } +static ZEND_FUNCTION(zend_test_zstr_init_literal) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + RETURN_STR(ZSTR_INIT_LITERAL("foo\0bar", false)); +} + static ZEND_FUNCTION(zend_test_is_string_marked_as_valid_utf8) { zend_string *str; diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index bf9a1c6b5bc..d0c0c64b8b1 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -301,6 +301,7 @@ namespace { function zend_test_zend_ini_parse_uquantity(string $str): int {} function zend_test_zend_ini_str(): string {} + function zend_test_zstr_init_literal(): string {} #ifdef ZEND_CHECK_STACK_LIMIT function zend_test_zend_call_stack_get(): ?array {} diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index bd2240cedd6..d2c7d6bbc28 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 6bccdc2444e6a68ba615fc281235a4551d0b8819 */ + * Stub hash: a8dae89983ccbcd5dd36d1cdee736d40af4fd33c */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_trigger_bailout, 0, 0, IS_NEVER, 0) ZEND_END_ARG_INFO() @@ -130,6 +130,8 @@ ZEND_END_ARG_INFO() #define arginfo_zend_test_zend_ini_str arginfo_zend_get_current_func_name +#define arginfo_zend_test_zstr_init_literal arginfo_zend_get_current_func_name + #if defined(ZEND_CHECK_STACK_LIMIT) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_zend_call_stack_get, 0, 0, IS_ARRAY, 1) ZEND_END_ARG_INFO() @@ -316,6 +318,7 @@ static ZEND_FUNCTION(zend_call_method_if_exists); static ZEND_FUNCTION(zend_test_zend_ini_parse_quantity); static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity); static ZEND_FUNCTION(zend_test_zend_ini_str); +static ZEND_FUNCTION(zend_test_zstr_init_literal); #if defined(ZEND_CHECK_STACK_LIMIT) static ZEND_FUNCTION(zend_test_zend_call_stack_get); static ZEND_FUNCTION(zend_test_zend_call_stack_use_all); @@ -447,6 +450,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(zend_test_zend_ini_parse_quantity, arginfo_zend_test_zend_ini_parse_quantity) ZEND_FE(zend_test_zend_ini_parse_uquantity, arginfo_zend_test_zend_ini_parse_uquantity) ZEND_FE(zend_test_zend_ini_str, arginfo_zend_test_zend_ini_str) + ZEND_FE(zend_test_zstr_init_literal, arginfo_zend_test_zstr_init_literal) #if defined(ZEND_CHECK_STACK_LIMIT) ZEND_FE(zend_test_zend_call_stack_get, arginfo_zend_test_zend_call_stack_get) ZEND_FE(zend_test_zend_call_stack_use_all, arginfo_zend_test_zend_call_stack_use_all) diff --git a/ext/zend_test/tests/zstr_init_literal.phpt b/ext/zend_test/tests/zstr_init_literal.phpt new file mode 100644 index 00000000000..b7f382da8d6 --- /dev/null +++ b/ext/zend_test/tests/zstr_init_literal.phpt @@ -0,0 +1,13 @@ +--TEST-- +zstr_init_literal +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +int(7) +string(14) "666f6f00626172"