diff options
| author | kkadosh | 2018-10-05 22:46:23 +0200 |
|---|---|---|
| committer | jvoisin | 2018-10-05 20:46:23 +0000 |
| commit | fc6e2455c5fcc2a5ec365552fb8d89a9c0571154 (patch) | |
| tree | 0e286d6f140a73c84303cd8e888e5752f1525993 /src | |
| parent | 2805631c6a71f1214906f8889ad6711f89b493f7 (diff) | |
Fix segfault array keys
Many thanks to @xXx-caillou-xXx for finding the true root cause and fixing the issue ♥
Diffstat (limited to 'src')
| -rw-r--r-- | src/sp_sloppy.c | 49 | ||||
| -rw-r--r-- | src/tests/sloppy_comparison_array_keys.phpt | 17 | ||||
| -rw-r--r-- | src/tests/sloppy_comparison_array_search_keys.phpt | 13 |
3 files changed, 60 insertions, 19 deletions
diff --git a/src/sp_sloppy.c b/src/sp_sloppy.c index ac0cb8a..695d2a3 100644 --- a/src/sp_sloppy.c +++ b/src/sp_sloppy.c | |||
| @@ -36,48 +36,57 @@ ZEND_API zend_op_array* sp_compile_file(zend_file_handle* file_handle, | |||
| 36 | return opline; | 36 | return opline; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static void array_handler(INTERNAL_FUNCTION_PARAMETERS, | 39 | |
| 40 | const char *name, size_t size, | 40 | static void array_handler(INTERNAL_FUNCTION_PARAMETERS, const char* name, |
| 41 | zif_handler orig_handler) { | 41 | size_t size, zif_handler orig_handler, |
| 42 | const char* spec) { | ||
| 42 | zif_handler handler; | 43 | zif_handler handler; |
| 43 | zval func_name; | 44 | zval func_name; |
| 44 | zval params[3]; | 45 | zval params[3]; |
| 45 | zval *value, *array; | 46 | zval *value, *array = NULL; |
| 46 | zend_bool strict; | 47 | zend_bool strict = 1; |
| 47 | 48 | ||
| 48 | memset(¶ms, 0, sizeof(params)); | 49 | memset(¶ms, 0, sizeof(params)); |
| 49 | zend_parse_parameters(ZEND_NUM_ARGS(), "zz|b", &value, &array, &strict); | 50 | |
| 51 | zend_parse_parameters(ZEND_NUM_ARGS(), spec, &value, &array, &strict); | ||
| 50 | 52 | ||
| 51 | ZVAL_COPY(¶ms[0], value); | 53 | ZVAL_COPY(¶ms[0], value); |
| 52 | ZVAL_COPY(¶ms[1], array); | 54 | if (array) { |
| 53 | ZVAL_BOOL(¶ms[2], 1); | 55 | ZVAL_COPY(¶ms[1], array); |
| 56 | ZVAL_BOOL(¶ms[2], 1); | ||
| 57 | } else { | ||
| 58 | // if there is no array as parameter, don't set strict mode. | ||
| 59 | // check php's implementation for details. | ||
| 60 | ZVAL_BOOL(¶ms[2], 0); | ||
| 61 | } | ||
| 62 | |||
| 54 | ZVAL_STRING(&func_name, name); | 63 | ZVAL_STRING(&func_name, name); |
| 55 | 64 | ||
| 56 | handler = zend_hash_str_find_ptr( | 65 | handler = zend_hash_str_find_ptr(SNUFFLEUPAGUS_G(sp_internal_functions_hook), |
| 57 | SNUFFLEUPAGUS_G(sp_internal_functions_hook), name, size); | 66 | name, size); |
| 58 | zend_internal_function *func = zend_hash_str_find_ptr( | 67 | zend_internal_function* func = |
| 59 | CG(function_table), name, size); | 68 | zend_hash_str_find_ptr(CG(function_table), name, size); |
| 60 | func->handler = handler; | 69 | func->handler = handler; |
| 61 | 70 | ||
| 62 | call_user_function(CG(function_table), NULL, &func_name, | 71 | call_user_function(CG(function_table), NULL, &func_name, return_value, 3, |
| 63 | return_value, 3, params); | 72 | params); |
| 64 | 73 | ||
| 65 | func->handler = orig_handler; | 74 | func->handler = orig_handler; |
| 66 | } | 75 | } |
| 67 | 76 | ||
| 68 | PHP_FUNCTION(sp_in_array) { | 77 | PHP_FUNCTION(sp_in_array) { |
| 69 | array_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, "in_array", | 78 | array_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, "in_array", |
| 70 | sizeof("in_array") - 1, PHP_FN(sp_in_array)); | 79 | sizeof("in_array") - 1, PHP_FN(sp_in_array), "zz|b"); |
| 71 | } | 80 | } |
| 72 | 81 | ||
| 73 | PHP_FUNCTION(sp_array_search) { | 82 | PHP_FUNCTION(sp_array_search) { |
| 74 | array_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, "array_search", | 83 | array_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, "array_search", |
| 75 | sizeof("array_search") - 1, PHP_FN(sp_array_search)); | 84 | sizeof("array_search") - 1, PHP_FN(sp_array_search), "zz|b"); |
| 76 | } | 85 | } |
| 77 | 86 | ||
| 78 | PHP_FUNCTION(sp_array_keys) { | 87 | PHP_FUNCTION(sp_array_keys) { |
| 79 | array_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, "array_keys", | 88 | array_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, "array_keys", |
| 80 | sizeof("array_keys") - 1, PHP_FN(sp_array_keys)); | 89 | sizeof("array_keys") - 1, PHP_FN(sp_array_keys), "z|zb"); |
| 81 | } | 90 | } |
| 82 | 91 | ||
| 83 | void hook_sloppy() { | 92 | void hook_sloppy() { |
| @@ -94,6 +103,8 @@ void hook_sloppy() { | |||
| 94 | } | 103 | } |
| 95 | 104 | ||
| 96 | HOOK_FUNCTION("in_array", sp_internal_functions_hook, PHP_FN(sp_in_array)); | 105 | HOOK_FUNCTION("in_array", sp_internal_functions_hook, PHP_FN(sp_in_array)); |
| 97 | HOOK_FUNCTION("array_search", sp_internal_functions_hook, PHP_FN(sp_array_search)); | 106 | HOOK_FUNCTION("array_search", sp_internal_functions_hook, |
| 98 | HOOK_FUNCTION("array_keys", sp_internal_functions_hook, PHP_FN(sp_array_keys)); | 107 | PHP_FN(sp_array_search)); |
| 108 | HOOK_FUNCTION("array_keys", sp_internal_functions_hook, | ||
| 109 | PHP_FN(sp_array_keys)); | ||
| 99 | } | 110 | } |
diff --git a/src/tests/sloppy_comparison_array_keys.phpt b/src/tests/sloppy_comparison_array_keys.phpt index 4adcbdb..934f3ba 100644 --- a/src/tests/sloppy_comparison_array_keys.phpt +++ b/src/tests/sloppy_comparison_array_keys.phpt | |||
| @@ -10,6 +10,15 @@ $qwe = array(rand(1,2), "qwe"); | |||
| 10 | var_dump(array_keys($qwe, 0)); | 10 | var_dump(array_keys($qwe, 0)); |
| 11 | var_dump(array_keys($qwe, 0, 0)); | 11 | var_dump(array_keys($qwe, 0, 0)); |
| 12 | var_dump(array_keys($qwe, 0, 1)); | 12 | var_dump(array_keys($qwe, 0, 1)); |
| 13 | |||
| 14 | $toto = [ | ||
| 15 | "toto" => 1, | ||
| 16 | "titi" => 2, | ||
| 17 | "tata" => 3, | ||
| 18 | ]; | ||
| 19 | |||
| 20 | var_dump(array_keys($toto)); | ||
| 21 | |||
| 13 | ?> | 22 | ?> |
| 14 | --EXPECT-- | 23 | --EXPECT-- |
| 15 | array(0) { | 24 | array(0) { |
| @@ -18,3 +27,11 @@ array(0) { | |||
| 18 | } | 27 | } |
| 19 | array(0) { | 28 | array(0) { |
| 20 | } | 29 | } |
| 30 | array(3) { | ||
| 31 | [0]=> | ||
| 32 | string(4) "toto" | ||
| 33 | [1]=> | ||
| 34 | string(4) "titi" | ||
| 35 | [2]=> | ||
| 36 | string(4) "tata" | ||
| 37 | } | ||
diff --git a/src/tests/sloppy_comparison_array_search_keys.phpt b/src/tests/sloppy_comparison_array_search_keys.phpt new file mode 100644 index 0000000..031708b --- /dev/null +++ b/src/tests/sloppy_comparison_array_search_keys.phpt | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | --TEST-- | ||
| 2 | Sloppy comparison array_search with keys | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) print "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/sloppy_comparison.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | $array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red'); | ||
| 10 | var_dump(array_search('green', $array)); | ||
| 11 | ?> | ||
| 12 | --EXPECT-- | ||
| 13 | int(2) | ||
