From a3bcc86564251a697b0986670fe447a9cb02bdd8 Mon Sep 17 00:00:00 2001 From: Weilin Du Date: Tue, 23 Jun 2026 23:12:12 +0800 Subject: [PATCH 1/4] Fix GH-22395: Avoid truncating base_convert() output at 64 characters (#22406) By using `ZEND_DOUBLE_MAX_LENGTH` instead of `(sizeof(double) << 3) + 1` we can fix the bug that base_convert() truncates output at 64 characters. Fixes #22395 --- NEWS | 2 ++ ext/standard/math.c | 3 ++- ext/standard/tests/math/gh22395.phpt | 11 +++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 ext/standard/tests/math/gh22395.phpt diff --git a/NEWS b/NEWS index 8ee746eadee2..df17e31c61f6 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ PHP NEWS - Standard: . Fixed bug GH-22360 (convert.base64-encode corruption on incremental flush). (David Carlier) + . Fixed bug GH-22395 (base_convert() outputs at most 64 characters). + (Weilin Du) 02 Jul 2026, PHP 8.4.23 diff --git a/ext/standard/math.c b/ext/standard/math.c index 2a9cf5d4a6ff..758b352f90ff 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -24,6 +24,7 @@ #include "zend_exceptions.h" #include "zend_multiply.h" #include "zend_portability.h" +#include "zend_strtod.h" #include #include @@ -949,7 +950,7 @@ PHPAPI zend_string * _php_math_zvaltobase(zval *arg, int base) if (Z_TYPE_P(arg) == IS_DOUBLE) { double fvalue = floor(Z_DVAL_P(arg)); /* floor it just in case */ char *ptr, *end; - char buf[(sizeof(double) << 3) + 1]; + char buf[ZEND_DOUBLE_MAX_LENGTH]; /* Don't try to convert +/- infinity */ if (fvalue == ZEND_INFINITY || fvalue == -ZEND_INFINITY) { diff --git a/ext/standard/tests/math/gh22395.phpt b/ext/standard/tests/math/gh22395.phpt new file mode 100644 index 000000000000..73c2c66da199 --- /dev/null +++ b/ext/standard/tests/math/gh22395.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-22395 (base_convert outputs at most 64 characters) +--FILE-- + +--EXPECT-- +int(78) +string(13) "4b61b5e0639ff" From 2a339c24d0c536a5716aa2061047537574354651 Mon Sep 17 00:00:00 2001 From: Weilin Du <108666168+LamentXU123@users.noreply.github.com> Date: Tue, 23 Jun 2026 23:37:17 +0800 Subject: [PATCH 2/4] ext/phar: Fix .phar-prefixed non-magic directory handling (#22372) Use a shared helper for checking whether a path refers to the magic .phar directory. Treat .phar itself and paths below it as magic, while allowing non-magic entries that merely use a .phar-prefixed name such as .pharx. Apply the same check across creation, copying, ArrayAccess, stream lookup, directory iteration, extraction, and mounts so these paths are handled consistently. Co-authored-by: Gina Peter Banyard Closes #22372 --- NEWS | 7 ++ ext/phar/dirstream.c | 4 +- ext/phar/phar_internal.h | 25 +++++++ ext/phar/phar_object.c | 45 ++++--------- ext/phar/tests/phar_magic_dir_prefix.phpt | 80 +++++++++++++++++++++++ ext/phar/util.c | 4 +- 6 files changed, 130 insertions(+), 35 deletions(-) create mode 100644 ext/phar/tests/phar_magic_dir_prefix.phpt diff --git a/NEWS b/NEWS index df17e31c61f6..060dc91e80a4 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,13 @@ PHP NEWS . Fixed memory leaks when calling Collator::__construct() or Spoofchecker::__construct() twice. (Weilin Du) +- Phar: + . Fixed inconsistent handling of the magic ".phar" directory. Paths such as + "/.phar" remain protected, while non-magic paths that merely start with + ".phar" are handled consistently across file and directory creation, + copying, ArrayAccess, stream lookup, directory iteration and extraction. + (Weilin Du) + - Reflection: . Fixed bug GH-22324 (Ignore leading namespace separator in ReflectionParameter::__construct()). (jorgsowa) diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index 4fe61db412a4..e28f4f977278 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -178,7 +178,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest) /* {{{ */ ALLOC_HASHTABLE(data); zend_hash_init(data, 64, NULL, NULL, 0); - if ((*dir == '/' && dirlen == 1 && (manifest->nNumOfElements == 0)) || (dirlen >= sizeof(".phar")-1 && !memcmp(dir, ".phar", sizeof(".phar")-1))) { + if ((*dir == '/' && dirlen == 1 && (manifest->nNumOfElements == 0)) || phar_path_is_magic_phar_ex(dir, dirlen)) { /* make empty root directory for empty phar */ /* make empty directory for .phar magic directory */ efree(dir); @@ -204,7 +204,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest) /* {{{ */ if (*dir == '/') { /* root directory */ - if (keylen >= sizeof(".phar")-1 && !memcmp(ZSTR_VAL(str_key), ".phar", sizeof(".phar")-1)) { + if (phar_is_magic_phar(str_key)) { /* do not add any magic entries to this directory */ if (SUCCESS != zend_hash_move_forward(manifest)) { break; diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index e9c34ad9117e..39f489ad439f 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -381,6 +381,31 @@ static inline bool phar_validate_alias(const char *alias, size_t alias_len) /* { } /* }}} */ +static inline bool phar_path_is_magic_phar_ex(const char *path, size_t path_len) /* {{{ */ +{ + if (path_len > 0 && path[0] == '/') { + path++; + path_len--; + } + + if (path_len < sizeof(".phar") - 1 || memcmp(path, ".phar", sizeof(".phar") - 1) != 0) { + return false; + } + + if (path_len == sizeof(".phar") - 1) { + return true; + } + + return path[sizeof(".phar") - 1] == '/' || path[sizeof(".phar") - 1] == '\\'; +} +/* }}} */ + +static inline bool phar_is_magic_phar(const zend_string *path) /* {{{ */ +{ + return phar_path_is_magic_phar_ex(ZSTR_VAL(path), ZSTR_LEN(path)); +} +/* }}} */ + static inline void phar_set_inode(phar_entry_info *entry) /* {{{ */ { char tmp[MAXPATHLEN]; diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index a2d70a1a000f..a1736f221e27 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -1619,7 +1619,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ return ZEND_HASH_APPLY_STOP; } after_open_fp: - if (str_key_len >= sizeof(".phar")-1 && !memcmp(str_key, ".phar", sizeof(".phar")-1)) { + if (phar_path_is_magic_phar_ex(str_key, str_key_len)) { /* silently skip any files that would be added to the magic .phar directory */ if (save) { efree(save); @@ -3468,14 +3468,14 @@ PHP_METHOD(Phar, copy) RETURN_THROWS(); } - if (zend_string_starts_with_literal(old_file, ".phar")) { + if (phar_is_magic_phar(old_file)) { /* can't copy a meta file */ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); RETURN_THROWS(); } - if (zend_string_starts_with_literal(new_file, ".phar")) { + if (phar_is_magic_phar(new_file)) { /* can't copy a meta file */ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); @@ -3562,11 +3562,8 @@ PHP_METHOD(Phar, offsetExists) } } - if (zend_string_starts_with_literal(file_name, ".phar")) { - /* none of these are real files, so they don't exist */ - RETURN_FALSE; - } - RETURN_TRUE; + /* none of these are real files, so they don't exist */ + RETURN_BOOL(!phar_is_magic_phar(file_name)); } else { /* If the info class is not based on PharFileInfo, directories are not directly instantiable */ if (UNEXPECTED(!instanceof_function(phar_obj->spl.info_class, phar_ce_entry))) { @@ -3609,7 +3606,7 @@ PHP_METHOD(Phar, offsetGet) RETURN_THROWS(); } - if (zend_string_starts_with_literal(file_name, ".phar")) { + if (phar_is_magic_phar(file_name)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot directly get any files or directories in magic \".phar\" directory"); RETURN_THROWS(); } @@ -3640,16 +3637,9 @@ static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, con ALLOCA_FLAG(filename_use_heap) #endif - if ( - zend_string_starts_with_literal(file_name, ".phar") - || zend_string_starts_with_literal(file_name, "/.phar") - ) { - size_t prefix_len = (ZSTR_VAL(file_name)[0] == '/') + sizeof(".phar")-1; - char next_char = ZSTR_VAL(file_name)[prefix_len]; - if (next_char == '/' || next_char == '\\' || next_char == '\0') { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create any files in magic \".phar\" directory"); - return; - } + if (phar_is_magic_phar(file_name)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create any files in magic \".phar\" directory"); + return; } /* TODO How to handle Windows path normalisation with zend_string ? */ @@ -3796,7 +3786,7 @@ PHP_METHOD(Phar, offsetSet) RETURN_THROWS(); } - if (zend_string_starts_with_literal(file_name, ".phar")) { + if (phar_is_magic_phar(file_name)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set any files or directories in magic \".phar\" directory"); RETURN_THROWS(); } @@ -3863,16 +3853,9 @@ PHP_METHOD(Phar, addEmptyDir) PHAR_ARCHIVE_OBJECT(); - if ( - zend_string_starts_with_literal(dir_name, ".phar") - || zend_string_starts_with_literal(dir_name, "/.phar") - ) { - size_t prefix_len = (ZSTR_VAL(dir_name)[0] == '/') + sizeof(".phar")-1; - char next_char = ZSTR_VAL(dir_name)[prefix_len]; - if (next_char == '/' || next_char == '\\' || next_char == '\0') { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory"); - RETURN_THROWS(); - } + if (phar_is_magic_phar(dir_name)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory"); + RETURN_THROWS(); } phar_mkdir(&phar_obj->archive, dir_name); @@ -4178,7 +4161,7 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha return SUCCESS; } - if (entry->filename_len >= sizeof(".phar")-1 && !memcmp(entry->filename, ".phar", sizeof(".phar")-1)) { + if (phar_path_is_magic_phar_ex(entry->filename, entry->filename_len)) { return SUCCESS; } /* strip .. from path and restrict it to be under dest directory */ diff --git a/ext/phar/tests/phar_magic_dir_prefix.phpt b/ext/phar/tests/phar_magic_dir_prefix.phpt new file mode 100644 index 000000000000..e1f1c517632e --- /dev/null +++ b/ext/phar/tests/phar_magic_dir_prefix.phpt @@ -0,0 +1,80 @@ +--TEST-- +Phar: .phar-prefixed non-magic directories are accessible +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +addFromString('.pharx/from-string.txt', 'from-string'); +$phar->addFromString('/.phary/leading.txt', 'leading'); +$phar->copy('.pharx/array.txt', '.pharx/copy.txt'); + +var_dump(isset($phar['.pharx/array.txt'])); +echo $phar['.pharx/array.txt']->getContent(), "\n"; +echo file_get_contents($pname . '/.pharx/from-string.txt'), "\n"; +echo file_get_contents($pname . '/.phary/leading.txt'), "\n"; +echo file_get_contents($pname . '/.pharx/copy.txt'), "\n"; + +$root = []; +$dh = opendir($pname . '/'); +while (false !== ($entry = readdir($dh))) { + $root[] = $entry; +} +closedir($dh); +sort($root); +var_dump($root); + +$subdir = []; +$dh = opendir($pname . '/.pharx'); +while (false !== ($entry = readdir($dh))) { + $subdir[] = $entry; +} +closedir($dh); +sort($subdir); +var_dump($subdir); + +try { + $phar->addFromString('.phar/still-magic.txt', 'no'); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $phar->addEmptyDir('/.phar'); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--CLEAN-- + +--EXPECT-- +bool(true) +array +from-string +leading +array +array(2) { + [0]=> + string(6) ".pharx" + [1]=> + string(6) ".phary" +} +array(3) { + [0]=> + string(9) "array.txt" + [1]=> + string(8) "copy.txt" + [2]=> + string(15) "from-string.txt" +} +Cannot create any files in magic ".phar" directory +Cannot create a directory in magic ".phar" directory diff --git a/ext/phar/util.c b/ext/phar/util.c index e2d1076921f2..2c896c6f6588 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -208,7 +208,7 @@ zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t fil return FAILURE; } - if (path_len >= sizeof(".phar")-1 && !memcmp(path, ".phar", sizeof(".phar")-1)) { + if (phar_path_is_magic_phar_ex(path, path_len)) { /* no creating magic phar files by mounting them */ return FAILURE; } @@ -1290,7 +1290,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si *error = NULL; } - if (security && path_len >= sizeof(".phar")-1 && !memcmp(path, ".phar", sizeof(".phar")-1)) { + if (security && phar_path_is_magic_phar_ex(path, path_len)) { if (error) { spprintf(error, 4096, "phar error: cannot directly access magic \".phar\" directory or files within it"); } From 08a6ebfe3116e149d13b572385bac345a301ef21 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 5 Mar 2026 12:15:21 +0000 Subject: [PATCH 3/4] ext/spl: ArrayObject improve ZPP test for usort() methods --- .../arrayObject_uasort_error1.phpt | 20 +++++-------------- .../arrayObject_uksort_error1.phpt | 20 +++++-------------- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt index d4c853245127..32defd35e6fc 100644 --- a/ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt @@ -1,26 +1,16 @@ --TEST-- -Test ArrayObject::uasort() function : wrong arg count +ArrayObject::uasort() function: non callable error --FILE-- uasort(); -} catch (ArgumentCountError $e) { - echo $e->getMessage() . "\n"; + $ao->uasort('not_a_valid_function'); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } -try { - $ao->uasort(1,2); -} catch (ArgumentCountError $e) { - echo $e->getMessage() . "\n"; -} ?> --EXPECT-- -ArrayObject::uasort() expects exactly 1 argument, 0 given -ArrayObject::uasort() expects exactly 1 argument, 2 given +TypeError: uasort(): Argument #2 ($callback) must be a valid callback, function "not_a_valid_function" not found or invalid function name diff --git a/ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt index 71164383e41b..11b40aae8c8f 100644 --- a/ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt @@ -1,26 +1,16 @@ --TEST-- -Test ArrayObject::uksort() function : wrong arg count +ArrayObject::uksort() function: non callable error --FILE-- uksort(); -} catch (ArgumentCountError $e) { - echo $e->getMessage() . "\n"; + $ao->uksort('not_a_valid_function'); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } -try { - $ao->uksort(1,2); -} catch (ArgumentCountError $e) { - echo $e->getMessage() . "\n"; -} ?> --EXPECT-- -ArrayObject::uksort() expects exactly 1 argument, 0 given -ArrayObject::uksort() expects exactly 1 argument, 2 given +TypeError: uksort(): Argument #2 ($callback) must be a valid callback, function "not_a_valid_function" not found or invalid function name From 6f0aa11d23a350e01f4d14112333281eb2b0d77a Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 5 Mar 2026 12:42:20 +0000 Subject: [PATCH 4/4] ext/spl/ArrayObject: handle ZPP for each sort methods directly --- ext/spl/spl_array.c | 125 ++++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 57 deletions(-) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 39d27bc40105..1976192e7b06 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1153,18 +1153,12 @@ PHP_METHOD(ArrayObject, count) RETURN_LONG(spl_array_object_count_elements_helper(intern)); } /* }}} */ -enum spl_array_object_sort_methods { - SPL_NAT_SORT, - SPL_CALLBACK_SORT, - SPL_OPTIONAL_FLAG_SORT -}; - -static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, const char *fname, size_t fname_len, enum spl_array_object_sort_methods use_arg) /* {{{ */ +static void spl_array_method(zval *return_value, spl_array_object *intern, const char *fname, size_t fname_len, const zval *extra_arg) /* {{{ */ { - spl_array_object *intern = Z_SPLARRAY_P(ZEND_THIS); HashTable **ht_ptr = spl_array_get_hash_table_ptr(intern); HashTable *aht = *ht_ptr; - zval params[2], *arg = NULL; + zval params[2]; + uint32_t param_num = 1; zend_function *fn = zend_hash_str_find_ptr(EG(function_table), fname, fname_len); if (UNEXPECTED(fn == NULL)) { @@ -1176,68 +1170,85 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, const char *fname, si ZVAL_ARR(Z_REFVAL(params[0]), aht); GC_ADDREF(aht); - if (use_arg == SPL_NAT_SORT) { - if (zend_parse_parameters_none() == FAILURE) { - goto exit; - } - - intern->nApplyCount++; - zend_call_known_function(fn, NULL, NULL, return_value, 1, params, NULL); - intern->nApplyCount--; - } else if (use_arg == SPL_OPTIONAL_FLAG_SORT) { - zend_long sort_flags = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &sort_flags) == FAILURE) { - goto exit; - } - ZVAL_LONG(¶ms[1], sort_flags); - intern->nApplyCount++; - zend_call_known_function(fn, NULL, NULL, return_value, 2, params, NULL); - intern->nApplyCount--; - } else { - ZEND_ASSERT(use_arg == SPL_CALLBACK_SORT); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg) == FAILURE) { - goto exit; - } - ZVAL_COPY_VALUE(¶ms[1], arg); - intern->nApplyCount++; - zend_call_known_function(fn, NULL, NULL, return_value, 2, params, NULL); - intern->nApplyCount--; + if (extra_arg) { + param_num = 2; + ZVAL_COPY_VALUE(¶ms[1], extra_arg); } + intern->nApplyCount++; + zend_call_known_function(fn, NULL, NULL, return_value, param_num, params, NULL); + intern->nApplyCount--; -exit: - { - zval *ht_zv = Z_REFVAL(params[0]); - zend_array_release(*ht_ptr); - SEPARATE_ARRAY(ht_zv); - *ht_ptr = Z_ARRVAL_P(ht_zv); - ZVAL_NULL(ht_zv); - zval_ptr_dtor(¶ms[0]); - } + zval *ht_zv = Z_REFVAL(params[0]); + zend_array_release(*ht_ptr); + SEPARATE_ARRAY(ht_zv); + *ht_ptr = Z_ARRVAL_P(ht_zv); + ZVAL_NULL(ht_zv); + zval_ptr_dtor(¶ms[0]); } /* }}} */ -#define SPL_ARRAY_METHOD(cname, fname, use_arg) \ -PHP_METHOD(cname, fname) \ -{ \ - spl_array_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, #fname, sizeof(#fname)-1, use_arg); \ -} - /* Sort the entries by values. */ -SPL_ARRAY_METHOD(ArrayObject, asort, SPL_OPTIONAL_FLAG_SORT) +PHP_METHOD(ArrayObject, asort) +{ + zend_long sort_flags = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &sort_flags) == FAILURE) { + RETURN_THROWS(); + } + zval sort_flag_param; + ZVAL_LONG(&sort_flag_param, sort_flags); + + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("asort"), &sort_flag_param); +} /* Sort the entries by key. */ -SPL_ARRAY_METHOD(ArrayObject, ksort, SPL_OPTIONAL_FLAG_SORT) +PHP_METHOD(ArrayObject, ksort) +{ + zend_long sort_flags = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &sort_flags) == FAILURE) { + RETURN_THROWS(); + } + zval sort_flag_param; + ZVAL_LONG(&sort_flag_param, sort_flags); + + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("ksort"), &sort_flag_param); +} /* Sort the entries by values user defined function. */ -SPL_ARRAY_METHOD(ArrayObject, uasort, SPL_CALLBACK_SORT) +PHP_METHOD(ArrayObject, uasort) +{ + zval *callback = NULL; + /* TODO: Should check variable is callable */ + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &callback) == FAILURE) { + RETURN_THROWS(); + } + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("uasort"), callback); +} /* Sort the entries by key using user defined function. */ -SPL_ARRAY_METHOD(ArrayObject, uksort, SPL_CALLBACK_SORT) +PHP_METHOD(ArrayObject, uksort) +{ + zval *callback = NULL; + /* TODO: Should check variable is callable */ + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &callback) == FAILURE) { + RETURN_THROWS(); + } + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("uksort"), callback); +} /* Sort the entries by values using "natural order" algorithm. */ -SPL_ARRAY_METHOD(ArrayObject, natsort, SPL_NAT_SORT) +PHP_METHOD(ArrayObject, natsort) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("natsort"), NULL); +} -/* {{{ Sort the entries by key using case-insensitive "natural order" algorithm. */ -SPL_ARRAY_METHOD(ArrayObject, natcasesort, SPL_NAT_SORT) +/* Sort the entries by key using case-insensitive "natural order" algorithm. */ +PHP_METHOD(ArrayObject, natcasesort) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + spl_array_method(return_value, Z_SPLARRAY_P(ZEND_THIS), ZEND_STRL("natcasesort"), NULL); +} /* {{{ Serialize the object */ PHP_METHOD(ArrayObject, serialize)