From fa23faaca4f8c54c26e7920a1673ac09f26fbc6c Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 1 Nov 2009 17:30:55 +0000 Subject: [PATCH] - Fixed bug #50006 (Segfault caused by uksort()) [5_2 only] --- NEWS | 1 + ext/standard/array.c | 40 +++++++++++++++++--------- ext/standard/tests/array/bug50006.phpt | 29 +++++++++++++++++++ 3 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 ext/standard/tests/array/bug50006.phpt diff --git a/NEWS b/NEWS index 2460f80535..972841e6ad 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,7 @@ PHP NEWS (Felipe) - Fixed memory leak in openssl_pkcs12_export_to_file(). (Felipe) +- Fixed bug #50006 (Segfault caused by uksort()). (Felipe) - Fixed bug #49990 (SNMP3 warning message about security level printed twice). (Jani) - Fixed bug #49985 (pdo_pgsql prepare() re-use previous aborted diff --git a/ext/standard/array.c b/ext/standard/array.c index b834b08ffb..58448cfdd4 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -762,17 +762,17 @@ PHP_FUNCTION(uasort) static int array_user_key_compare(const void *a, const void *b TSRMLS_DC) /* {{{ */ { + zend_fcall_info fci; Bucket *f; Bucket *s; zval *key1, *key2; - zval *args[2]; - zval retval; - int status; + zval **args[2]; + zval *retval_ptr = NULL; ALLOC_INIT_ZVAL(key1); ALLOC_INIT_ZVAL(key2); - args[0] = key1; - args[1] = key2; + args[0] = &key1; + args[1] = &key2; f = *((Bucket **) a); s = *((Bucket **) b); @@ -793,16 +793,30 @@ static int array_user_key_compare(const void *a, const void *b TSRMLS_DC) /* {{{ Z_LVAL_P(key2) = s->h; Z_TYPE_P(key2) = IS_LONG; } - - status = call_user_function(EG(function_table), NULL, *BG(user_compare_func_name), &retval, 2, args TSRMLS_CC); - zval_ptr_dtor(&key1); - zval_ptr_dtor(&key2); - - if (status == SUCCESS) { - convert_to_long(&retval); - return Z_LVAL(retval); + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = *BG(user_compare_func_name); + fci.symbol_table = NULL; + fci.object_pp = NULL; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = 2; + fci.params = args; + fci.no_separation = 0; + + if (zend_call_function(&fci, &BG(user_compare_fci_cache) TSRMLS_CC)== SUCCESS + && retval_ptr) { + long retval; + + convert_to_long_ex(&retval_ptr); + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + zval_ptr_dtor(&key1); + zval_ptr_dtor(&key2); + return retval; } else { + zval_ptr_dtor(&key1); + zval_ptr_dtor(&key2); return 0; } } diff --git a/ext/standard/tests/array/bug50006.phpt b/ext/standard/tests/array/bug50006.phpt new file mode 100644 index 0000000000..f03a002629 --- /dev/null +++ b/ext/standard/tests/array/bug50006.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #50006 (Segfault caused by uksort()) +--FILE-- + 0, + 'bar-bazbazbaz-' => 0, + 'foo' => 0, +); +uksort($data, 'magic_sort_cmp'); +print_r($data); + +function magic_sort_cmp($a, $b) { + $a = substr($a, 1); + $b = substr($b, 1); + if (!$a) return $b ? -1 : 0; + if (!$b) return 1; + return magic_sort_cmp($a, $b); +} + +?> +--EXPECTF-- +Array +( + [foo] => 0 + [bar-bazbazbaz-] => 0 + [bar-bazbazbaz.] => 0 +) -- 2.50.1