From 1f38d98134b87ff87625c212d01ff29494ff5503 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 2 Sep 2013 15:01:22 +0200 Subject: [PATCH 1/2] Initial named args implementation --- Zend/tests/arg_unpack/string_keys.phpt | 20 - Zend/tests/named_args/basic.phpt | 58 + Zend/tests/named_args/by_ref.phpt | 87 + Zend/tests/named_args/func_get_args.phpt | 113 ++ Zend/tests/named_args/internal.phpt | 111 ++ ...verwriting_already_passed_arg_warning.phpt | 32 + .../positional_arg_after_named_arg_error.phpt | 10 + .../named_args/unknown_named_arg_error.phpt | 12 + Zend/tests/named_args/unpack_named_args.phpt | 135 ++ .../tests/named_args/variadic_named_args.phpt | 71 + Zend/zend_API.c | 226 ++- Zend/zend_API.h | 3 + Zend/zend_builtin_functions.c | 99 +- Zend/zend_compile.c | 121 +- Zend/zend_compile.h | 12 +- Zend/zend_execute.c | 115 +- Zend/zend_execute.h | 11 +- Zend/zend_language_parser.y | 16 +- Zend/zend_object_handlers.c | 2 + Zend/zend_opcode.c | 7 +- Zend/zend_vm_def.h | 205 ++- Zend/zend_vm_execute.h | 1401 ++++++++++++----- ext/standard/array.c | 5 +- 23 files changed, 2282 insertions(+), 590 deletions(-) delete mode 100644 Zend/tests/arg_unpack/string_keys.phpt create mode 100644 Zend/tests/named_args/basic.phpt create mode 100644 Zend/tests/named_args/by_ref.phpt create mode 100644 Zend/tests/named_args/func_get_args.phpt create mode 100644 Zend/tests/named_args/internal.phpt create mode 100644 Zend/tests/named_args/overwriting_already_passed_arg_warning.phpt create mode 100644 Zend/tests/named_args/positional_arg_after_named_arg_error.phpt create mode 100644 Zend/tests/named_args/unknown_named_arg_error.phpt create mode 100644 Zend/tests/named_args/unpack_named_args.phpt create mode 100644 Zend/tests/named_args/variadic_named_args.phpt diff --git a/Zend/tests/arg_unpack/string_keys.phpt b/Zend/tests/arg_unpack/string_keys.phpt deleted file mode 100644 index 443a8829413dd..0000000000000 --- a/Zend/tests/arg_unpack/string_keys.phpt +++ /dev/null @@ -1,20 +0,0 @@ ---TEST-- -Argument unpacking does not work with string keys (forward compatibility for named args) ---FILE-- - 3, 4]); -var_dump(...new ArrayIterator([1, 2, "foo" => 3, 4])); - -?> ---EXPECTF-- -string(36) "Cannot unpack array with string keys" -int(1) -int(2) -string(42) "Cannot unpack Traversable with string keys" -int(1) -int(2) diff --git a/Zend/tests/named_args/basic.phpt b/Zend/tests/named_args/basic.phpt new file mode 100644 index 0000000000000..0bb95747e5847 --- /dev/null +++ b/Zend/tests/named_args/basic.phpt @@ -0,0 +1,58 @@ +--TEST-- +Basic named arguments +--FILE-- + "A", b => "B"); +test(a => "A", b => "B", c => "C", d => "D", e => "E"); +test(d => "D", a => "A", c => "C", e => "E", b => "B"); +test(d => "D", b => "B", a => "A"); +test(d => "D", b => "B"); +test("A", "B", d => "D"); +test("A", e => "E", b => "B"); + +?> +--EXPECTF-- +string(1) "A" +string(1) "B" +string(1) "c" +string(1) "d" +string(1) "e" +string(1) "A" +string(1) "B" +string(1) "C" +string(1) "D" +string(1) "E" +string(1) "A" +string(1) "B" +string(1) "C" +string(1) "D" +string(1) "E" +string(1) "A" +string(1) "B" +string(1) "c" +string(1) "D" +string(1) "e" + +Warning: Missing argument 1 for test(), called in %s on line %d and defined in %s on line %d + +Notice: Undefined variable: a in %s on line %d +NULL +string(1) "B" +string(1) "c" +string(1) "D" +string(1) "e" +string(1) "A" +string(1) "B" +string(1) "c" +string(1) "D" +string(1) "e" +string(1) "A" +string(1) "B" +string(1) "c" +string(1) "d" +string(1) "E" diff --git a/Zend/tests/named_args/by_ref.phpt b/Zend/tests/named_args/by_ref.phpt new file mode 100644 index 0000000000000..11a9108b40d1d --- /dev/null +++ b/Zend/tests/named_args/by_ref.phpt @@ -0,0 +1,87 @@ +--TEST-- +Named arguments respect by-reference passing semantics +--FILE-- + $a1, b => $b1, c => $c1, d => $d1); +var_dump($b1, $d1); + +test(c => $c2, b => $b2, d => $d2, a => $a1); +var_dump($b2, $d2); + +test(b => $b3, d => $d3); +var_dump($b3, $d3); + +$arr1 = []; +test(c => $arr1['c'], b => $arr1['b'], d => $arr1['d'], a => $arr1['a']); +var_dump($arr1); + +$test = 'test'; +$arr2 = []; +test(c => $arr2['c'], b => $arr2['b'], d => $arr2['d'], a => $arr2['a']); +var_dump($arr2); + +?> +--EXPECTF-- +Notice: Undefined variable: a1 in %s on line %d + +Notice: Undefined variable: c1 in %s on line %d +NULL +NULL +NULL +NULL +int(1) +int(1) + +Notice: Undefined variable: c2 in %s on line %d + +Notice: Undefined variable: a1 in %s on line %d +NULL +NULL +NULL +NULL +int(1) +int(1) + +Warning: Missing argument 1 for test(), called in %s on line %d and defined in %s on line %d + +Notice: Undefined variable: a in %s on line %d +NULL +NULL +int(0) +NULL +int(1) +int(1) + +Notice: Undefined index: c in %s on line %d + +Notice: Undefined index: a in %s on line %d +NULL +NULL +NULL +NULL +array(2) { + ["b"]=> + int(1) + ["d"]=> + int(1) +} + +Notice: Undefined index: c in %s on line %d + +Notice: Undefined index: a in %s on line %d +NULL +NULL +NULL +NULL +array(2) { + ["b"]=> + int(1) + ["d"]=> + int(1) +} diff --git a/Zend/tests/named_args/func_get_args.phpt b/Zend/tests/named_args/func_get_args.phpt new file mode 100644 index 0000000000000..e8d4f0b594b8f --- /dev/null +++ b/Zend/tests/named_args/func_get_args.phpt @@ -0,0 +1,113 @@ +--TEST-- +func_get_args() skips arguments that weren't passed +--FILE-- + "C", a => "A"); +test(c => "C", a => "A", d => "D"); +test(c => "C", b => "B"); +test(c => "C"); + +function test2($a = FOO, $b = [FOO, BAR], $c = null) { + var_dump(func_get_args()); + var_dump(func_get_arg(0), func_get_arg(1), func_get_arg(2)); +} + +define('FOO', 'FOO value'); +define('BAR', 'BAR value'); + +test2(c => 42); + +?> +--EXPECTF-- +array(3) { + [0]=> + string(1) "A" + [1]=> + string(1) "b" + [2]=> + string(1) "C" +} + +Warning: func_get_arg(): Argument 3 not passed to function in %s on line %d +string(1) "A" +string(1) "b" +string(1) "C" +bool(false) +int(3) +array(3) { + [0]=> + string(1) "A" + [1]=> + string(1) "b" + [2]=> + string(1) "C" +} + +Warning: func_get_arg(): Argument 3 not passed to function in %s on line %d +string(1) "A" +string(1) "b" +string(1) "C" +bool(false) +int(3) + +Warning: Missing argument 1 for test(), called in %s on line %d and defined in %s on line %d +array(3) { + [0]=> + NULL + [1]=> + string(1) "B" + [2]=> + string(1) "C" +} + +Warning: func_get_arg(): Argument 3 not passed to function in %s on line %d +NULL +string(1) "B" +string(1) "C" +bool(false) +int(3) + +Warning: Missing argument 1 for test(), called in %s on line %d and defined in %s on line %d +array(3) { + [0]=> + NULL + [1]=> + string(1) "b" + [2]=> + string(1) "C" +} + +Warning: func_get_arg(): Argument 3 not passed to function in %s on line %d +NULL +string(1) "b" +string(1) "C" +bool(false) +int(3) +array(3) { + [0]=> + string(9) "FOO value" + [1]=> + array(2) { + [0]=> + string(9) "FOO value" + [1]=> + string(9) "BAR value" + } + [2]=> + int(42) +} +string(9) "FOO value" +array(2) { + [0]=> + string(9) "FOO value" + [1]=> + string(9) "BAR value" +} +int(42) diff --git a/Zend/tests/named_args/internal.phpt b/Zend/tests/named_args/internal.phpt new file mode 100644 index 0000000000000..20867467f3cce --- /dev/null +++ b/Zend/tests/named_args/internal.phpt @@ -0,0 +1,111 @@ +--TEST-- +Named arguments work with internal functions +--FILE-- + 0, num => 3, val => 42)); +var_dump(array_fill(val => 42, start_key => 1, num => 2)); +var_dump(array_fill(2, val => 42, num => 1)); + +// array_slice(array $input, int $offset, int $length = NULL, bool $preserve_keys = false) + +var_dump(array_slice(arg => [1, 2, 3, 4, 5], offset => 2, length => 2)); +var_dump(array_slice(length => 2, offset => 2, arg => [1, 2, 3, 4, 5])); +var_dump(array_slice(arg => ['a' => 0, 'b' => 1], offset => 1, preserve_keys => true)); +var_dump(array_slice(['a' => 0, 'b' => 1], preserve_keys => true, offset => 1)); + +// missing required arg: +var_dump(array_slice(offset => 2)); + +// by_ref: +// array_splice(array &$input, int $offset, int $length = 0, mixed $replacement = []) + +$array = [1, 2, 3, 4, 5]; +var_dump(array_splice(replacement => ["3", "4"], offset => 2, arg => $array)); +var_dump($array); + +$array = [1, 2, 3, 4, 5]; +var_dump(array_splice($array, 2, replacement => ["3", "4"])); +var_dump($array); + +?> +--EXPECTF-- +array(3) { + [0]=> + int(42) + [1]=> + int(42) + [2]=> + int(42) +} +array(2) { + [1]=> + int(42) + [2]=> + int(42) +} +array(1) { + [2]=> + int(42) +} +array(2) { + [0]=> + int(3) + [1]=> + int(4) +} +array(2) { + [0]=> + int(3) + [1]=> + int(4) +} +array(1) { + ["b"]=> + int(1) +} +array(1) { + ["b"]=> + int(1) +} + +Warning: Parameter 1 missing for array_slice() in %s on line %d +NULL +array(3) { + [0]=> + int(3) + [1]=> + int(4) + [2]=> + int(5) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(1) "3" + [3]=> + string(1) "4" +} +array(3) { + [0]=> + int(3) + [1]=> + int(4) + [2]=> + int(5) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(1) "3" + [3]=> + string(1) "4" +} diff --git a/Zend/tests/named_args/overwriting_already_passed_arg_warning.phpt b/Zend/tests/named_args/overwriting_already_passed_arg_warning.phpt new file mode 100644 index 0000000000000..aca4081b87d59 --- /dev/null +++ b/Zend/tests/named_args/overwriting_already_passed_arg_warning.phpt @@ -0,0 +1,32 @@ +--TEST-- +A warning is raised if you try to overwrite a argument that was already passed +--FILE-- + 1, a => 2, b => 3); +test(b => 1, a => 2, a => 3); +test(b => 1, b => 2, b => 3); + +?> +--EXPECTF-- +Warning: Overwriting already passed parameter 1 ($a) in %s on line %d +int(2) +int(3) + +Warning: Overwriting already passed parameter 1 ($a) in %s on line %d +int(3) +int(1) + +Warning: Overwriting already passed parameter 2 ($b) in %s on line %d + +Warning: Overwriting already passed parameter 2 ($b) in %s on line %d + +Warning: Missing argument 1 for test(), called in %s on line %d and defined in %s on line %d + +Notice: Undefined variable: a in %s on line %d +NULL +int(3) diff --git a/Zend/tests/named_args/positional_arg_after_named_arg_error.phpt b/Zend/tests/named_args/positional_arg_after_named_arg_error.phpt new file mode 100644 index 0000000000000..5e98e7b49401c --- /dev/null +++ b/Zend/tests/named_args/positional_arg_after_named_arg_error.phpt @@ -0,0 +1,10 @@ +--TEST-- +Positional arguments cannot be used after named arguments +--FILE-- + "foobar", "bar"); + +?> +--EXPECTF-- +Fatal error: Cannot pass positional arguments after named arguments in %s on line %d diff --git a/Zend/tests/named_args/unknown_named_arg_error.phpt b/Zend/tests/named_args/unknown_named_arg_error.phpt new file mode 100644 index 0000000000000..9f0c4181504cd --- /dev/null +++ b/Zend/tests/named_args/unknown_named_arg_error.phpt @@ -0,0 +1,12 @@ +--TEST-- +Unknown named arguments to non-variadic functions throw a fatal error +--FILE-- + 42); + +?> +--EXPECTF-- +Fatal error: Unknown named argument $tets in %s on line %d diff --git a/Zend/tests/named_args/unpack_named_args.phpt b/Zend/tests/named_args/unpack_named_args.phpt new file mode 100644 index 0000000000000..88922b67aa549 --- /dev/null +++ b/Zend/tests/named_args/unpack_named_args.phpt @@ -0,0 +1,135 @@ +--TEST-- +Unpacking named args +--FILE-- + $v) yield $k => $v; +} +function gen2() { + yield [1, 2, 3] => "a"; + yield 3.14 => "b"; + yield "c" => "C"; + yield "d" => "D"; +} + +test(...["a", "b", "c" => "C", "d" => "D"]); +test(...["a", "c" => "C", "d" => "D", "b"]); +test("a", ...["b", "c" => "C", "d" => "D"]); +test(a => "A", ...["b", "c" => "C", "d" => "D"]); +test(...["a", "a" => "A"]); + +test(...gen(["a", "b", "c" => "C", "d" => "D"])); +test(...gen(["c" => "C", "d" => "D", "a", "b"])); +test("a", ...gen(["b", "c" => "C", "d" => "D"])); +test(...gen2()); + +test2("a", "b", ...["c" => "C"]); +test2(b => "B", ...["c" => "C", "a" => "A"]); +test2(c => "C", ...["a", "b"]); + +?> +--EXPECTF-- +string(1) "a" +array(3) { + [0]=> + string(1) "b" + ["c"]=> + string(1) "C" + ["d"]=> + string(1) "D" +} + +Warning: Cannot pass positional arguments after named arguments. Aborting argument unpacking in %s on line %d +string(1) "a" +array(2) { + ["c"]=> + string(1) "C" + ["d"]=> + string(1) "D" +} +string(1) "a" +array(3) { + [0]=> + string(1) "b" + ["c"]=> + string(1) "C" + ["d"]=> + string(1) "D" +} + +Warning: Cannot pass positional arguments after named arguments. Aborting argument unpacking in %s on line %d +string(1) "A" +array(0) { +} + +Warning: Overwriting already passed parameter 1 ($a) in %s on line %d +string(1) "A" +array(0) { +} +string(1) "a" +array(3) { + [0]=> + string(1) "b" + ["c"]=> + string(1) "C" + ["d"]=> + string(1) "D" +} + +Warning: Cannot pass positional arguments after named arguments. Aborting argument unpacking in %s on line %d + +Warning: Missing argument 1 for test(), called in %s on line %d and defined in %s on line %d + +Notice: Undefined variable: a in %s on line %d +NULL +array(2) { + ["c"]=> + string(1) "C" + ["d"]=> + string(1) "D" +} +string(1) "a" +array(3) { + [0]=> + string(1) "b" + ["c"]=> + string(1) "C" + ["d"]=> + string(1) "D" +} +string(1) "a" +array(3) { + [0]=> + string(1) "b" + ["c"]=> + string(1) "C" + ["d"]=> + string(1) "D" +} +string(1) "a" +string(1) "b" +string(1) "C" +string(1) "A" +string(1) "B" +string(1) "C" + +Warning: Cannot pass positional arguments after named arguments. Aborting argument unpacking in %s on line %d + +Warning: Missing argument 1 for test2(), called in %s on line %d and defined in %s on line %d + +Warning: Missing argument 2 for test2(), called in %s on line %d and defined in %s on line %d + +Notice: Undefined variable: a in %s on line %d + +Notice: Undefined variable: b in %s on line %d +NULL +NULL +string(1) "C" diff --git a/Zend/tests/named_args/variadic_named_args.phpt b/Zend/tests/named_args/variadic_named_args.phpt new file mode 100644 index 0000000000000..f2b732cf1584e --- /dev/null +++ b/Zend/tests/named_args/variadic_named_args.phpt @@ -0,0 +1,71 @@ +--TEST-- +Collecting unknown named arguments in a variadic function +--FILE-- + "a", b => "b", c => "c"); +test(c => "c", b => "b", a => "a"); +test(c => "c", b => "b"); +test("a", b => "b", b => "B"); +test("a", "b", "c", e => "e", d => "d"); + +function test2(&...$opts) { + foreach ($opts as $name => &$opt) { + $opt = $name; + } +} + +test2(b => $b, a => $a); +var_dump($a, $b); + +?> +--EXPECTF-- +string(1) "a" +array(2) { + ["b"]=> + string(1) "b" + ["c"]=> + string(1) "c" +} +string(1) "a" +array(2) { + ["c"]=> + string(1) "c" + ["b"]=> + string(1) "b" +} + +Warning: Missing argument 1 for test(), called in %s on line %d and defined in %s on line %d + +Notice: Undefined variable: a in %s on line %d +NULL +array(2) { + ["c"]=> + string(1) "c" + ["b"]=> + string(1) "b" +} + +Warning: Overwriting already passed parameter $b in %s on line %d +string(1) "a" +array(1) { + ["b"]=> + string(1) "B" +} +string(1) "a" +array(4) { + [0]=> + string(1) "b" + [1]=> + string(1) "c" + ["e"]=> + string(1) "e" + ["d"]=> + string(1) "d" +} +string(1) "a" +string(1) "b" diff --git a/Zend/zend_API.c b/Zend/zend_API.c index ed13c6a7d6031..58a5a66459839 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -97,7 +97,7 @@ ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval **argument while (param_count-->0) { param_ptr = *(p-arg_count); - if (!PZVAL_IS_REF(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) { + if (param_ptr != NULL && !PZVAL_IS_REF(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) { zval *new_tmp; ALLOC_ZVAL(new_tmp); @@ -167,6 +167,32 @@ ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_arr } /* }}} */ +ZEND_API int zend_get_parameters_array_nodefault(int param_count, zval ***argument_array TSRMLS_DC) /* {{{ */ +{ + void **p; + int arg_count; + + p = zend_vm_stack_top(TSRMLS_C) - 1; + arg_count = (int)(zend_uintptr_t) *p; + + if (param_count>arg_count) { + return FAILURE; + } + + while (param_count-->0) { + zval **value = (zval**)(p-arg_count); + if(*value == NULL) { + // defaults not allowed + return FAILURE; + } + *(argument_array++) = value; + arg_count--; + } + + return SUCCESS; +} +/* }}} */ + ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TSRMLS_DC) /* {{{ */ { void **p; @@ -302,6 +328,112 @@ static int parse_arg_object_to_string(zval **arg, char **p, int *pl, int type TS } /* }}} */ +static void zend_parse_arg_skip(va_list *va, const char **spec TSRMLS_DC) /* {{{ */ +{ + /* Just a first idea of how argument skipping should work. In this implementation I'm not + * touching values at all, unless check_null is specified, in which case I do the appropriate + * logic. This likely is not the optimal approach, because code may rely on values being set + * if later values are set. */ + const char *spec_walk = *spec; + char c = *spec_walk++; + zend_bool check_null = 0; + + if (*spec_walk == '!') { + check_null = 1; + spec_walk++; + } + + switch (c) { + case 'l': + case 'L': { + va_arg(*va, long *); + if (check_null) { + zend_bool *p = va_arg(*va, zend_bool *); + *p = 1; + } + break; + } + case 'd': { + va_arg(*va, double *); + if (check_null) { + zend_bool *p = va_arg(*va, zend_bool *); + *p = 1; + } + break; + } + case 'p': + case 's': { + char **p = va_arg(*va, char **); + int *pl = va_arg(*va, int *); + if (check_null) { + *p = NULL; + *pl = 0; + } + break; + } + case 'b': { + va_arg(*va, zend_bool *); + if (check_null) { + zend_bool *p = va_arg(*va, zend_bool *); + *p = 1; + } + break; + } + case 'r': + case 'A': + case 'a': + case 'o': + case 'z': { + zval **p = va_arg(*va, zval **); + if (check_null) { + *p = NULL; + } + break; + } + case 'H': + case 'h': { + HashTable **p = va_arg(*va, HashTable **); + if (check_null) { + *p = NULL; + } + break; + } + case 'O': { + zval **p = va_arg(*va, zval **); + va_arg(*va, zend_class_entry *); + if (check_null) { + *p = NULL; + } + break; + } + case 'C': { + zend_class_entry **p = va_arg(*va, zend_class_entry **); + if (check_null) { + *p = NULL; + } + break; + } + case 'f': { + zend_fcall_info *fci = va_arg(*va, zend_fcall_info *); + zend_fcall_info_cache *fcc = va_arg(*va, zend_fcall_info_cache *); + if (check_null) { + fci->size = 0; + fcc->initialized = 0; + } + break; + } + case 'Z': { + zval ***p = va_arg(*va, zval ***); + if (check_null) { + *p = NULL; + } + break; + } + } + + *spec = spec_walk; +} + static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, const char **spec, char **error, int *severity TSRMLS_DC) /* {{{ */ { const char *spec_walk = *spec; @@ -739,6 +871,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, zend_bool have_varargs = 0; zval ****varargs = NULL; int *n_varargs = NULL; + int disallow_default = flags & ZEND_PARSE_PARAMS_NODEFAULT; for (spec_walk = type_spec; *spec_walk; spec_walk++) { c = *spec_walk; @@ -834,6 +967,8 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, i = 0; while (num_args-- > 0) { + int parse_failed; + if (*type_spec == '|') { type_spec++; } @@ -850,17 +985,40 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, int iv = 0; zval **p = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count - i)); - *n_varargs = num_varargs; + num_args -= num_varargs-1; /* adjust how many args we've left after varargs, -1 because we already subtracted 1 above */ + i += num_varargs; /* put loop counter after varargs */ /* allocate space for array and store args */ *varargs = safe_emalloc(num_varargs, sizeof(zval **), 0); - while (num_varargs-- > 0) { - (*varargs)[iv++] = p++; + for (;num_varargs-- > 0;p++) { + if(*p == NULL) { + /* skipped arg - not counting in varargs */ + continue; + } + (*varargs)[iv++] = p; + } + if(iv == 0) { + efree(*varargs); + *varargs = NULL; + + if(type_spec[-1] == '+') { + if (!quiet) { + zend_function *active_function = EG(current_execute_data)->function_state.function; + const char *class_name = active_function->common.scope ? active_function->common.scope->name : ""; + zend_error(E_WARNING, "%s%s%s() expects %s %d parameter%s, %d given", + class_name, + class_name[0] ? "::" : "", + active_function->common.function_name, + min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most", + num_args < min_num_args ? min_num_args : max_num_args, + (num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s", + num_args); + } + return FAILURE; + } } - /* adjust how many args we have left and restart loop */ - num_args = num_args + 1 - iv; - i += iv; + *n_varargs = iv; continue; } else { *varargs = NULL; @@ -870,7 +1028,29 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, arg = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count-i)); - if (zend_parse_arg(i+1, arg, va, &type_spec, quiet TSRMLS_CC) == FAILURE) { + parse_failed = 0; + if (*arg == NULL) { + /* we have skipped arg */ + if (i < min_num_args || disallow_default || type_spec[1] == '/') { + /* this is one of the required args or skipping is prohibited or we'd need to write there */ + if (!quiet) { + zend_function *active_function = EG(current_execute_data)->function_state.function; + const char *class_name = active_function->common.scope ? active_function->common.scope->name : ""; + zend_error(E_WARNING, "Parameter %d missing for %s%s%s()", + i+1, + class_name, + class_name[0] ? "::" : "", + active_function->common.function_name); + } + parse_failed = 1; + } else { + i++; + zend_parse_arg_skip(va, &type_spec TSRMLS_CC); + continue; + } + } + + if (parse_failed || zend_parse_arg(i+1, arg, va, &type_spec, quiet TSRMLS_CC) == FAILURE) { /* clean up varargs array if it was used */ if (varargs && *varargs) { efree(*varargs); @@ -2069,6 +2249,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio internal_function->function_name = (char*)ptr->fname; internal_function->scope = scope; internal_function->prototype = NULL; + internal_function->arg_offsets = NULL; if (ptr->flags) { if (!(ptr->flags & ZEND_ACC_PPP_MASK)) { if (ptr->flags != ZEND_ACC_DEPRECATED || scope) { @@ -2886,6 +3067,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca fcc->function_handler->internal_function.module = (ce_org->type == ZEND_INTERNAL_CLASS) ? ce_org->info.internal.module : NULL; fcc->function_handler->internal_function.handler = zend_std_call_user_call; fcc->function_handler->internal_function.arg_info = NULL; + fcc->function_handler->internal_function.arg_offsets = NULL; fcc->function_handler->internal_function.num_args = 0; fcc->function_handler->internal_function.scope = ce_org; fcc->function_handler->internal_function.fn_flags = ZEND_ACC_CALL_VIA_HANDLER; @@ -4052,6 +4234,34 @@ ZEND_API const char* zend_resolve_method_name(zend_class_entry *ce, zend_functio } /* }}} */ +ZEND_API int zend_get_arg_num(zend_uint *arg_num_target, zend_function *fn, char *name, int name_len, zend_ulong hash_value TSRMLS_DC) /* {{{ */ +{ + HashTable *arg_offsets = fn->common.arg_offsets; + if (arg_offsets == NULL) { + zend_arg_info *arg_info = fn->common.arg_info; + zend_uint i, num_args = fn->common.num_args; + + arg_offsets = pemalloc(sizeof(HashTable), fn->type != ZEND_USER_FUNCTION); + zend_hash_init(arg_offsets, num_args, NULL, NULL, fn->type != ZEND_USER_FUNCTION); + for (i = 0; i < num_args; ++i) { + zend_hash_update(arg_offsets, arg_info[i].name, arg_info[i].name_len + 1, &i, sizeof(zend_uint), NULL); + } + + fn->common.arg_offsets = arg_offsets; + } + + { + zend_uint *arg_num; + if (zend_hash_find(arg_offsets, name, name_len + 1, (void **) &arg_num) == SUCCESS) { + *arg_num_target = *arg_num + 1; + return SUCCESS; + } else { + return FAILURE; + } + } +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_API.h b/Zend/zend_API.h index efc267f918e61..c12cc2a5b75eb 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -240,6 +240,7 @@ ZEND_API int zend_get_parameters(int ht, int param_count, ...); ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval **argument_array TSRMLS_DC); ZEND_API ZEND_ATTRIBUTE_DEPRECATED int zend_get_parameters_ex(int param_count, ...); ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_array TSRMLS_DC); +ZEND_API int zend_get_parameters_array_nodefault(int param_count, zval ***argument_array TSRMLS_DC); /* internal function to efficiently copy parameters when executing __call() */ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TSRMLS_DC); @@ -254,6 +255,7 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TS /* Parameter parsing API -- andrei */ #define ZEND_PARSE_PARAMS_QUIET 1<<1 +#define ZEND_PARSE_PARAMS_NODEFAULT 1<<2 ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, const char *type_spec, ...); ZEND_API int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, const char *type_spec, ...); ZEND_API char *zend_zval_type_name(const zval *arg); @@ -526,6 +528,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D); ZEND_API const char* zend_find_alias_name(zend_class_entry *ce, const char *name, zend_uint len); ZEND_API const char* zend_resolve_method_name(zend_class_entry *ce, zend_function *f); +ZEND_API int zend_get_arg_num(zend_uint *arg_num_target, zend_function *fn, char *name, int name_len, zend_ulong hash_value TSRMLS_DC); #define add_method(arg, key, method) add_assoc_function((arg), (key), (method)) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 6bfb888988d6a..fe632b234f049 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -386,6 +386,48 @@ ZEND_FUNCTION(gc_disable) } /* }}} */ +static zval *zend_get_arg_default_value_ex(zend_op_array *op_array, zend_uint arg_num, zend_op **start_op_ptr TSRMLS_DC) /* {{{ */ +{ + zend_op *op = *start_op_ptr; + zend_op *end_op = op_array->opcodes + op_array->last; + zval *retval = NULL; + + for (; op < end_op; ++op) { + if ((op->opcode != ZEND_RECV && op->opcode != ZEND_RECV_INIT) || op->op1.num != arg_num) { + continue; + } + + if (op->opcode == ZEND_RECV_INIT) { + MAKE_STD_ZVAL(retval); + ZVAL_COPY_VALUE(retval, op->op2.zv); + + if ((Z_TYPE_P(retval) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT + || Z_TYPE_P(retval) == IS_CONSTANT_ARRAY + ) { + zval_update_constant_no_inline_change(&retval, op_array->scope TSRMLS_CC); + } else { + zval_copy_ctor(retval); + } + } + break; + } + + *start_op_ptr = op; + return retval; +} +/* }}} */ + +static zval *zend_get_arg_default_value(zend_function *fn, zend_uint arg_num TSRMLS_DC) /* {{{ */ +{ + if (fn->type == ZEND_USER_FUNCTION) { + zend_op *start_op = fn->op_array.opcodes; + return zend_get_arg_default_value_ex(&fn->op_array, arg_num, &start_op TSRMLS_CC); + } + + return NULL; +} +/* }}} */ + /* {{{ proto int func_num_args(void) Get the number of arguments that were passed to the function */ ZEND_FUNCTION(func_num_args) @@ -406,11 +448,10 @@ ZEND_FUNCTION(func_num_args) Get the $arg_num'th argument that was passed to the function */ ZEND_FUNCTION(func_get_arg) { - void **p; - int arg_count; - zval *arg; + zval **arg; long requested_offset; zend_execute_data *ex = EG(current_execute_data)->prev_execute_data; + zend_uint arg_count; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &requested_offset) == FAILURE) { return; @@ -426,16 +467,21 @@ ZEND_FUNCTION(func_get_arg) RETURN_FALSE; } - p = ex->function_state.arguments; - arg_count = (int)(zend_uintptr_t) *p; /* this is the amount of arguments passed to func_get_arg(); */ - + arg_count = zend_vm_stack_get_args_count(TSRMLS_C); if (requested_offset >= arg_count) { zend_error(E_WARNING, "func_get_arg(): Argument %ld not passed to function", requested_offset); RETURN_FALSE; } - arg = *(p-(arg_count-requested_offset)); - RETURN_ZVAL_FAST(arg); + arg = zend_vm_stack_get_arg(requested_offset + 1 TSRMLS_CC); + if (arg != NULL) { + RETURN_ZVAL_FAST(*arg); + } else { + zval *retval = zend_get_arg_default_value(ex->function_state.function, requested_offset + 1 TSRMLS_CC); + if (retval != NULL) { + RETURN_ZVAL(retval, 0, 1); + } + } } /* }}} */ @@ -445,32 +491,39 @@ ZEND_FUNCTION(func_get_arg) ZEND_FUNCTION(func_get_args) { void **p; - int arg_count; - int i; + zend_uint arg_count, i; zend_execute_data *ex = EG(current_execute_data)->prev_execute_data; + zend_op_array *op_array = NULL; + zend_op *start_op; if (!ex || !ex->function_state.arguments) { zend_error(E_WARNING, "func_get_args(): Called from the global scope - no function context"); RETURN_FALSE; } + if (ex->function_state.function->type == ZEND_USER_FUNCTION) { + op_array = &ex->function_state.function->op_array; + start_op = op_array->opcodes; + } + p = ex->function_state.arguments; - arg_count = (int)(zend_uintptr_t) *p; /* this is the amount of arguments passed to func_get_args(); */ + arg_count = (int)(zend_uintptr_t) *p; array_init_size(return_value, arg_count); - for (i=0; ivalue.ht, &element, sizeof(zval *), NULL); + if (arg != NULL) { + SEPARATE_ARG_IF_REF(arg); + } else if (op_array) { + arg = zend_get_arg_default_value_ex(op_array, i + 1, &start_op TSRMLS_CC); + } + + if (arg == NULL) { + ALLOC_INIT_ZVAL(arg); + } + + zend_hash_next_index_insert(return_value->value.ht, &arg, sizeof(zval *), NULL); } } /* }}} */ diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 1bcd430840b8a..10a9af919d955 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1303,7 +1303,7 @@ void zend_do_begin_variable_parse(TSRMLS_D) /* {{{ */ } /* }}} */ -void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC) /* {{{ */ +void zend_do_end_variable_parse_ex(znode *variable, int type, int arg_offset, zend_bool is_named_arg TSRMLS_DC) /* {{{ */ { zend_llist *fetch_list_ptr; zend_llist_element *le; @@ -1380,6 +1380,9 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS case BP_VAR_FUNC_ARG: opline->opcode += 9; /* 3+3+3 */ opline->extended_value |= arg_offset; + if (is_named_arg) { + opline->extended_value |= ZEND_FETCH_NAMED; + } break; case BP_VAR_UNSET: if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2_type == IS_UNUSED) { @@ -1399,6 +1402,12 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS } /* }}} */ +void zend_do_end_variable_parse(znode *variable, int type, int arg_num TSRMLS_DC) /* {{{ */ +{ + zend_do_end_variable_parse_ex(variable, type, arg_num, 0 TSRMLS_CC); +} +/* }}} */ + void zend_do_add_string(znode *result, const znode *op1, znode *op2 TSRMLS_DC) /* {{{ */ { zend_op *opline; @@ -2566,7 +2575,7 @@ void zend_do_end_function_call(znode *function_name, znode *result, int is_metho opline = &CG(active_op_array)->opcodes[Z_LVAL(function_name->u.constant)]; } else { opline = get_next_op(CG(active_op_array) TSRMLS_CC); - if (fcall->fbc) { + if (fcall->fbc && !fcall->uses_delayed_fcall) { opline->opcode = ZEND_DO_FCALL; SET_NODE(opline->op1, function_name); SET_UNUSED(opline->op2); @@ -2579,10 +2588,9 @@ void zend_do_end_function_call(znode *function_name, znode *result, int is_metho SET_UNUSED(opline->op2); opline->op2.num = --CG(context).nested_calls; - /* This would normally be a ZEND_DO_FCALL, but was forced to use - * ZEND_DO_FCALL_BY_NAME due to a ... argument. In this case we need to - * free the function_name */ - if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) { + /* This would normally be a ZEND_DO_FCALL, but was forced to + * ZEND_DO_FCALL_BY_NAME for argument unpacking or named args. */ + if (fcall->uses_delayed_fcall) { zval_dtor(&function_name->u.constant); } } @@ -2601,41 +2609,80 @@ void zend_do_end_function_call(znode *function_name, znode *result, int is_metho } /* }}} */ -void zend_do_pass_param(znode *param, zend_uchar op TSRMLS_DC) /* {{{ */ +void zend_do_delayed_begin_function_call(zend_function_call_entry *fcall TSRMLS_DC) /* {{{ */ +{ + zval func_name; + zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); + ZVAL_STRING(&func_name, fcall->fbc->common.function_name, 1); + + opline->opcode = ZEND_INIT_FCALL_BY_NAME; + opline->result.num = CG(context).nested_calls; + SET_UNUSED(opline->op1); + opline->op2_type = IS_CONST; + opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &func_name TSRMLS_CC); + GET_CACHE_SLOT(opline->op2.constant); + + ++CG(context).nested_calls; + fcall->uses_delayed_fcall = 1; +} +/* }}} */ + +void zend_do_pass_param(znode *param, zend_uchar op, znode *named_arg TSRMLS_DC) /* {{{ */ { zend_op *opline; int original_op = op; zend_function_call_entry *fcall; - zend_function *function_ptr; + zend_uint arg_num; int send_by_reference = 0; int send_function = 0; zend_stack_top(&CG(function_call_stack), (void **) &fcall); - function_ptr = fcall->fbc; - fcall->arg_num++; if (fcall->uses_argument_unpacking) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use positional argument after argument unpacking"); } + if (named_arg != NULL) { + zend_ulong hash_value = zend_inline_hash_func(Z_STRVAL(named_arg->u.constant), Z_STRLEN(named_arg->u.constant)+1); + + fcall->uses_named_args = 1; + if (fcall->fbc) { + if (!fcall->uses_delayed_fcall) { + zend_do_delayed_begin_function_call(fcall TSRMLS_CC); + } + + if (zend_get_arg_num(&arg_num, fcall->fbc, Z_STRVAL(named_arg->u.constant), Z_STRLEN(named_arg->u.constant), hash_value TSRMLS_CC) == FAILURE) { + if (fcall->fbc->common.fn_flags & ZEND_ACC_VARIADIC) { + arg_num = fcall->fbc->common.num_args; + } else { + zend_error_noreturn(E_COMPILE_ERROR, "Unknown named argument $%s", Z_STRVAL(named_arg->u.constant)); + } + } + } + } else if (fcall->uses_named_args) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot pass positional arguments after named arguments"); + } else { + arg_num = ++fcall->arg_num; + } + if (original_op == ZEND_SEND_REF) { - if (function_ptr && - function_ptr->common.function_name && - function_ptr->common.type == ZEND_USER_FUNCTION && - !ARG_SHOULD_BE_SENT_BY_REF(function_ptr, fcall->arg_num)) { - zend_error_noreturn(E_COMPILE_ERROR, + if (fcall->fbc && + fcall->fbc->common.function_name && + fcall->fbc->common.type == ZEND_USER_FUNCTION && + !ARG_SHOULD_BE_SENT_BY_REF(fcall->fbc, arg_num)) { + zend_error(E_COMPILE_ERROR, "Call-time pass-by-reference has been removed; " "If you would like to pass argument by reference, modify the declaration of %s().", - function_ptr->common.function_name); + fcall->fbc->common.function_name); } else { zend_error_noreturn(E_COMPILE_ERROR, "Call-time pass-by-reference has been removed"); } return; } - if (function_ptr) { - if (ARG_MAY_BE_SENT_BY_REF(function_ptr, fcall->arg_num)) { + if (fcall->fbc) { + if (ARG_MAY_BE_SENT_BY_REF(fcall->fbc, arg_num)) { if (op == ZEND_SEND_VAR && param->op_type & (IS_VAR|IS_CV)) { send_by_reference = ZEND_ARG_SEND_BY_REF; if (zend_is_function_or_method_call(param)) { @@ -2646,7 +2693,7 @@ void zend_do_pass_param(znode *param, zend_uchar op TSRMLS_DC) /* {{{ */ } else { op = ZEND_SEND_VAL; } - } else if (ARG_SHOULD_BE_SENT_BY_REF(function_ptr, fcall->arg_num)) { + } else if (ARG_SHOULD_BE_SENT_BY_REF(fcall->fbc, arg_num)) { send_by_reference = ZEND_ARG_SEND_BY_REF; } } @@ -2678,10 +2725,12 @@ void zend_do_pass_param(znode *param, zend_uchar op TSRMLS_DC) /* {{{ */ zend_do_end_variable_parse(param, BP_VAR_R, 0 TSRMLS_CC); break; case ZEND_SEND_VAR: - if (function_ptr) { + if (fcall->fbc) { zend_do_end_variable_parse(param, BP_VAR_R, 0 TSRMLS_CC); } else { - zend_do_end_variable_parse(param, BP_VAR_FUNC_ARG, fcall->arg_num TSRMLS_CC); + zend_do_end_variable_parse_ex( + param, BP_VAR_FUNC_ARG, fcall->arg_num, named_arg != NULL TSRMLS_CC + ); } break; case ZEND_SEND_REF: @@ -2693,22 +2742,29 @@ void zend_do_pass_param(znode *param, zend_uchar op TSRMLS_DC) /* {{{ */ opline = get_next_op(CG(active_op_array) TSRMLS_CC); if (op == ZEND_SEND_VAR_NO_REF) { - if (function_ptr) { + if (fcall->fbc) { opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND | send_by_reference | send_function; } else { opline->extended_value = send_function; } } else { - if (function_ptr) { + if (fcall->fbc) { opline->extended_value = ZEND_DO_FCALL; } else { opline->extended_value = ZEND_DO_FCALL_BY_NAME; } } + opline->opcode = op; SET_NODE(opline->op1, param); - opline->op2.opline_num = fcall->arg_num; - SET_UNUSED(opline->op2); + opline->result.num = fcall->arg_num; + if (named_arg == NULL) { + SET_UNUSED(opline->op2); + } else { + SET_NODE(opline->op2, named_arg); + CALCULATE_LITERAL_HASH(opline->op2.constant); + GET_POLYMORPHIC_CACHE_SLOT(opline->op2.constant); + } if (++CG(context).used_stack > CG(active_op_array)->used_stack) { CG(active_op_array)->used_stack = CG(context).used_stack; @@ -2728,18 +2784,9 @@ void zend_do_unpack_params(znode *params TSRMLS_DC) /* {{{ */ /* If argument unpacking is used argument numbers and sending modes can no longer be * computed at compile time, thus we need access to EX(call). In order to have it we * retroactively emit a ZEND_INIT_FCALL_BY_NAME opcode. */ - zval func_name; - ZVAL_STRING(&func_name, fcall->fbc->common.function_name, 1); - - opline = get_next_op(CG(active_op_array) TSRMLS_CC); - opline->opcode = ZEND_INIT_FCALL_BY_NAME; - opline->result.num = CG(context).nested_calls; - SET_UNUSED(opline->op1); - opline->op2_type = IS_CONST; - opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &func_name TSRMLS_CC); - GET_CACHE_SLOT(opline->op2.constant); - - ++CG(context).nested_calls; + if (!fcall->uses_delayed_fcall) { + zend_do_delayed_begin_function_call(fcall TSRMLS_CC); + } fcall->fbc = NULL; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 5362058fa266f..265e27b0a74e1 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -274,6 +274,7 @@ struct _zend_op_array { zend_uint num_args; zend_uint required_num_args; zend_arg_info *arg_info; + HashTable *arg_offsets; /* END of common elements */ zend_uint *refcount; @@ -331,6 +332,7 @@ typedef struct _zend_internal_function { zend_uint num_args; zend_uint required_num_args; zend_arg_info *arg_info; + HashTable *arg_offsets; /* END of common elements */ void (*handler)(INTERNAL_FUNCTION_PARAMETERS); @@ -351,6 +353,7 @@ typedef union _zend_function { zend_uint num_args; zend_uint required_num_args; zend_arg_info *arg_info; + HashTable *arg_offsets; } common; zend_op_array op_array; @@ -361,12 +364,15 @@ typedef union _zend_function { typedef struct _zend_function_state { zend_function *function; void **arguments; + HashTable *additional_named_args; } zend_function_state; typedef struct _zend_function_call_entry { zend_function *fbc; zend_uint arg_num; zend_bool uses_argument_unpacking; + zend_bool uses_named_args; + zend_bool uses_delayed_fcall; } zend_function_call_entry; typedef struct _zend_switch_entry { @@ -388,9 +394,11 @@ typedef struct _call_slot { zend_function *fbc; zval *object; zend_class_entry *called_scope; + HashTable *additional_named_args; zend_uint num_additional_args; zend_bool is_ctor_call; zend_bool is_ctor_result_used; + zend_bool uses_named_args; } call_slot; struct _zend_execute_data { @@ -503,6 +511,7 @@ void zend_do_pre_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC void zend_do_post_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC); void zend_do_begin_variable_parse(TSRMLS_D); +void zend_do_end_variable_parse_ex(znode *variable, int type, int arg_offset, zend_bool is_named_arg TSRMLS_DC); void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC); void zend_check_writable_variable(const znode *variable); @@ -559,7 +568,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent void zend_do_early_binding(TSRMLS_D); ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS_DC); -void zend_do_pass_param(znode *param, zend_uchar op TSRMLS_DC); +void zend_do_pass_param(znode *param, zend_uchar op, znode *named_arg TSRMLS_DC); void zend_do_unpack_params(znode *params TSRMLS_DC); @@ -811,6 +820,7 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC); #define ZEND_FETCH_STANDARD 0x00000000 #define ZEND_FETCH_ADD_LOCK 0x08000000 #define ZEND_FETCH_MAKE_REF 0x04000000 +#define ZEND_FETCH_NAMED 0x00400000 #define ZEND_ISSET 0x02000000 #define ZEND_ISEMPTY 0x01000000 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 66accd61e970d..c6114c78430f5 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1628,6 +1628,15 @@ static zend_always_inline zend_execute_data *i_create_execute_data_from_op_array Z_ADDREF_P(arg_dst[i]); } } + + if (EG(current_execute_data)->function_state.additional_named_args) { + ALLOC_HASHTABLE(EX(prev_execute_data)->function_state.additional_named_args); + zend_hash_copy( + EX(prev_execute_data)->function_state.additional_named_args, + EG(current_execute_data)->function_state.additional_named_args, + (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *) + ); + } } else { execute_data = zend_vm_stack_alloc(total_size TSRMLS_CC); execute_data = (zend_execute_data*)((char*)execute_data + Ts_size); @@ -1673,6 +1682,7 @@ static zend_always_inline zend_execute_data *i_create_execute_data_from_op_array EX(function_state).function = (zend_function *) op_array; EX(function_state).arguments = NULL; + EX(function_state).additional_named_args = NULL; return execute_data; } @@ -1684,13 +1694,6 @@ ZEND_API zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array } /* }}} */ -static zend_always_inline zend_bool zend_is_by_ref_func_arg_fetch(zend_op *opline, call_slot *call TSRMLS_DC) /* {{{ */ -{ - zend_uint arg_num = opline->extended_value & ZEND_FETCH_ARG_MASK; - return ARG_SHOULD_BE_SENT_BY_REF(call->fbc, arg_num); -} -/* }}} */ - static void **zend_vm_stack_push_args_with_copy(int count TSRMLS_DC) /* {{{ */ { zend_vm_stack p = EG(argument_stack); @@ -1726,6 +1729,104 @@ static zend_always_inline void** zend_vm_stack_push_args(int count TSRMLS_DC) /* } /* }}} */ +zend_always_inline void zend_init_call_slot(call_slot *call TSRMLS_DC) /* {{{ */ +{ + call->num_additional_args = 0; + call->additional_named_args = NULL; + call->uses_named_args = 0; +} +/* }}} */ + +zend_always_inline void zend_check_for_overwritten_parameter(zend_function *fbc, zend_uint arg_num, void **target TSRMLS_DC) /* {{{ */ +{ + if (*target != NULL) { + zval_ptr_dtor((zval **) target); + zend_error( + E_WARNING, "Overwriting already passed parameter %d ($%s)", + arg_num, fbc->common.arg_info[arg_num - 1].name + ); + } +} +/* }}} */ + +void **zend_handle_named_arg(zend_uint *arg_num_target, call_slot *call, char *name, int name_len, const zend_literal *key, zend_uint orig_arg_num TSRMLS_DC) /* {{{ */ +{ + void **target; + zend_uint arg_num; + int relative_arg_num; + + call->uses_named_args = 1; + if (!key || !(arg_num = (zend_uint) (zend_uintptr_t) CACHED_POLYMORPHIC_PTR(key->cache_slot, call->fbc))) { + zend_ulong hash_value = key ? key->hash_value : zend_inline_hash_func(name, name_len+1); + if (zend_get_arg_num(&arg_num, call->fbc, name, name_len, hash_value TSRMLS_CC) == FAILURE) { + if (call->fbc->common.fn_flags & ZEND_ACC_VARIADIC) { + if (!call->additional_named_args) { + ALLOC_HASHTABLE(call->additional_named_args); + zend_hash_init(call->additional_named_args, 0, NULL, ZVAL_PTR_DTOR, 0); + } + + if (zend_hash_quick_find(call->additional_named_args, name, name_len+1, hash_value, (void **) &target) == SUCCESS) { + zval_ptr_dtor((zval **) target); + zend_error(E_WARNING, "Overwriting already passed parameter $%s", name); + } else { + void *dummy = NULL; + zend_hash_quick_update(call->additional_named_args, name, name_len+1, hash_value, &dummy, sizeof(zval *), (void **) &target); + } + + *arg_num_target = call->fbc->common.num_args; + return target; + } else { + zend_error_noreturn(E_ERROR, "Unknown named argument $%s", name); + } + } else if (key) { + CACHE_POLYMORPHIC_PTR(key->cache_slot, call->fbc, (void *) (zend_uintptr_t) arg_num); + } + } + + *arg_num_target = arg_num; + relative_arg_num = arg_num - orig_arg_num - call->num_additional_args - 1; + + target = EG(argument_stack)->top + relative_arg_num; + if (relative_arg_num < 0) { + zend_check_for_overwritten_parameter(call->fbc, arg_num, target TSRMLS_CC); + } else if (relative_arg_num > 0) { + ZEND_VM_STACK_GROW_IF_NEEDED(relative_arg_num); + memset(EG(argument_stack)->top, 0, relative_arg_num * sizeof(void *)); + EG(argument_stack)->top += relative_arg_num + 1; + call->num_additional_args += relative_arg_num + 1; + } else { + EG(argument_stack)->top++; + call->num_additional_args++; + } + + return target; +} +/* }}} */ + +zend_always_inline zend_bool zend_is_by_ref_func_arg_fetch(zend_op *opline, call_slot *call TSRMLS_DC) /* {{{ */ +{ + zend_uint arg_num; + + if (opline->extended_value & ZEND_FETCH_NAMED) { + /* This is likely not the right way to do it... */ + zend_op *send_op = opline + 1; + while (send_op->opcode != ZEND_SEND_VAR) { + send_op++; + } + + if (zend_get_arg_num(&arg_num, call->fbc, Z_STRVAL_P(send_op->op2.zv), Z_STRLEN_P(send_op->op2.zv), Z_HASH_P(send_op->op2.zv) TSRMLS_CC) == SUCCESS) { + return ARG_SHOULD_BE_SENT_BY_REF(call->fbc, arg_num); + } else if (call->fbc->common.fn_flags & ZEND_ACC_VARIADIC) { + return ARG_SHOULD_BE_SENT_BY_REF(call->fbc, call->fbc->common.num_args); + } else { + return 0; + } + } else { + arg_num = (opline->extended_value & ZEND_FETCH_ARG_MASK) + call->num_additional_args; + return ARG_SHOULD_BE_SENT_BY_REF(call->fbc, arg_num); + } +} +/* }}} */ #define ZEND_VM_NEXT_OPCODE() \ CHECK_SYMBOL_TABLES() \ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 0d3a908a1527c..d070eb93bbf25 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -305,6 +305,7 @@ static zend_always_inline void zend_vm_stack_clear_multiple(int nested TSRMLS_DC while (p != end) { zval *q = (zval *) *(--p); *p = NULL; + if (UNEXPECTED(q == NULL)) continue; i_zval_ptr_dtor(q ZEND_FILE_LINE_CC TSRMLS_CC); } if (nested) { @@ -326,13 +327,19 @@ static zend_always_inline int zend_vm_stack_get_args_count_ex(zend_execute_data static zend_always_inline zval** zend_vm_stack_get_arg_ex(zend_execute_data *ex, int requested_arg) { - void **p = ex->function_state.arguments; + void **p = ex->function_state.arguments, **arg; int arg_count = (int)(zend_uintptr_t) *p; if (UNEXPECTED(requested_arg > arg_count)) { return NULL; } - return (zval**)p - arg_count + requested_arg - 1; + + arg = p - arg_count + requested_arg - 1; + if (UNEXPECTED(*arg == NULL)) { + return NULL; + } + + return (zval **) arg; } static zend_always_inline int zend_vm_stack_get_args_count(TSRMLS_D) diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index d3844540cf597..b9021acbeef41 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -580,7 +580,7 @@ optional_class_type: function_call_parameter_list: '(' ')' { Z_LVAL($$.u.constant) = 0; } | '(' non_empty_function_call_parameter_list ')' { $$ = $2; } - | '(' yield_expr ')' { zend_do_pass_param(&$2, ZEND_SEND_VAL TSRMLS_CC); } + | '(' yield_expr ')' { zend_do_pass_param(&$2, ZEND_SEND_VAL, NULL TSRMLS_CC); } ; @@ -590,10 +590,18 @@ non_empty_function_call_parameter_list: ; function_call_parameter: - expr_without_variable { zend_do_pass_param(&$1, ZEND_SEND_VAL TSRMLS_CC); } - | variable { zend_do_pass_param(&$1, ZEND_SEND_VAR TSRMLS_CC); } - | '&' w_variable { zend_do_pass_param(&$2, ZEND_SEND_REF TSRMLS_CC); } + expr_without_variable { zend_do_pass_param(&$1, ZEND_SEND_VAL, NULL TSRMLS_CC); } + | variable { zend_do_pass_param(&$1, ZEND_SEND_VAR, NULL TSRMLS_CC); } + | '&' w_variable { zend_do_pass_param(&$2, ZEND_SEND_REF, NULL TSRMLS_CC); } | T_ELLIPSIS expr { zend_do_unpack_params(&$2 TSRMLS_CC); } + | named_arg T_DOUBLE_ARROW expr_without_variable { zend_do_pass_param(&$3, ZEND_SEND_VAL, &$1 TSRMLS_CC); } + | named_arg T_DOUBLE_ARROW variable { zend_do_pass_param(&$3, ZEND_SEND_VAR, &$1 TSRMLS_CC); } + | named_arg T_DOUBLE_ARROW '&' w_variable { zend_do_pass_param(&$4, ZEND_SEND_REF, &$1 TSRMLS_CC); } +; + +named_arg: + T_STRING { $$ = $1; } + | T_CONSTANT_ENCAPSED_STRING { $$ = $1; } ; global_var_list: diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 2ba05399b4ddb..2ef5e16b0464d 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1020,6 +1020,7 @@ static inline union _zend_function *zend_get_user_call_function(zend_class_entry call_user_call->module = (ce->type == ZEND_INTERNAL_CLASS) ? ce->info.internal.module : NULL; call_user_call->handler = zend_std_call_user_call; call_user_call->arg_info = NULL; + call_user_call->arg_offsets = NULL; call_user_call->num_args = 0; call_user_call->scope = ce; call_user_call->fn_flags = ZEND_ACC_CALL_VIA_HANDLER; @@ -1160,6 +1161,7 @@ static inline union _zend_function *zend_get_user_callstatic_function(zend_class callstatic_user_call->module = (ce->type == ZEND_INTERNAL_CLASS) ? ce->info.internal.module : NULL; callstatic_user_call->handler = zend_std_callstatic_user_call; callstatic_user_call->arg_info = NULL; + callstatic_user_call->arg_offsets = NULL; callstatic_user_call->num_args = 0; callstatic_user_call->scope = ce; callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 457f08f31390b..44ae93fdecd1f 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -78,9 +78,10 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz op_array->doc_comment = NULL; op_array->doc_comment_len = 0; - op_array->arg_info = NULL; op_array->num_args = 0; op_array->required_num_args = 0; + op_array->arg_info = NULL; + op_array->arg_offsets = NULL; op_array->scope = NULL; @@ -410,6 +411,10 @@ ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC) } efree(op_array->arg_info); } + if (op_array->arg_offsets) { + zend_hash_destroy(op_array->arg_offsets); + FREE_HASHTABLE(op_array->arg_offsets); + } } void init_op(zend_op *op TSRMLS_DC) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index ed353edbac3db..2e25daf017b85 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1834,9 +1834,9 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) LOAD_REGS(); LOAD_OPLINE(); if (UNEXPECTED(opline->opcode == ZEND_INCLUDE_OR_EVAL)) { - EX(function_state).function = (zend_function *) EX(op_array); EX(function_state).arguments = NULL; + EX(function_state).additional_named_args = NULL; EG(opline_ptr) = &EX(opline); EG(active_op_array) = EX(op_array); @@ -1862,6 +1862,12 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) EX(function_state).function = (zend_function *) EX(op_array); EX(function_state).arguments = NULL; + if (EX(function_state).additional_named_args) { + zend_hash_destroy(EX(function_state).additional_named_args); + FREE_HASHTABLE(EX(function_state).additional_named_args); + EX(function_state).additional_named_args = NULL; + } + if (EG(This)) { if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) { if (EX(call)->is_ctor_result_used) { @@ -1947,6 +1953,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) } num_args = opline->extended_value + EX(call)->num_additional_args; + EX(function_state).additional_named_args = EX(call)->additional_named_args; if (EX(call)->num_additional_args) { EX(function_state).arguments = zend_vm_stack_push_args(num_args TSRMLS_CC); } else { @@ -2048,6 +2055,12 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) EX(function_state).function = (zend_function *) EX(op_array); EX(function_state).arguments = NULL; + if (EX(function_state).additional_named_args) { + zend_hash_destroy(EX(function_state).additional_named_args); + FREE_HASHTABLE(EX(function_state).additional_named_args); + EX(function_state).additional_named_args = NULL; + } + if (should_change_scope) { if (EG(This)) { if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) { @@ -2480,7 +2493,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -2608,7 +2621,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -2633,9 +2646,9 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2664,9 +2677,9 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) efree(lcname); FREE_OP2(); + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2687,7 +2700,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) FREE_OP2(); } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -2757,7 +2770,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -2796,9 +2809,9 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST) CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2827,10 +2840,10 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY) CACHE_PTR(opline->op1.literal->cache_slot, EX(function_state).function); } + zend_init_call_slot(call TSRMLS_CC); call->fbc = EX(function_state).function; call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -3057,15 +3070,28 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV) } } -ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) +ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, CONST|UNUSED) { USE_OPLINE + void **target; SAVE_OPLINE(); - if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { - if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num); + if (OP2_TYPE == IS_CONST) { + zend_uint arg_num; + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error(E_ERROR, "Cannot pass parameter $%s by reference", Z_STRVAL_P(opline->op2.zv)); } + } else { + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + zend_uint arg_num = opline->result.num + EX(call)->num_additional_args; + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", arg_num); + } + } + + target = EG(argument_stack)->top++; } { @@ -3080,14 +3106,14 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) if (!IS_OP1_TMP_FREE()) { zval_copy_ctor(valptr); } - zend_vm_stack_push(valptr TSRMLS_CC); + *target = valptr; FREE_OP1_IF_VAR(); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY) +ZEND_VM_HELPER_EX(zend_send_by_var_helper, VAR|CV, CONST|UNUSED, void **target) { USE_OPLINE zval *varptr; @@ -3114,26 +3140,40 @@ ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY) } else if (OP1_TYPE == IS_CV) { Z_ADDREF_P(varptr); } - zend_vm_stack_push(varptr TSRMLS_CC); + *target = varptr; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) +ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, CONST|UNUSED) { USE_OPLINE zend_free_op free_op1; zval *varptr; + zend_uint arg_num; + void **target; + zend_bool compile_time_bound; SAVE_OPLINE(); - if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ + compile_time_bound = opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND; + + if (OP2_TYPE == IS_CONST) { + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + } else { + target = EG(argument_stack)->top++; + } + + if (compile_time_bound) { /* Had function_ptr at compile_time */ if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { - ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_send_by_var_helper, target, target); } } else { - if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + if (OP2_TYPE != IS_CONST) { + arg_num = opline->result.num + EX(call)->num_additional_args; + } + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_send_by_var_helper, target, target); } } @@ -3146,11 +3186,11 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) if (OP1_TYPE == IS_CV) { Z_ADDREF_P(varptr); } - zend_vm_stack_push(varptr TSRMLS_CC); + *target = varptr; } else { zval *valptr; - if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? + if (compile_time_bound ? !(opline->extended_value & ZEND_ARG_SEND_SILENT) : !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { zend_error(E_STRICT, "Only variables should be passed by reference"); @@ -3161,13 +3201,13 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) zval_copy_ctor(valptr); } FREE_OP1_IF_VAR(); - zend_vm_stack_push(valptr TSRMLS_CC); + *target = valptr; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) +ZEND_VM_HELPER_EX(zend_send_by_ref_helper, VAR|CV, CONST|UNUSED, void **target) { USE_OPLINE zend_free_op free_op1; @@ -3183,39 +3223,59 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) if (OP1_TYPE == IS_VAR && UNEXPECTED(*varptr_ptr == &EG(error_zval))) { ALLOC_INIT_ZVAL(varptr); - zend_vm_stack_push(varptr TSRMLS_CC); + *target = varptr; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } - if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && - EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { - if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); - } - } - SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); varptr = *varptr_ptr; Z_ADDREF_P(varptr); - zend_vm_stack_push(varptr TSRMLS_CC); + *target = varptr; FREE_OP1_VAR_PTR(); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY) +ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, CONST|UNUSED) +{ + USE_OPLINE; + void **target; + + if (OP2_TYPE == IS_CONST) { + zend_uint arg_num; + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + } else { + target = EG(argument_stack)->top++; + } + + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_send_by_ref_helper, target, target); +} + +ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, CONST|UNUSED) { USE_OPLINE + void **target; + zend_uint arg_num; - if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF); + if (OP2_TYPE == IS_CONST) { + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_send_by_ref_helper, target, target); + } + } else { + target = EG(argument_stack)->top++; + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + arg_num = opline->result.num + EX(call)->num_additional_args; + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_send_by_ref_helper, target, target); + } } } + SAVE_OPLINE(); - ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_send_by_var_helper, target, target); } ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY) @@ -3223,7 +3283,7 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY) USE_OPLINE zend_free_op free_op1; zval *args; - int arg_num; + zend_uint arg_num; SAVE_OPLINE(); args = GET_OP1_ZVAL_PTR(BP_VAR_R); @@ -3244,12 +3304,22 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY) char *name; zend_uint name_len; zend_ulong index; - - if (zend_hash_get_current_key_ex(ht, &name, &name_len, &index, 0, &pos) == HASH_KEY_IS_STRING) { - zend_error(E_RECOVERABLE_ERROR, "Cannot unpack array with string keys"); - FREE_OP1(); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + void **target; + + switch (zend_hash_get_current_key_ex(ht, &name, &name_len, &index, 0, &pos)) { + case HASH_KEY_IS_LONG: + if (EX(call)->uses_named_args) { + zend_error(E_WARNING, "Cannot pass positional arguments after named arguments. Aborting argument unpacking"); + FREE_OP1(); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); + } + target = EG(argument_stack)->top++; + EX(call)->num_additional_args++; + break; + case HASH_KEY_IS_STRING: + target = zend_handle_named_arg(&arg_num, EX(call), name, name_len-1, NULL, opline->op2.num TSRMLS_CC); + break; } if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { @@ -3264,8 +3334,7 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY) Z_ADDREF_P(arg); } - zend_vm_stack_push(arg TSRMLS_CC); - EX(call)->num_additional_args++; + *target = arg; } break; } @@ -3297,7 +3366,8 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY) } for (; iter->funcs->valid(iter TSRMLS_CC) == SUCCESS; ++arg_num) { - zval **arg_ptr, *arg; + zval **arg_ptr, *arg, key; + void **target; if (UNEXPECTED(EG(exception) != NULL)) { ZEND_VM_C_GOTO(unpack_iter_dtor); @@ -3309,20 +3379,31 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY) } if (iter->funcs->get_current_key) { - zval key; iter->funcs->get_current_key(iter, &key TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { ZEND_VM_C_GOTO(unpack_iter_dtor); } + } else { + Z_TYPE(key) = IS_LONG; + } - if (Z_TYPE(key) == IS_STRING) { - zend_error(E_RECOVERABLE_ERROR, - "Cannot unpack Traversable with string keys"); + switch (Z_TYPE(key)) { + default: zval_dtor(&key); - ZEND_VM_C_GOTO(unpack_iter_dtor); - } + /* break missing intentionally */ + case IS_LONG: + if (EX(call)->uses_named_args) { + zend_error(E_WARNING, "Cannot pass positional arguments after named arguments. Aborting argument unpacking"); + ZEND_VM_C_GOTO(unpack_iter_dtor); + } - zval_dtor(&key); + target = EG(argument_stack)->top++; + EX(call)->num_additional_args++; + break; + case IS_STRING: + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL(key), Z_STRLEN(key), NULL, opline->op2.num TSRMLS_CC); + zval_dtor(&key); + break; } if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { @@ -3344,8 +3425,7 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY) } ZEND_VM_STACK_GROW_IF_NEEDED(1); - zend_vm_stack_push(arg TSRMLS_CC); - EX(call)->num_additional_args++; + *target = arg; iter->funcs->move_forward(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { @@ -3467,6 +3547,13 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY) Z_ADDREF_PP(param); } + if (EX(prev_execute_data)->function_state.additional_named_args != NULL) { + zend_hash_copy( + Z_ARRVAL_P(params), EX(prev_execute_data)->function_state.additional_named_args, + (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *) + ); + } + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -3598,10 +3685,10 @@ ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY) } /* We are not handling overloaded classes right now */ + zend_init_call_slot(call TSRMLS_CC); call->fbc = constructor; call->object = object_zval; call->called_scope = EX_T(opline->op1.var).class_entry; - call->num_additional_args = 0; call->is_ctor_call = 1; call->is_ctor_result_used = RETURN_VALUE_USED(opline); EX(call) = call; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index a4e3350eaa16c..5d76bf5c81eaf 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -414,9 +414,9 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) LOAD_REGS(); LOAD_OPLINE(); if (UNEXPECTED(opline->opcode == ZEND_INCLUDE_OR_EVAL)) { - EX(function_state).function = (zend_function *) EX(op_array); EX(function_state).arguments = NULL; + EX(function_state).additional_named_args = NULL; EG(opline_ptr) = &EX(opline); EG(active_op_array) = EX(op_array); @@ -442,6 +442,12 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) EX(function_state).function = (zend_function *) EX(op_array); EX(function_state).arguments = NULL; + if (EX(function_state).additional_named_args) { + zend_hash_destroy(EX(function_state).additional_named_args); + FREE_HASHTABLE(EX(function_state).additional_named_args); + EX(function_state).additional_named_args = NULL; + } + if (EG(This)) { if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) { if (EX(call)->is_ctor_result_used) { @@ -527,6 +533,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR } num_args = opline->extended_value + EX(call)->num_additional_args; + EX(function_state).additional_named_args = EX(call)->additional_named_args; if (EX(call)->num_additional_args) { EX(function_state).arguments = zend_vm_stack_push_args(num_args TSRMLS_CC); } else { @@ -628,6 +635,12 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR EX(function_state).function = (zend_function *) EX(op_array); EX(function_state).arguments = NULL; + if (EX(function_state).additional_named_args) { + zend_hash_destroy(EX(function_state).additional_named_args); + FREE_HASHTABLE(EX(function_state).additional_named_args); + EX(function_state).additional_named_args = NULL; + } + if (should_change_scope) { if (EG(This)) { if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) { @@ -710,7 +723,7 @@ static int ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS USE_OPLINE zend_free_op free_op1; zval *args; - int arg_num; + zend_uint arg_num; SAVE_OPLINE(); args = get_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, BP_VAR_R); @@ -731,12 +744,22 @@ static int ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS char *name; zend_uint name_len; zend_ulong index; - - if (zend_hash_get_current_key_ex(ht, &name, &name_len, &index, 0, &pos) == HASH_KEY_IS_STRING) { - zend_error(E_RECOVERABLE_ERROR, "Cannot unpack array with string keys"); - FREE_OP(free_op1); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + void **target; + + switch (zend_hash_get_current_key_ex(ht, &name, &name_len, &index, 0, &pos)) { + case HASH_KEY_IS_LONG: + if (EX(call)->uses_named_args) { + zend_error(E_WARNING, "Cannot pass positional arguments after named arguments. Aborting argument unpacking"); + FREE_OP(free_op1); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); + } + target = EG(argument_stack)->top++; + EX(call)->num_additional_args++; + break; + case HASH_KEY_IS_STRING: + target = zend_handle_named_arg(&arg_num, EX(call), name, name_len-1, NULL, opline->op2.num TSRMLS_CC); + break; } if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { @@ -751,8 +774,7 @@ static int ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS Z_ADDREF_P(arg); } - zend_vm_stack_push(arg TSRMLS_CC); - EX(call)->num_additional_args++; + *target = arg; } break; } @@ -784,7 +806,8 @@ static int ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS } for (; iter->funcs->valid(iter TSRMLS_CC) == SUCCESS; ++arg_num) { - zval **arg_ptr, *arg; + zval **arg_ptr, *arg, key; + void **target; if (UNEXPECTED(EG(exception) != NULL)) { goto unpack_iter_dtor; @@ -796,20 +819,31 @@ static int ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS } if (iter->funcs->get_current_key) { - zval key; iter->funcs->get_current_key(iter, &key TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { goto unpack_iter_dtor; } + } else { + Z_TYPE(key) = IS_LONG; + } - if (Z_TYPE(key) == IS_STRING) { - zend_error(E_RECOVERABLE_ERROR, - "Cannot unpack Traversable with string keys"); + switch (Z_TYPE(key)) { + default: zval_dtor(&key); - goto unpack_iter_dtor; - } + /* break missing intentionally */ + case IS_LONG: + if (EX(call)->uses_named_args) { + zend_error(E_WARNING, "Cannot pass positional arguments after named arguments. Aborting argument unpacking"); + goto unpack_iter_dtor; + } - zval_dtor(&key); + target = EG(argument_stack)->top++; + EX(call)->num_additional_args++; + break; + case IS_STRING: + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL(key), Z_STRLEN(key), NULL, opline->op2.num TSRMLS_CC); + zval_dtor(&key); + break; } if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { @@ -831,8 +865,7 @@ static int ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS } ZEND_VM_STACK_GROW_IF_NEEDED(1); - zend_vm_stack_push(arg TSRMLS_CC); - EX(call)->num_additional_args++; + *target = arg; iter->funcs->move_forward(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { @@ -921,6 +954,13 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR Z_ADDREF_PP(param); } + if (EX(prev_execute_data)->function_state.additional_named_args != NULL) { + zend_hash_copy( + Z_ARRVAL_P(params), EX(prev_execute_data)->function_state.additional_named_args, + (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *) + ); + } + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -963,10 +1003,10 @@ static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } /* We are not handling overloaded classes right now */ + zend_init_call_slot(call TSRMLS_CC); call->fbc = constructor; call->object = object_zval; call->called_scope = EX_T(opline->op1.var).class_entry; - call->num_additional_args = 0; call->is_ctor_call = 1; call->is_ctor_result_used = RETURN_VALUE_USED(opline); EX(call) = call; @@ -1439,9 +1479,9 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -1469,9 +1509,9 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE } efree(lcname); + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -1492,7 +1532,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -1562,7 +1602,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -1600,9 +1640,9 @@ static int ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPC CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -1775,9 +1815,9 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -1806,9 +1846,9 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H efree(lcname); zval_dtor(free_op2.var); + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -1829,7 +1869,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H zval_dtor(free_op2.var); } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -1899,7 +1939,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -1974,9 +2014,9 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2005,9 +2045,9 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H efree(lcname); zval_ptr_dtor_nogc(&free_op2.var); + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2028,7 +2068,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H zval_ptr_dtor_nogc(&free_op2.var); } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -2098,7 +2138,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -2211,9 +2251,9 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2241,9 +2281,9 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA } efree(lcname); + zend_init_call_slot(call TSRMLS_CC); call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2264,7 +2304,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -2334,7 +2374,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -2575,10 +2615,10 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A CACHE_PTR(opline->op1.literal->cache_slot, EX(function_state).function); } + zend_init_call_slot(call TSRMLS_CC); call->fbc = EX(function_state).function; call->object = NULL; call->called_scope = NULL; - call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2730,36 +2770,6 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS HANDLE_EXCEPTION(); } -static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { - if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num); - } - } - - { - zval *valptr; - zval *value; - - - value = opline->op1.zv; - - ALLOC_ZVAL(valptr); - INIT_PZVAL_COPY(valptr, value); - if (!0) { - zval_copy_ctor(valptr); - } - zend_vm_stack_push(valptr TSRMLS_CC); - - } - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - static int ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -3916,7 +3926,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER( } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -3924,6 +3934,49 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER( ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + void **target; + + SAVE_OPLINE(); + if (IS_CONST == IS_CONST) { + zend_uint arg_num; + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error(E_ERROR, "Cannot pass parameter $%s by reference", Z_STRVAL_P(opline->op2.zv)); + } + } else { + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + zend_uint arg_num = opline->result.num + EX(call)->num_additional_args; + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", arg_num); + } + } + + target = EG(argument_stack)->top++; + } + + { + zval *valptr; + zval *value; + + + value = opline->op1.zv; + + ALLOC_ZVAL(valptr); + INIT_PZVAL_COPY(valptr, value); + if (!0) { + zval_copy_ctor(valptr); + } + *target = valptr; + + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -4916,7 +4969,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -5780,7 +5833,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -6515,7 +6568,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -6523,6 +6576,49 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + void **target; + + SAVE_OPLINE(); + if (IS_UNUSED == IS_CONST) { + zend_uint arg_num; + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error(E_ERROR, "Cannot pass parameter $%s by reference", Z_STRVAL_P(opline->op2.zv)); + } + } else { + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + zend_uint arg_num = opline->result.num + EX(call)->num_additional_args; + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", arg_num); + } + } + + target = EG(argument_stack)->top++; + } + + { + zval *valptr; + zval *value; + + + value = opline->op1.zv; + + ALLOC_ZVAL(valptr); + INIT_PZVAL_COPY(valptr, value); + if (!0) { + zval_copy_ctor(valptr); + } + *target = valptr; + + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -7368,7 +7464,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -8087,36 +8183,6 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) HANDLE_EXCEPTION(); } -static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { - if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num); - } - } - - { - zval *valptr; - zval *value; - zend_free_op free_op1; - - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - - ALLOC_ZVAL(valptr); - INIT_PZVAL_COPY(valptr, value); - if (!1) { - zval_copy_ctor(valptr); - } - zend_vm_stack_push(valptr TSRMLS_CC); - - } - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - static int ZEND_FASTCALL ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -9327,7 +9393,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -9336,6 +9402,49 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + void **target; + + SAVE_OPLINE(); + if (IS_CONST == IS_CONST) { + zend_uint arg_num; + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error(E_ERROR, "Cannot pass parameter $%s by reference", Z_STRVAL_P(opline->op2.zv)); + } + } else { + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + zend_uint arg_num = opline->result.num + EX(call)->num_additional_args; + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", arg_num); + } + } + + target = EG(argument_stack)->top++; + } + + { + zval *valptr; + zval *value; + zend_free_op free_op1; + + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + + ALLOC_ZVAL(valptr); + INIT_PZVAL_COPY(valptr, value); + if (!1) { + zval_copy_ctor(valptr); + } + *target = valptr; + + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -10192,7 +10301,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -11058,7 +11167,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -11678,6 +11787,49 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAND return zend_fetch_var_address_helper_SPEC_TMP_UNUSED(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } +static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + void **target; + + SAVE_OPLINE(); + if (IS_UNUSED == IS_CONST) { + zend_uint arg_num; + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error(E_ERROR, "Cannot pass parameter $%s by reference", Z_STRVAL_P(opline->op2.zv)); + } + } else { + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + zend_uint arg_num = opline->result.num + EX(call)->num_additional_args; + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", arg_num); + } + } + + target = EG(argument_stack)->top++; + } + + { + zval *valptr; + zval *value; + zend_free_op free_op1; + + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + + ALLOC_ZVAL(valptr); + INIT_PZVAL_COPY(valptr, value); + if (!1) { + zval_copy_ctor(valptr); + } + *target = valptr; + + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -12504,7 +12656,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_ } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -13345,137 +13497,6 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) HANDLE_EXCEPTION(); } -static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr; - zend_free_op free_op1; - varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - - if (varptr == &EG(uninitialized_zval)) { - if (IS_VAR == IS_VAR) { - Z_DELREF_P(varptr); - } - ALLOC_INIT_ZVAL(varptr); - } else if (PZVAL_IS_REF(varptr)) { - if (IS_VAR == IS_CV || - (IS_VAR == IS_VAR && Z_REFCOUNT_P(varptr) > 2)) { - zval *original_var = varptr; - - ALLOC_ZVAL(varptr); - INIT_PZVAL_COPY(varptr, original_var); - zval_copy_ctor(varptr); - zval_ptr_dtor_nogc(&free_op1.var); - } else { - Z_UNSET_ISREF_P(varptr); - } - } else if (IS_VAR == IS_CV) { - Z_ADDREF_P(varptr); - } - zend_vm_stack_push(varptr TSRMLS_CC); - - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *varptr; - - SAVE_OPLINE(); - if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ - if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { - return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - } else { - if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - } - - varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || - EX_T(opline->op1.var).var.fcall_returned_reference) && - varptr != &EG(uninitialized_zval) && - (PZVAL_IS_REF(varptr) || Z_REFCOUNT_P(varptr) == 1)) { - Z_SET_ISREF_P(varptr); - if (IS_VAR == IS_CV) { - Z_ADDREF_P(varptr); - } - zend_vm_stack_push(varptr TSRMLS_CC); - } else { - zval *valptr; - - if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? - !(opline->extended_value & ZEND_ARG_SEND_SILENT) : - !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - zend_error(E_STRICT, "Only variables should be passed by reference"); - } - ALLOC_ZVAL(valptr); - INIT_PZVAL_COPY(valptr, varptr); - if (!0) { - zval_copy_ctor(valptr); - } - zval_ptr_dtor_nogc(&free_op1.var); - zend_vm_stack_push(valptr TSRMLS_CC); - } - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval **varptr_ptr; - zval *varptr; - - SAVE_OPLINE(); - varptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - - if (IS_VAR == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) { - zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); - } - - if (IS_VAR == IS_VAR && UNEXPECTED(*varptr_ptr == &EG(error_zval))) { - ALLOC_INIT_ZVAL(varptr); - zend_vm_stack_push(varptr TSRMLS_CC); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); - } - - if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && - EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { - if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - } - - SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); - varptr = *varptr_ptr; - Z_ADDREF_P(varptr); - zend_vm_stack_push(varptr TSRMLS_CC); - - if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - } - SAVE_OPLINE(); - return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); -} - static int ZEND_FASTCALL ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -15742,7 +15763,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -15869,7 +15890,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -15877,6 +15898,171 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR_CONST(void **target, ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr; + zend_free_op free_op1; + varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + + if (varptr == &EG(uninitialized_zval)) { + if (IS_VAR == IS_VAR) { + Z_DELREF_P(varptr); + } + ALLOC_INIT_ZVAL(varptr); + } else if (PZVAL_IS_REF(varptr)) { + if (IS_VAR == IS_CV || + (IS_VAR == IS_VAR && Z_REFCOUNT_P(varptr) > 2)) { + zval *original_var = varptr; + + ALLOC_ZVAL(varptr); + INIT_PZVAL_COPY(varptr, original_var); + zval_copy_ctor(varptr); + zval_ptr_dtor_nogc(&free_op1.var); + } else { + Z_UNSET_ISREF_P(varptr); + } + } else if (IS_VAR == IS_CV) { + Z_ADDREF_P(varptr); + } + *target = varptr; + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *varptr; + zend_uint arg_num; + void **target; + zend_bool compile_time_bound; + + SAVE_OPLINE(); + compile_time_bound = opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND; + + if (IS_CONST == IS_CONST) { + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + } else { + target = EG(argument_stack)->top++; + } + + if (compile_time_bound) { /* Had function_ptr at compile_time */ + if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { + return zend_send_by_var_helper_SPEC_VAR_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } else { + if (IS_CONST != IS_CONST) { + arg_num = opline->result.num + EX(call)->num_additional_args; + } + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_var_helper_SPEC_VAR_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } + + varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || + EX_T(opline->op1.var).var.fcall_returned_reference) && + varptr != &EG(uninitialized_zval) && + (PZVAL_IS_REF(varptr) || Z_REFCOUNT_P(varptr) == 1)) { + Z_SET_ISREF_P(varptr); + if (IS_VAR == IS_CV) { + Z_ADDREF_P(varptr); + } + *target = varptr; + } else { + zval *valptr; + + if (compile_time_bound ? + !(opline->extended_value & ZEND_ARG_SEND_SILENT) : + !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { + zend_error(E_STRICT, "Only variables should be passed by reference"); + } + ALLOC_ZVAL(valptr); + INIT_PZVAL_COPY(valptr, varptr); + if (!0) { + zval_copy_ctor(valptr); + } + zval_ptr_dtor_nogc(&free_op1.var); + *target = valptr; + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_send_by_ref_helper_SPEC_VAR_CONST(void **target, ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval **varptr_ptr; + zval *varptr; + + SAVE_OPLINE(); + varptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + + if (IS_VAR == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); + } + + if (IS_VAR == IS_VAR && UNEXPECTED(*varptr_ptr == &EG(error_zval))) { + ALLOC_INIT_ZVAL(varptr); + *target = varptr; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); + } + + SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); + varptr = *varptr_ptr; + Z_ADDREF_P(varptr); + *target = varptr; + + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE; + void **target; + + if (IS_CONST == IS_CONST) { + zend_uint arg_num; + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + } else { + target = EG(argument_stack)->top++; + } + + return zend_send_by_ref_helper_SPEC_VAR_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + void **target; + zend_uint arg_num; + + if (IS_CONST == IS_CONST) { + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_ref_helper_SPEC_VAR_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } else { + target = EG(argument_stack)->top++; + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + arg_num = opline->result.num + EX(call)->num_additional_args; + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_ref_helper_SPEC_VAR_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } + } + + SAVE_OPLINE(); + return zend_send_by_var_helper_SPEC_VAR_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -18089,7 +18275,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -18217,7 +18403,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -20396,7 +20582,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -20524,7 +20710,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -21970,7 +22156,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -21978,6 +22164,171 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR_UNUSED(void **target, ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr; + zend_free_op free_op1; + varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + + if (varptr == &EG(uninitialized_zval)) { + if (IS_VAR == IS_VAR) { + Z_DELREF_P(varptr); + } + ALLOC_INIT_ZVAL(varptr); + } else if (PZVAL_IS_REF(varptr)) { + if (IS_VAR == IS_CV || + (IS_VAR == IS_VAR && Z_REFCOUNT_P(varptr) > 2)) { + zval *original_var = varptr; + + ALLOC_ZVAL(varptr); + INIT_PZVAL_COPY(varptr, original_var); + zval_copy_ctor(varptr); + zval_ptr_dtor_nogc(&free_op1.var); + } else { + Z_UNSET_ISREF_P(varptr); + } + } else if (IS_VAR == IS_CV) { + Z_ADDREF_P(varptr); + } + *target = varptr; + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *varptr; + zend_uint arg_num; + void **target; + zend_bool compile_time_bound; + + SAVE_OPLINE(); + compile_time_bound = opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND; + + if (IS_UNUSED == IS_CONST) { + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + } else { + target = EG(argument_stack)->top++; + } + + if (compile_time_bound) { /* Had function_ptr at compile_time */ + if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { + return zend_send_by_var_helper_SPEC_VAR_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } else { + if (IS_UNUSED != IS_CONST) { + arg_num = opline->result.num + EX(call)->num_additional_args; + } + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_var_helper_SPEC_VAR_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } + + varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || + EX_T(opline->op1.var).var.fcall_returned_reference) && + varptr != &EG(uninitialized_zval) && + (PZVAL_IS_REF(varptr) || Z_REFCOUNT_P(varptr) == 1)) { + Z_SET_ISREF_P(varptr); + if (IS_VAR == IS_CV) { + Z_ADDREF_P(varptr); + } + *target = varptr; + } else { + zval *valptr; + + if (compile_time_bound ? + !(opline->extended_value & ZEND_ARG_SEND_SILENT) : + !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { + zend_error(E_STRICT, "Only variables should be passed by reference"); + } + ALLOC_ZVAL(valptr); + INIT_PZVAL_COPY(valptr, varptr); + if (!0) { + zval_copy_ctor(valptr); + } + zval_ptr_dtor_nogc(&free_op1.var); + *target = valptr; + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_send_by_ref_helper_SPEC_VAR_UNUSED(void **target, ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval **varptr_ptr; + zval *varptr; + + SAVE_OPLINE(); + varptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + + if (IS_VAR == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); + } + + if (IS_VAR == IS_VAR && UNEXPECTED(*varptr_ptr == &EG(error_zval))) { + ALLOC_INIT_ZVAL(varptr); + *target = varptr; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); + } + + SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); + varptr = *varptr_ptr; + Z_ADDREF_P(varptr); + *target = varptr; + + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE; + void **target; + + if (IS_UNUSED == IS_CONST) { + zend_uint arg_num; + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + } else { + target = EG(argument_stack)->top++; + } + + return zend_send_by_ref_helper_SPEC_VAR_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + void **target; + zend_uint arg_num; + + if (IS_UNUSED == IS_CONST) { + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_ref_helper_SPEC_VAR_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } else { + target = EG(argument_stack)->top++; + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + arg_num = opline->result.num + EX(call)->num_additional_args; + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_ref_helper_SPEC_VAR_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } + } + + SAVE_OPLINE(); + return zend_send_by_var_helper_SPEC_VAR_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -23853,7 +24204,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -23980,7 +24331,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_ } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -25495,7 +25846,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -26904,7 +27255,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -28218,7 +28569,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -29960,7 +30311,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -30956,136 +31307,6 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) HANDLE_EXCEPTION(); } -static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr; - - varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - - if (varptr == &EG(uninitialized_zval)) { - if (IS_CV == IS_VAR) { - Z_DELREF_P(varptr); - } - ALLOC_INIT_ZVAL(varptr); - } else if (PZVAL_IS_REF(varptr)) { - if (IS_CV == IS_CV || - (IS_CV == IS_VAR && Z_REFCOUNT_P(varptr) > 2)) { - zval *original_var = varptr; - - ALLOC_ZVAL(varptr); - INIT_PZVAL_COPY(varptr, original_var); - zval_copy_ctor(varptr); - - } else { - Z_UNSET_ISREF_P(varptr); - } - } else if (IS_CV == IS_CV) { - Z_ADDREF_P(varptr); - } - zend_vm_stack_push(varptr TSRMLS_CC); - - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *varptr; - - SAVE_OPLINE(); - if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ - if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { - return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - } else { - if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - } - - varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || - EX_T(opline->op1.var).var.fcall_returned_reference) && - varptr != &EG(uninitialized_zval) && - (PZVAL_IS_REF(varptr) || Z_REFCOUNT_P(varptr) == 1)) { - Z_SET_ISREF_P(varptr); - if (IS_CV == IS_CV) { - Z_ADDREF_P(varptr); - } - zend_vm_stack_push(varptr TSRMLS_CC); - } else { - zval *valptr; - - if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? - !(opline->extended_value & ZEND_ARG_SEND_SILENT) : - !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - zend_error(E_STRICT, "Only variables should be passed by reference"); - } - ALLOC_ZVAL(valptr); - INIT_PZVAL_COPY(valptr, varptr); - if (!0) { - zval_copy_ctor(valptr); - } - - zend_vm_stack_push(valptr TSRMLS_CC); - } - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval **varptr_ptr; - zval *varptr; - - SAVE_OPLINE(); - varptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - - if (IS_CV == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) { - zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); - } - - if (IS_CV == IS_VAR && UNEXPECTED(*varptr_ptr == &EG(error_zval))) { - ALLOC_INIT_ZVAL(varptr); - zend_vm_stack_push(varptr TSRMLS_CC); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); - } - - if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && - EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { - if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - } - - SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); - varptr = *varptr_ptr; - Z_ADDREF_P(varptr); - zend_vm_stack_push(varptr TSRMLS_CC); - - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { - return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - } - SAVE_OPLINE(); - return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); -} - static int ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -33199,7 +33420,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -33208,6 +33429,170 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV_CONST(void **target, ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr; + + varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + + if (varptr == &EG(uninitialized_zval)) { + if (IS_CV == IS_VAR) { + Z_DELREF_P(varptr); + } + ALLOC_INIT_ZVAL(varptr); + } else if (PZVAL_IS_REF(varptr)) { + if (IS_CV == IS_CV || + (IS_CV == IS_VAR && Z_REFCOUNT_P(varptr) > 2)) { + zval *original_var = varptr; + + ALLOC_ZVAL(varptr); + INIT_PZVAL_COPY(varptr, original_var); + zval_copy_ctor(varptr); + + } else { + Z_UNSET_ISREF_P(varptr); + } + } else if (IS_CV == IS_CV) { + Z_ADDREF_P(varptr); + } + *target = varptr; + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *varptr; + zend_uint arg_num; + void **target; + zend_bool compile_time_bound; + + SAVE_OPLINE(); + compile_time_bound = opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND; + + if (IS_CONST == IS_CONST) { + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + } else { + target = EG(argument_stack)->top++; + } + + if (compile_time_bound) { /* Had function_ptr at compile_time */ + if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { + return zend_send_by_var_helper_SPEC_CV_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } else { + if (IS_CONST != IS_CONST) { + arg_num = opline->result.num + EX(call)->num_additional_args; + } + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_var_helper_SPEC_CV_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } + + varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || + EX_T(opline->op1.var).var.fcall_returned_reference) && + varptr != &EG(uninitialized_zval) && + (PZVAL_IS_REF(varptr) || Z_REFCOUNT_P(varptr) == 1)) { + Z_SET_ISREF_P(varptr); + if (IS_CV == IS_CV) { + Z_ADDREF_P(varptr); + } + *target = varptr; + } else { + zval *valptr; + + if (compile_time_bound ? + !(opline->extended_value & ZEND_ARG_SEND_SILENT) : + !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { + zend_error(E_STRICT, "Only variables should be passed by reference"); + } + ALLOC_ZVAL(valptr); + INIT_PZVAL_COPY(valptr, varptr); + if (!0) { + zval_copy_ctor(valptr); + } + + *target = valptr; + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_send_by_ref_helper_SPEC_CV_CONST(void **target, ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval **varptr_ptr; + zval *varptr; + + SAVE_OPLINE(); + varptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + + if (IS_CV == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); + } + + if (IS_CV == IS_VAR && UNEXPECTED(*varptr_ptr == &EG(error_zval))) { + ALLOC_INIT_ZVAL(varptr); + *target = varptr; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); + } + + SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); + varptr = *varptr_ptr; + Z_ADDREF_P(varptr); + *target = varptr; + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE; + void **target; + + if (IS_CONST == IS_CONST) { + zend_uint arg_num; + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + } else { + target = EG(argument_stack)->top++; + } + + return zend_send_by_ref_helper_SPEC_CV_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + void **target; + zend_uint arg_num; + + if (IS_CONST == IS_CONST) { + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_ref_helper_SPEC_CV_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } else { + target = EG(argument_stack)->top++; + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + arg_num = opline->result.num + EX(call)->num_additional_args; + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_ref_helper_SPEC_CV_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } + } + + SAVE_OPLINE(); + return zend_send_by_var_helper_SPEC_CV_CONST(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -35311,7 +35696,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -37478,7 +37863,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -38802,6 +39187,170 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV_UNUSED(void **target, ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr; + + varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + + if (varptr == &EG(uninitialized_zval)) { + if (IS_CV == IS_VAR) { + Z_DELREF_P(varptr); + } + ALLOC_INIT_ZVAL(varptr); + } else if (PZVAL_IS_REF(varptr)) { + if (IS_CV == IS_CV || + (IS_CV == IS_VAR && Z_REFCOUNT_P(varptr) > 2)) { + zval *original_var = varptr; + + ALLOC_ZVAL(varptr); + INIT_PZVAL_COPY(varptr, original_var); + zval_copy_ctor(varptr); + + } else { + Z_UNSET_ISREF_P(varptr); + } + } else if (IS_CV == IS_CV) { + Z_ADDREF_P(varptr); + } + *target = varptr; + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *varptr; + zend_uint arg_num; + void **target; + zend_bool compile_time_bound; + + SAVE_OPLINE(); + compile_time_bound = opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND; + + if (IS_UNUSED == IS_CONST) { + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + } else { + target = EG(argument_stack)->top++; + } + + if (compile_time_bound) { /* Had function_ptr at compile_time */ + if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { + return zend_send_by_var_helper_SPEC_CV_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } else { + if (IS_UNUSED != IS_CONST) { + arg_num = opline->result.num + EX(call)->num_additional_args; + } + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_var_helper_SPEC_CV_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } + + varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || + EX_T(opline->op1.var).var.fcall_returned_reference) && + varptr != &EG(uninitialized_zval) && + (PZVAL_IS_REF(varptr) || Z_REFCOUNT_P(varptr) == 1)) { + Z_SET_ISREF_P(varptr); + if (IS_CV == IS_CV) { + Z_ADDREF_P(varptr); + } + *target = varptr; + } else { + zval *valptr; + + if (compile_time_bound ? + !(opline->extended_value & ZEND_ARG_SEND_SILENT) : + !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) { + zend_error(E_STRICT, "Only variables should be passed by reference"); + } + ALLOC_ZVAL(valptr); + INIT_PZVAL_COPY(valptr, varptr); + if (!0) { + zval_copy_ctor(valptr); + } + + *target = valptr; + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_send_by_ref_helper_SPEC_CV_UNUSED(void **target, ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval **varptr_ptr; + zval *varptr; + + SAVE_OPLINE(); + varptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + + if (IS_CV == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); + } + + if (IS_CV == IS_VAR && UNEXPECTED(*varptr_ptr == &EG(error_zval))) { + ALLOC_INIT_ZVAL(varptr); + *target = varptr; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); + } + + SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); + varptr = *varptr_ptr; + Z_ADDREF_P(varptr); + *target = varptr; + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE; + void **target; + + if (IS_UNUSED == IS_CONST) { + zend_uint arg_num; + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + } else { + target = EG(argument_stack)->top++; + } + + return zend_send_by_ref_helper_SPEC_CV_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + void **target; + zend_uint arg_num; + + if (IS_UNUSED == IS_CONST) { + target = zend_handle_named_arg(&arg_num, EX(call), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal, opline->result.num TSRMLS_CC); + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_ref_helper_SPEC_CV_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } else { + target = EG(argument_stack)->top++; + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + arg_num = opline->result.num + EX(call)->num_additional_args; + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_ref_helper_SPEC_CV_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + } + } + + SAVE_OPLINE(); + return zend_send_by_var_helper_SPEC_CV_UNUSED(target, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -40646,7 +41195,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H } } - call->num_additional_args = 0; + zend_init_call_slot(call TSRMLS_CC); call->is_ctor_call = 0; EX(call) = call; @@ -42858,16 +43407,18 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_SEND_VAL_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_SPEC_TMP_HANDLER, + ZEND_SEND_VAL_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_VAL_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_VAL_SPEC_TMP_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_VAL_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -42891,26 +43442,20 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_SEND_VAR_SPEC_VAR_CONST_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_SPEC_VAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, ZEND_NULL_HANDLER, + ZEND_SEND_VAR_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_SEND_VAR_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -42918,21 +43463,25 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_SEND_REF_SPEC_VAR_HANDLER, - ZEND_SEND_REF_SPEC_VAR_HANDLER, - ZEND_SEND_REF_SPEC_VAR_HANDLER, - ZEND_SEND_REF_SPEC_VAR_HANDLER, - ZEND_SEND_REF_SPEC_VAR_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_SEND_REF_SPEC_VAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_REF_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_SEND_REF_SPEC_CV_HANDLER, - ZEND_SEND_REF_SPEC_CV_HANDLER, - ZEND_SEND_REF_SPEC_CV_HANDLER, - ZEND_SEND_REF_SPEC_CV_HANDLER, - ZEND_SEND_REF_SPEC_CV_HANDLER, ZEND_NEW_SPEC_HANDLER, ZEND_NEW_SPEC_HANDLER, ZEND_NEW_SPEC_HANDLER, @@ -43893,21 +44442,21 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_SEND_VAR_NO_REF_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_SEND_VAR_NO_REF_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, diff --git a/ext/standard/array.c b/ext/standard/array.c index e84e01969089a..b108d077c7116 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2064,14 +2064,15 @@ PHP_FUNCTION(array_splice) length = 0, repl_num = 0; /* Number of replacement elements */ int num_in; /* Number of elements in the input array */ + zend_bool length_null; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|lz/", &array, &offset, &length, &repl_array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|l!z/", &array, &offset, &length, &length_null, &repl_array) == FAILURE) { return; } num_in = zend_hash_num_elements(Z_ARRVAL_P(array)); - if (ZEND_NUM_ARGS() < 3) { + if (length_null) { length = num_in; } From 0872deb0b06b4087ce54f9e50bfa6dbd454d0468 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 26 Feb 2014 20:55:33 +0100 Subject: [PATCH 2/2] Cherry pick 7682dfc by stas Minus whitespace changes, minus some things not relevant here. Not carefully reviewed. Might contain some changes that do not apply to my branch and need to be removed --- Zend/zend_builtin_functions.c | 4 +- Zend/zend_execute.c | 4 +- Zend/zend_execute.h | 9 + ext/bcmath/bcmath.c | 72 ++-- ext/bz2/bz2.c | 12 +- ext/date/php_date.c | 38 +-- ext/dba/dba.c | 5 +- ext/enchant/enchant.c | 2 +- ext/ereg/ereg.c | 9 +- ext/gd/gd.c | 23 +- ext/gd/gd_ctx.c | 12 +- ext/hash/hash.c | 4 +- ext/iconv/iconv.c | 4 +- ext/imap/php_imap.c | 50 ++- ext/interbase/ibase_blobs.c | 43 ++- ext/interbase/ibase_events.c | 6 +- ext/interbase/ibase_query.c | 9 +- ext/interbase/interbase.c | 6 +- ext/intl/grapheme/grapheme_string.c | 16 +- ext/intl/grapheme/grapheme_util.c | 6 +- ext/intl/grapheme/grapheme_util.h | 6 +- ext/ldap/ldap.c | 6 +- ext/mbstring/mbstring.c | 71 ++-- ext/mbstring/php_mbregex.c | 29 +- ext/mssql/php_mssql.c | 15 +- ext/mysql/php_mysql.c | 27 +- ext/mysqli/mysqli.c | 42 +-- ext/mysqli/mysqli_api.c | 109 ++---- ext/mysqli/mysqli_warning.c | 5 +- ext/mysqli/tests/mysqli_stmt_bind_result.phpt | 3 +- ext/oci8/oci8.c | 9 +- ext/oci8/oci8_interface.c | 26 +- ext/odbc/php_odbc.c | 10 +- ext/pcntl/pcntl.c | 4 +- ext/pcre/php_pcre.c | 4 +- ext/pdo/pdo_dbh.c | 2 +- ext/pdo/pdo_stmt.c | 108 +++--- ext/pdo/tests/bug_44173.phpt | 2 +- ext/pgsql/pgsql.c | 317 ++++++++---------- ext/pspell/pspell.c | 10 +- ext/reflection/php_reflection.c | 25 +- ext/session/session.c | 11 +- ext/simplexml/simplexml.c | 10 +- ext/skeleton/create_stubs | 2 +- ext/snmp/snmp.c | 6 +- ext/soap/soap.c | 7 + ext/sockets/sockets.c | 12 +- ext/spl/php_spl.c | 2 +- ext/spl/spl_array.c | 6 +- ext/spl/spl_directory.c | 78 +++-- ext/spl/spl_iterators.c | 2 +- ext/standard/array.c | 79 +++-- ext/standard/assert.c | 13 +- ext/standard/basic_functions.c | 21 +- ext/standard/dir.c | 2 +- ext/standard/file.c | 31 +- ext/standard/filestat.c | 4 +- ext/standard/head.c | 2 +- ext/standard/image.c | 5 +- ext/standard/math.c | 4 +- ext/standard/rand.c | 4 +- ext/standard/streamsfuncs.c | 9 +- ext/standard/string.c | 53 ++- ext/standard/tests/array/array_rand.phpt | 2 + ext/standard/type.c | 22 +- ext/standard/versioning.c | 9 +- ext/sybase_ct/php_sybase_ct.c | 2 +- ext/tokenizer/tokenizer.c | 6 +- ext/xmlrpc/xmlrpc-epi-php.c | 7 +- sapi/cgi/cgi_main.c | 8 +- 70 files changed, 687 insertions(+), 896 deletions(-) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index fe632b234f049..409559fafa70c 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -850,7 +850,7 @@ ZEND_FUNCTION(get_called_class) Retrieves the parent class name for object or class or current scope. */ ZEND_FUNCTION(get_parent_class) { - zval *arg; + zval *arg = NULL; zend_class_entry *ce = NULL; const char *name; zend_uint name_length; @@ -859,7 +859,7 @@ ZEND_FUNCTION(get_parent_class) return; } - if (!ZEND_NUM_ARGS()) { + if (!ZEND_NUM_ARGS() || arg == NULL) { ce = EG(scope); if (ce && ce->parent) { RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index c6114c78430f5..2a336e9c84dda 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1619,8 +1619,8 @@ static zend_always_inline zend_execute_data *i_create_execute_data_from_op_array /* copy arguments */ *EX(prev_execute_data)->function_state.arguments = (void*)(zend_uintptr_t)args_count; if (args_count > 0) { - zval **arg_src = (zval**)zend_vm_stack_get_arg_ex(EG(current_execute_data), 1); - zval **arg_dst = (zval**)zend_vm_stack_get_arg_ex(EX(prev_execute_data), 1); + zval **arg_src = zend_vm_stack_get_args(EG(current_execute_data)); + zval **arg_dst = zend_vm_stack_get_args(EX(prev_execute_data)); int i; for (i = 0; i < args_count; i++) { diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index d070eb93bbf25..789836ec5decc 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -342,6 +342,15 @@ static zend_always_inline zval** zend_vm_stack_get_arg_ex(zend_execute_data *ex, return (zval **) arg; } +static zend_always_inline zval** zend_vm_stack_get_args(zend_execute_data *ex) +{ + void **p = ex->function_state.arguments; + int arg_count = (int)(zend_uintptr_t) *p; + + return (zval**)p - arg_count; +} + + static zend_always_inline int zend_vm_stack_get_args_count(TSRMLS_D) { return zend_vm_stack_get_args_count_ex(EG(current_execute_data)->prev_execute_data); diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 9369897c7fdcb..8af46ea20a12b 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -206,18 +206,15 @@ static void php_str2num(bc_num *num, char *str TSRMLS_DC) PHP_FUNCTION(bcadd) { char *left, *right; - long scale_param = 0; - bc_num first, second, result; int left_len, right_len; - int scale = BCG(bc_precision), argc = ZEND_NUM_ARGS(); + long scale_param = BCG(bc_precision); + bc_num first, second, result; + int scale; - if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { return; } - - if (argc == 3) { scale = (int) ((int)scale_param < 0) ? 0 : scale_param; - } bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); @@ -246,17 +243,14 @@ PHP_FUNCTION(bcsub) { char *left, *right; int left_len, right_len; - long scale_param = 0; + long scale_param = BCG(bc_precision); bc_num first, second, result; - int scale = BCG(bc_precision), argc = ZEND_NUM_ARGS(); + int scale; - if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { return; } - - if (argc == 3) { scale = (int) ((int)scale_param < 0) ? 0 : scale_param; - } bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); @@ -285,17 +279,14 @@ PHP_FUNCTION(bcmul) { char *left, *right; int left_len, right_len; - long scale_param = 0; + long scale_param = BCG(bc_precision); bc_num first, second, result; - int scale = BCG(bc_precision), argc = ZEND_NUM_ARGS(); + int scale; - if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { return; } - - if (argc == 3) { scale = (int) ((int)scale_param < 0) ? 0 : scale_param; - } bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); @@ -324,17 +315,14 @@ PHP_FUNCTION(bcdiv) { char *left, *right; int left_len, right_len; - long scale_param = 0; + long scale_param = BCG(bc_precision); bc_num first, second, result; - int scale = BCG(bc_precision), argc = ZEND_NUM_ARGS(); + int scale; - if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { return; } - - if (argc == 3) { scale = (int) ((int)scale_param < 0) ? 0 : scale_param; - } bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); @@ -412,6 +400,7 @@ PHP_FUNCTION(bcpowmod) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|l", &left, &left_len, &right, &right_len, &modulous, &modulous_len, &scale) == FAILURE) { return; } + scale_int = (int) ((int)scale < 0) ? 0 : scale; bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); @@ -421,8 +410,6 @@ PHP_FUNCTION(bcpowmod) php_str2num(&second, right TSRMLS_CC); php_str2num(&mod, modulous TSRMLS_CC); - scale_int = (int) ((int)scale < 0) ? 0 : scale; - if (bc_raisemod(first, second, mod, &result, scale_int TSRMLS_CC) != -1) { if (result->n_scale > scale) { result->n_scale = scale; @@ -448,17 +435,14 @@ PHP_FUNCTION(bcpow) { char *left, *right; int left_len, right_len; - long scale_param = 0; + long scale_param = BCG(bc_precision); bc_num first, second, result; - int scale = BCG(bc_precision), argc = ZEND_NUM_ARGS(); + int scale; - if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { return; } - - if (argc == 3) { scale = (int) ((int)scale_param < 0) ? 0 : scale_param; - } bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); @@ -487,17 +471,14 @@ PHP_FUNCTION(bcsqrt) { char *left; int left_len; - long scale_param = 0; - bc_num result; - int scale = BCG(bc_precision), argc = ZEND_NUM_ARGS(); + long scale_param = BCG(bc_precision); + bc_num first, second, result; + int scale; - if (zend_parse_parameters(argc TSRMLS_CC, "s|l", &left, &left_len, &scale_param) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &left, &left_len, &scale_param) == FAILURE) { return; } - - if (argc == 2) { scale = (int) ((int)scale_param < 0) ? 0 : scale_param; - } bc_init_num(&result TSRMLS_CC); php_str2num(&result, left TSRMLS_CC); @@ -524,17 +505,14 @@ PHP_FUNCTION(bccomp) { char *left, *right; int left_len, right_len; - long scale_param = 0; - bc_num first, second; - int scale = BCG(bc_precision), argc = ZEND_NUM_ARGS(); + long scale_param = BCG(bc_precision); + bc_num first, second, result; + int scale; - if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { return; } - - if (argc == 3) { scale = (int) ((int)scale_param < 0) ? 0 : scale_param; - } bc_init_num(&first TSRMLS_CC); bc_init_num(&second TSRMLS_CC); diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c index 2f440597bac31..21d04a835613e 100644 --- a/ext/bz2/bz2.c +++ b/ext/bz2/bz2.c @@ -479,18 +479,15 @@ static PHP_FUNCTION(bzerror) static PHP_FUNCTION(bzcompress) { char *source; /* Source data to compress */ - long zblock_size = 0; /* Optional block size to use */ + long zblock_size = 4; /* Optional block size to use */ long zwork_factor = 0;/* Optional work factor to use */ char *dest = NULL; /* Destination to place the compressed data into */ int error, /* Error Container */ block_size = 4, /* Block size for compression algorithm */ - work_factor = 0, /* Work factor for compression algorithm */ - argc; /* Argument count */ + work_factor = 0; /* Work factor for compression algorithm */ int source_len; /* Length of the source data */ unsigned int dest_len; /* Length of the destination buffer */ - argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &source, &source_len, &zblock_size, &zwork_factor) == FAILURE) { return; } @@ -505,13 +502,8 @@ static PHP_FUNCTION(bzcompress) dest = emalloc(dest_len + 1); /* Handle the optional arguments */ - if (argc > 1) { block_size = zblock_size; - } - - if (argc > 2) { work_factor = zwork_factor; - } error = BZ2_bzBuffToBuffCompress(dest, &dest_len, source, source_len, block_size, 0, work_factor); if (error != BZ_OK) { diff --git a/ext/date/php_date.c b/ext/date/php_date.c index f6b12bc42ed9b..d16bbfc613e89 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -1211,12 +1211,10 @@ static void php_date(INTERNAL_FUNCTION_PARAMETERS, int localtime) long ts; char *string; + ts = (long)time(NULL); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, &ts) == FAILURE) { RETURN_FALSE; } - if (ZEND_NUM_ARGS() == 1) { - ts = time(NULL); - } string = php_format_date(format, format_len, ts, localtime TSRMLS_CC); @@ -1370,6 +1368,7 @@ PHP_FUNCTION(idate) long ts = 0; int ret; + ts = (long)time(NULL); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, &ts) == FAILURE) { RETURN_FALSE; } @@ -1379,10 +1378,6 @@ PHP_FUNCTION(idate) RETURN_FALSE; } - if (ZEND_NUM_ARGS() == 1) { - ts = time(NULL); - } - ret = php_idate(format[0], ts, 0 TSRMLS_CC); if (ret == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unrecognized date format token."); @@ -1456,7 +1451,7 @@ PHP_FUNCTION(strtotime) timelib_unixtime2local(now, t->sse); timelib_time_dtor(t); efree(initial_ts); - } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", ×, &time_len, &preset_ts) != FAILURE) { + } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "s|l", ×, &time_len, &preset_ts) != FAILURE) { /* We have no initial timestamp */ now = timelib_time_ctor(); now->tz_info = tzi; @@ -1498,7 +1493,7 @@ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt) long ts, adjust_seconds = 0; int error; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lllllll", &hou, &min, &sec, &mon, &day, &yea, &dst) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "|lllllll", &hou, &min, &sec, &mon, &day, &yea, &dst) == FAILURE) { RETURN_FALSE; } /* Initialize structure with current time */ @@ -4566,40 +4561,25 @@ PHP_FUNCTION(date_default_timezone_get) */ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, int calc_sunset) { - double latitude = 0.0, longitude = 0.0, zenith = 0.0, gmt_offset = 0, altitude; + double latitude = INI_FLT("date.default_latitude"), longitude = INI_FLT("date.default_latitude"), zenith = 0.0, gmt_offset = 0, altitude; double h_rise, h_set, N; timelib_sll rise, set, transit; - long time, retformat = 0; + long time, retformat = SUNFUNCS_RET_STRING; int rs; timelib_time *t; timelib_tzinfo *tzi; char *retstr; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ldddd", &time, &retformat, &latitude, &longitude, &zenith, &gmt_offset) == FAILURE) { - RETURN_FALSE; - } - - switch (ZEND_NUM_ARGS()) { - case 1: - retformat = SUNFUNCS_RET_STRING; - case 2: - latitude = INI_FLT("date.default_latitude"); - case 3: - longitude = INI_FLT("date.default_longitude"); - case 4: if (calc_sunset) { zenith = INI_FLT("date.sunset_zenith"); } else { zenith = INI_FLT("date.sunrise_zenith"); } - case 5: - case 6: - break; - default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid format"); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ldddd", &time, &retformat, &latitude, &longitude, &zenith, &gmt_offset) == FAILURE) { RETURN_FALSE; - break; } + if (retformat != SUNFUNCS_RET_TIMESTAMP && retformat != SUNFUNCS_RET_STRING && retformat != SUNFUNCS_RET_DOUBLE) diff --git a/ext/dba/dba.c b/ext/dba/dba.c index 3bb45aa5612c8..7e3de4f76908d 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -554,13 +554,12 @@ static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode) int val_len; zval *id; dba_info *info = NULL; - int ac = ZEND_NUM_ARGS(); zval *key; char *val; char *key_str, *key_free; size_t key_len; - if (zend_parse_parameters(ac TSRMLS_CC, "zsr", &key, &val, &val_len, &id) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zsr", &key, &val, &val_len, &id) == FAILURE) { return; } @@ -634,7 +633,7 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* we pass additional args to the respective handler */ args = safe_emalloc(ac, sizeof(zval *), 0); - if (zend_get_parameters_array_ex(ac, args) != SUCCESS) { + if (zend_get_parameters_array_nodefault(ac, args TSRMLS_CC) != SUCCESS) { FREENOW; WRONG_PARAM_COUNT; } diff --git a/ext/enchant/enchant.c b/ext/enchant/enchant.c index 6de2feac80470..4ce1b05aa5982 100644 --- a/ext/enchant/enchant.c +++ b/ext/enchant/enchant.c @@ -740,7 +740,7 @@ PHP_FUNCTION(enchant_dict_quick_check) size_t n_sugg_st; char **suggs; - if (!sugg && ZEND_NUM_ARGS() == 2) { + if (!sugg) { RETURN_FALSE; } diff --git a/ext/ereg/ereg.c b/ext/ereg/ereg.c index 20f967feb9d95..e910e76a5d0bf 100644 --- a/ext/ereg/ereg.c +++ b/ext/ereg/ereg.c @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | - | Jaakko Hyvätti | + | Jaakko Hyv�tti | +----------------------------------------------------------------------+ */ /* $Id$ */ @@ -300,9 +300,8 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase) off_t start, end; char *buf = NULL; char *string = NULL; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "Zs|Z", ®ex, &findin, &findin_len, &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs|Z", ®ex, &findin, &findin_len, &array) == FAILURE) { return; } @@ -310,7 +309,7 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase) copts |= REG_ICASE; } - if (argc == 2) { + if (array == NULL) { copts |= REG_NOSUB; } @@ -455,7 +454,7 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co 1) find out how long the string will be, and allocate buf 2) copy the part before match, replacement and backrefs to buf - Jaakko Hyvätti + Jaakko Hyv�tti */ new_l = strlen(buf) + subs[0].rm_so; /* part before the match */ diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 14d9f90af7736..03eaf652f8bee 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -2556,35 +2556,26 @@ PHP_FUNCTION(imagecreatefromgd2part) static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) { zval *imgind; - char *file = NULL; - long quality = 0, type = 0; + long quality = -1, type = 1; gdImagePtr im; char *fn = NULL; FILE *fp; - int file_len = 0, argc = ZEND_NUM_ARGS(); + int file_len = 0; int q = -1, i, t = 1; /* The quality parameter for Wbmp stands for the threshold when called from image2wbmp() */ /* When called from imagewbmp() the quality parameter stands for the foreground color. Default: black. */ /* The quality parameter for gd2 stands for chunk size */ - if (zend_parse_parameters(argc TSRMLS_CC, "r|pll", &imgind, &file, &file_len, &quality, &type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|pll", &imgind, &fn, &file_len, &quality, &type) == FAILURE) { return; } ZEND_FETCH_RESOURCE(im, gdImagePtr, &imgind, -1, "Image", le_gd); - - if (argc > 1) { - fn = file; - if (argc == 3) { q = quality; - } - if (argc == 4) { t = type; - } - } - if (argc >= 2 && file_len) { + if (fn != NULL && file_len) { PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename"); fp = VCWD_FOPEN(fn, "wb"); @@ -3279,7 +3270,7 @@ PHP_FUNCTION(imagecolorstotal) PHP_FUNCTION(imagecolortransparent) { zval *IM; - long COL = 0; + long COL = -1; gdImagePtr im; int argc = ZEND_NUM_ARGS(); @@ -3303,7 +3294,7 @@ PHP_FUNCTION(imageinterlace) { zval *IM; int argc = ZEND_NUM_ARGS(); - long INT = 0; + long INT = 1; gdImagePtr im; if (zend_parse_parameters(argc TSRMLS_CC, "r|l", &IM, &INT) == FAILURE) { @@ -4273,7 +4264,7 @@ PHP_FUNCTION(imagepsbbox) ZEND_WRONG_PARAM_COUNT(); } - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "srl|lld", &str, &str_len, &fnt, &sz, &sp, &wd, &angle) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "srl|lld", &str, &str_len, &fnt, &sz, &sp, &wd, &angle) == FAILURE) { return; } diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c index 59eff80443685..a0f5dd65d83b5 100644 --- a/ext/gd/gd_ctx.c +++ b/ext/gd/gd_ctx.c @@ -79,9 +79,8 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, zval *imgind; char *file = NULL; int file_len = 0; - long quality, basefilter; + long quality = -1, basefilter = -1; gdImagePtr im; - int argc = ZEND_NUM_ARGS(); int q = -1, i; int f = -1; gdIOCtx *ctx = NULL; @@ -109,15 +108,10 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, } ZEND_FETCH_RESOURCE(im, gdImagePtr, &imgind, -1, "Image", phpi_get_le_gd()); - - if (argc >= 3) { q = quality; /* or colorindex for foreground of BW images (defaults to black) */ - if (argc == 4) { f = basefilter; - } - } - if (argc > 1 && to_zval != NULL) { + if (to_zval != NULL) { if (Z_TYPE_P(to_zval) == IS_RESOURCE) { php_stream_from_zval_no_verify(stream, &to_zval); if (stream == NULL) { @@ -172,7 +166,7 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, break; case PHP_GDIMG_TYPE_XBM: case PHP_GDIMG_TYPE_WBM: - if (argc < 3) { + if (ZEND_NUM_ARGS() < 3) { for(i=0; i < gdImageColorsTotal(im); i++) { if(!gdImageRed(im, i) && !gdImageGreen(im, i) && !gdImageBlue(im, i)) break; } diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 928ec778dcdb1..d71a5ba13c99a 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -333,13 +333,13 @@ Initialize a hashing context */ PHP_FUNCTION(hash_init) { char *algo, *key = NULL; - int algo_len, key_len = 0, argc = ZEND_NUM_ARGS(); + int algo_len, key_len = 0; long options = 0; void *context; const php_hash_ops *ops; php_hash_data *hash; - if (zend_parse_parameters(argc TSRMLS_CC, "s|ls", &algo, &algo_len, &options, &key, &key_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls", &algo, &algo_len, &options, &key, &key_len) == FAILURE) { return; } diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 87ad5eeaab0c0..30ed19b57c3ff 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -2028,7 +2028,7 @@ PHP_FUNCTION(iconv_substr) int charset_len = 0; char *str; int str_len; - long offset, length = 0; + long offset, length = LONG_MAX; php_iconv_err_t err; @@ -2045,7 +2045,7 @@ PHP_FUNCTION(iconv_substr) RETURN_FALSE; } - if (ZEND_NUM_ARGS() < 3) { + if (length == LONG_MAX) { length = str_len; } diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c index 0e8310a367b76..dcb0a88ad0e84 100644 --- a/ext/imap/php_imap.c +++ b/ext/imap/php_imap.c @@ -1721,7 +1721,7 @@ PHP_FUNCTION(imap_body) PHP_FUNCTION(imap_mail_copy) { zval *streamind; - long options = 0; + long options = NIL; char *seq, *folder; int seq_len, folder_len, argc = ZEND_NUM_ARGS(); pils *imap_le_struct; @@ -1994,10 +1994,9 @@ PHP_FUNCTION(imap_delete) { zval *streamind, **sequence; pils *imap_le_struct; - long flags = 0; - int argc = ZEND_NUM_ARGS(); + long flags = NIL; - if (zend_parse_parameters(argc TSRMLS_CC, "rZ|l", &streamind, &sequence, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ|l", &streamind, &sequence, &flags) == FAILURE) { return; } @@ -2005,7 +2004,7 @@ PHP_FUNCTION(imap_delete) convert_to_string_ex(sequence); - mail_setflag_full(imap_le_struct->imap_stream, Z_STRVAL_PP(sequence), "\\DELETED", (argc == 3 ? flags : NIL)); + mail_setflag_full(imap_le_struct->imap_stream, Z_STRVAL_PP(sequence), "\\DELETED", flags); RETVAL_TRUE; } /* }}} */ @@ -2015,11 +2014,10 @@ PHP_FUNCTION(imap_delete) PHP_FUNCTION(imap_undelete) { zval *streamind, **sequence; - long flags = 0; + long flags = NIL; pils *imap_le_struct; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rZ|l", &streamind, &sequence, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ|l", &streamind, &sequence, &flags) == FAILURE) { return; } @@ -2027,7 +2025,7 @@ PHP_FUNCTION(imap_undelete) convert_to_string_ex(sequence); - mail_clearflag_full(imap_le_struct->imap_stream, Z_STRVAL_PP(sequence), "\\DELETED", (argc == 3 ? flags : NIL)); + mail_clearflag_full(imap_le_struct->imap_stream, Z_STRVAL_PP(sequence), "\\DELETED", flags); RETVAL_TRUE; } /* }}} */ @@ -2039,7 +2037,7 @@ PHP_FUNCTION(imap_headerinfo) zval *streamind; char *defaulthost = NULL; int defaulthost_len = 0, argc = ZEND_NUM_ARGS(); - long msgno, fromlength, subjectlength; + long msgno, fromlength = 0, subjectlength = 0; pils *imap_le_struct; MESSAGECACHE *cache; ENVELOPE *en; @@ -2056,16 +2054,12 @@ PHP_FUNCTION(imap_headerinfo) php_error_docref(NULL TSRMLS_CC, E_WARNING, "From length has to be between 0 and %d", MAILTMPLEN); RETURN_FALSE; } - } else { - fromlength = 0x00; } if (argc >= 4) { if (subjectlength < 0 || subjectlength > MAILTMPLEN) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Subject length has to be between 0 and %d", MAILTMPLEN); RETURN_FALSE; } - } else { - subjectlength = 0x00; } PHP_IMAP_CHECK_MSGNO(msgno); @@ -2121,13 +2115,13 @@ PHP_FUNCTION(imap_rfc822_parse_headers) { char *headers, *defaulthost = NULL; ENVELOPE *en; - int headers_len, defaulthost_len = 0, argc = ZEND_NUM_ARGS(); + int headers_len, defaulthost_len = 0; - if (zend_parse_parameters(argc TSRMLS_CC, "s|s", &headers, &headers_len, &defaulthost, &defaulthost_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &headers, &headers_len, &defaulthost, &defaulthost_len) == FAILURE) { return; } - if (argc == 2) { + if (defaulthost != NULL) { rfc822_parse_msg(&en, NULL, headers, headers_len, NULL, defaulthost, NIL); } else { rfc822_parse_msg(&en, NULL, headers, headers_len, NULL, "UNKNOWN", NIL); @@ -3069,17 +3063,16 @@ PHP_FUNCTION(imap_clearflag_full) zval *streamind; char *sequence, *flag; int sequence_len, flag_len; - long flags = 0; + long flags = NIL; pils *imap_le_struct; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rss|l", &streamind, &sequence, &sequence_len, &flag, &flag_len, &flags) ==FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss|l", &streamind, &sequence, &sequence_len, &flag, &flag_len, &flags) ==FAILURE) { return; } ZEND_FETCH_RESOURCE(imap_le_struct, pils *, &streamind, -1, "imap", le_imap); - mail_clearflag_full(imap_le_struct->imap_stream, sequence, flag, (argc == 4 ? flags : NIL)); + mail_clearflag_full(imap_le_struct->imap_stream, sequence, flag, flags); RETURN_TRUE; } /* }}} */ @@ -3391,9 +3384,8 @@ PHP_FUNCTION(imap_fetch_overview) zval *myoverview; char *address; long status, flags = 0L; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rs|l", &streamind, &sequence, &sequence_len, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &streamind, &sequence, &sequence_len, &flags) == FAILURE) { return; } @@ -4046,9 +4038,9 @@ int _php_imap_mail(char *to, char *subject, char *message, char *headers, char * PHP_FUNCTION(imap_mail) { char *to=NULL, *message=NULL, *headers=NULL, *subject=NULL, *cc=NULL, *bcc=NULL, *rpath=NULL; - int to_len, message_len, headers_len, subject_len, cc_len, bcc_len, rpath_len, argc = ZEND_NUM_ARGS(); + int to_len, message_len, headers_len, subject_len, cc_len, bcc_len, rpath_len; - if (zend_parse_parameters(argc TSRMLS_CC, "sss|ssss", &to, &to_len, &subject, &subject_len, &message, &message_len, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ssss", &to, &to_len, &subject, &subject_len, &message, &message_len, &headers, &headers_len, &cc, &cc_len, &bcc, &bcc_len, &rpath, &rpath_len) == FAILURE) { return; } @@ -4091,10 +4083,9 @@ PHP_FUNCTION(imap_search) pils *imap_le_struct; char *search_criteria; MESSAGELIST *cur; - int argc = ZEND_NUM_ARGS(); SEARCHPGM *pgm = NIL; - if (zend_parse_parameters(argc TSRMLS_CC, "rs|ls", &streamind, &criteria, &criteria_len, &flags, &charset, &charset_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|ls", &streamind, &criteria, &criteria_len, &flags, &charset, &charset_len) == FAILURE) { return; } @@ -4105,7 +4096,7 @@ PHP_FUNCTION(imap_search) IMAPG(imap_messages) = IMAPG(imap_messages_tail) = NIL; pgm = mail_criteria(search_criteria); - mail_search_full(imap_le_struct->imap_stream, (argc == 4 ? charset : NIL), pgm, flags); + mail_search_full(imap_le_struct->imap_stream, (charset != NULL ? charset : NIL), pgm, flags); if (pgm && !(flags & SE_FREE)) { mail_free_searchpgm(&pgm); @@ -4712,10 +4703,9 @@ PHP_FUNCTION(imap_thread) long flags = SE_FREE; char criteria[] = "ALL"; THREADNODE *top; - int argc = ZEND_NUM_ARGS(); SEARCHPGM *pgm = NIL; - if (zend_parse_parameters(argc TSRMLS_CC, "r|l", &streamind, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &streamind, &flags) == FAILURE) { return; } diff --git a/ext/interbase/ibase_blobs.c b/ext/interbase/ibase_blobs.c index 7c27ccf3250e2..75f0807b9eb19 100644 --- a/ext/interbase/ibase_blobs.c +++ b/ext/interbase/ibase_blobs.c @@ -128,18 +128,16 @@ int _php_ibase_blob_get(zval *return_value, ibase_blob *ib_blob, unsigned long m } /* }}} */ -int _php_ibase_blob_add(zval **string_arg, ibase_blob *ib_blob TSRMLS_DC) /* {{{ */ +int _php_ibase_blob_add(const char *str, int str_len, ibase_blob *ib_blob TSRMLS_DC) /* {{{ */ { unsigned long put_cnt = 0, rem_cnt; unsigned short chunk_size; - convert_to_string_ex(string_arg); - - for (rem_cnt = Z_STRLEN_PP(string_arg); rem_cnt > 0; rem_cnt -= chunk_size) { + for (rem_cnt = str_len; rem_cnt > 0; rem_cnt -= chunk_size) { chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : (unsigned short)rem_cnt; - if (isc_put_segment(IB_STATUS, &ib_blob->bl_handle, chunk_size, &Z_STRVAL_PP(string_arg)[put_cnt] )) { + if (isc_put_segment(IB_STATUS, &ib_blob->bl_handle, chunk_size, &str[put_cnt] )) { _php_ibase_error(TSRMLS_C); return FAILURE; } @@ -293,23 +291,25 @@ PHP_FUNCTION(ibase_blob_open) Add data into created blob */ PHP_FUNCTION(ibase_blob_add) { - zval **blob_arg, **string_arg; + zval *blob_handle = NULL; + char *str; + int str_len; ibase_blob *ib_blob; RESET_ERRMSG; - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &blob_arg, &string_arg) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &blob_handle, &str, &str_len)) { WRONG_PARAM_COUNT; } - ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob); + ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, &blob_handle, -1, "Interbase blob", le_blob); if (ib_blob->type != BLOB_INPUT) { _php_ibase_module_error("BLOB is not open for input" TSRMLS_CC); RETURN_FALSE; } - if (_php_ibase_blob_add(string_arg, ib_blob TSRMLS_CC) != SUCCESS) { + if (_php_ibase_blob_add(str, str_len, ib_blob TSRMLS_CC) != SUCCESS) { RETURN_FALSE; } } @@ -319,25 +319,24 @@ PHP_FUNCTION(ibase_blob_add) Get len bytes data from open blob */ PHP_FUNCTION(ibase_blob_get) { - zval **blob_arg, **len_arg; + zval *blob_handle = NULL; + long len; ibase_blob *ib_blob; RESET_ERRMSG; - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &blob_arg, &len_arg) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &blob_handle, &len) == FAILURE) { WRONG_PARAM_COUNT; } - ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob); + ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, &blob_handle, -1, "Interbase blob", le_blob); if (ib_blob->type != BLOB_OUTPUT) { _php_ibase_module_error("BLOB is not open for output" TSRMLS_CC); RETURN_FALSE; } - convert_to_long_ex(len_arg); - - if (_php_ibase_blob_get(return_value, ib_blob, Z_LVAL_PP(len_arg) TSRMLS_CC) != SUCCESS) { + if (_php_ibase_blob_get(return_value, ib_blob, len TSRMLS_CC) != SUCCESS) { RETURN_FALSE; } } @@ -345,16 +344,16 @@ PHP_FUNCTION(ibase_blob_get) static void _php_ibase_blob_end(INTERNAL_FUNCTION_PARAMETERS, int bl_end) /* {{{ */ { - zval **blob_arg; - ibase_blob *ib_blob; + zval *blob_handle = NULL; + ibase_blob *ib_blob = NULL; RESET_ERRMSG; - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &blob_arg) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &blob_handle) == FAILURE) { WRONG_PARAM_COUNT; } - ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob); + ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, &blob_handle, -1, "Interbase blob", le_blob); if (bl_end == BLOB_CLOSE) { /* return id here */ @@ -375,7 +374,7 @@ static void _php_ibase_blob_end(INTERNAL_FUNCTION_PARAMETERS, int bl_end) /* {{{ ib_blob->bl_handle = NULL; RETVAL_TRUE; } - zend_list_delete(Z_LVAL_PP(blob_arg)); + zend_list_delete(Z_LVAL_P(blob_handle)); } /* }}} */ @@ -538,7 +537,7 @@ PHP_FUNCTION(ibase_blob_echo) Create blob, copy file in it, and close it */ PHP_FUNCTION(ibase_blob_import) { - zval *link = NULL, *file; + zval *link = NULL, *file = NULL; int size; unsigned short b; ibase_blob ib_blob = { NULL, 0 }; @@ -549,7 +548,7 @@ PHP_FUNCTION(ibase_blob_import) RESET_ERRMSG; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|r", + if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "r|r", (ZEND_NUM_ARGS()-1) ? &link : &file, &file)) { RETURN_FALSE; } diff --git a/ext/interbase/ibase_events.c b/ext/interbase/ibase_events.c index 09cdbfa404967..b95f73487eaf3 100644 --- a/ext/interbase/ibase_events.c +++ b/ext/interbase/ibase_events.c @@ -161,7 +161,7 @@ PHP_FUNCTION(ibase_wait_event) } } - for (; i < ZEND_NUM_ARGS(); ++i) { + for (; i < num_args; ++i) { convert_to_string_ex(args[i]); events[event_count++] = Z_STRVAL_PP(args[i]); } @@ -340,14 +340,14 @@ PHP_FUNCTION(ibase_set_event_handler) event->link = ib_link; event->event_count = 0; event->state = NEW; - event->events = (char **) safe_emalloc(sizeof(char *),ZEND_NUM_ARGS()-i,0); + event->events = (char **) safe_emalloc(sizeof(char *),num_args-i,0); ALLOC_ZVAL(event->callback); *event->callback = **cb_arg; INIT_PZVAL(event->callback); zval_copy_ctor(event->callback); - for (; i < ZEND_NUM_ARGS(); ++i) { + for (; i < num_args; ++i) { convert_to_string_ex(args[i]); event->events[event->event_count++] = estrdup(Z_STRVAL_PP(args[i])); } diff --git a/ext/interbase/ibase_query.c b/ext/interbase/ibase_query.c index 53eb7a885ef07..e1be74c828bd3 100644 --- a/ext/interbase/ibase_query.c +++ b/ext/interbase/ibase_query.c @@ -1169,9 +1169,16 @@ PHP_FUNCTION(ibase_query) break; } } else if (bind_n > 0) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &bind_args, &bind_num) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_NUM_ARGS() TSRMLS_CC, "+", &bind_args, &bind_num) == FAILURE) { return; } + if(bind_num != expected_n) { + php_error_docref(NULL TSRMLS_CC, (bind_num < expected_n) ? E_WARNING : E_NOTICE, + "Statement expects %d arguments, %d given", expected_n, bind_num); + if (bind_num < expected_n) { + break; + } + } } if (FAILURE == _php_ibase_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, &result, &ib_query, diff --git a/ext/interbase/interbase.c b/ext/interbase/interbase.c index c78c5226061e0..6cbaf90646cb5 100644 --- a/ext/interbase/interbase.c +++ b/ext/interbase/interbase.c @@ -1064,7 +1064,7 @@ PHP_FUNCTION(ibase_close) return; } - if (ZEND_NUM_ARGS() == 0) { + if (link_arg == NULL) { link_id = IBG(default_link); CHECK_LINK(link_id); IBG(default_link) = -1; @@ -1093,7 +1093,7 @@ PHP_FUNCTION(ibase_drop_db) return; } - if (ZEND_NUM_ARGS() == 0) { + if (link_arg == NULL) { link_id = IBG(default_link); CHECK_LINK(link_id); IBG(default_link) = -1; @@ -1324,7 +1324,7 @@ static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{ return; } - if (ZEND_NUM_ARGS() == 0) { + if (arg == NULL) { ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink); if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) { /* this link doesn't have a default transaction */ diff --git a/ext/intl/grapheme/grapheme_string.c b/ext/intl/grapheme/grapheme_string.c index 8a094e015e433..28bc7c6dd9bc3 100644 --- a/ext/intl/grapheme/grapheme_string.c +++ b/ext/intl/grapheme/grapheme_string.c @@ -409,14 +409,22 @@ PHP_FUNCTION(grapheme_substr) UBreakIterator* bi = NULL; int sub_str_start_pos, sub_str_end_pos; int32_t (*iter_func)(UBreakIterator *); + int no_length = 1; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", (char **)&str, &str_len, &lstart, &length) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l!", (char **)&str, &str_len, &lstart, &length, &no_length) == FAILURE) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_substr: unable to parse input param", 0 TSRMLS_CC ); RETURN_FALSE; } + if(no_length) { + length = str_len; + } else if(length < INT32_MIN) { + length = INT32_MIN; + } else if(length > INT32_MAX) { + length = INT32_MAX; + } if ( OUTSIDE_STRING(lstart, str_len) ) { @@ -431,7 +439,7 @@ PHP_FUNCTION(grapheme_substr) /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ if ( grapheme_ascii_check(str, str_len) >= 0 ) { - grapheme_substr_ascii((char *)str, str_len, start, length, ZEND_NUM_ARGS(), (char **) &sub_str, &sub_str_len); + grapheme_substr_ascii((char *)str, str_len, start, (int32_t)length, (char **) &sub_str, &sub_str_len); if ( NULL == sub_str ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_substr: invalid parameters", 1 TSRMLS_CC ); @@ -499,9 +507,9 @@ PHP_FUNCTION(grapheme_substr) RETURN_FALSE; } - if (ZEND_NUM_ARGS() <= 2) { + if (length >= str_len) { - /* no length supplied, return the rest of the string */ + /* no length supplied or length too big, return the rest of the string */ sub_str = NULL; sub_str_len = 0; diff --git a/ext/intl/grapheme/grapheme_util.c b/ext/intl/grapheme/grapheme_util.c index c752b02372e2c..e1036eb6b678a 100644 --- a/ext/intl/grapheme/grapheme_util.c +++ b/ext/intl/grapheme/grapheme_util.c @@ -49,19 +49,15 @@ grapheme_close_global_iterator( TSRMLS_D ) /* }}} */ /* {{{ grapheme_substr_ascii f='from' - starting point, l='length' */ -void grapheme_substr_ascii(char *str, int str_len, int f, int l, int argc, char **sub_str, int *sub_str_len) +void grapheme_substr_ascii(char *str, int32_t str_len, int32_t f, int32_t l, char **sub_str, int *sub_str_len) { *sub_str = NULL; - if (argc > 2) { if ((l < 0 && -l > str_len)) { return; } else if (l > str_len) { l = str_len; } - } else { - l = str_len; - } if (f > str_len || (f < 0 && -f > str_len)) { return; diff --git a/ext/intl/grapheme/grapheme_util.h b/ext/intl/grapheme/grapheme_util.h index 14f3f22c456b4..095995f24dd3e 100644 --- a/ext/intl/grapheme/grapheme_util.h +++ b/ext/intl/grapheme/grapheme_util.h @@ -23,7 +23,8 @@ /* get_break_interator: get a break iterator from the global structure */ UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status TSRMLS_DC ); -void grapheme_substr_ascii(char *str, int32_t str_len, int32_t f, int32_t l, int argc, char **sub_str, int *sub_str_len); +void +grapheme_substr_ascii(char *str, int32_t str_len, int32_t f, int32_t l, char **sub_str, int *sub_str_len); int grapheme_strrpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int f_ignore_case TSRMLS_DC); @@ -41,7 +42,8 @@ int grapheme_get_haystack_offset(UBreakIterator* bi, int32_t offset); int32_t grapheme_strrpos_ascii(unsigned char *haystack, int32_t haystack_len, unsigned char *needle, int32_t needle_len, int32_t offset); -UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status TSRMLS_DC ); +UBreakIterator* +grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status TSRMLS_DC ); /* OUTSIDE_STRING: check if (possibly negative) long offset is outside the string with int32_t length */ #define OUTSIDE_STRING(offset, max_len) ( offset <= INT32_MIN || offset > INT32_MAX || (offset < 0 ? -offset > (long) max_len : offset >= (long) max_len) ) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index f5583cd8c02c4..230759de11e10 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -603,7 +603,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) { zval *link, *base_dn, **filter, *attrs = NULL, **attr; - long attrsonly, sizelimit, timelimit, deref; + long attrsonly = 0, sizelimit = -1, timelimit = -1, deref = -1; char *ldap_base_dn = NULL, *ldap_filter = NULL, **ldap_attrs = NULL; ldap_linkdata *ld = NULL; LDAPMessage *ldap_res; @@ -627,6 +627,8 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) case 5: ldap_attrsonly = attrsonly; case 4: + if(attrs == NULL) break; + num_attribs = zend_hash_num_elements(Z_ARRVAL_P(attrs)); ldap_attrs = safe_emalloc((num_attribs+1), sizeof(char *), 0); @@ -2189,7 +2191,7 @@ PHP_FUNCTION(ldap_set_option) Extract information from result */ PHP_FUNCTION(ldap_parse_result) { - zval *link, *result, *errcode, *matcheddn, *errmsg, *referrals; + zval *link, *result, *errcode, *matcheddn = NULL, *errmsg = NULL, *referrals = NULL; ldap_linkdata *ld; LDAPMessage *ldap_result; char **lreferrals, **refp; diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index e7f08a3256488..d5d93c7af20c4 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -693,7 +693,7 @@ php_mb_parse_encoding_list(const char *value, size_t value_length, const mbfl_en endp = tmpstr + value_length; n = 1; p1 = tmpstr; - while ((p2 = php_memnstr(p1, ",", 1, endp)) != NULL) { + while ((p2 = (char *)php_memnstr(p1, ",", 1, endp)) != NULL) { p1 = p2 + 1; n++; } @@ -706,7 +706,7 @@ php_mb_parse_encoding_list(const char *value, size_t value_length, const mbfl_en bauto = 0; p1 = tmpstr; do { - p2 = p = php_memnstr(p1, ",", 1, endp); + p2 = p = (char *)php_memnstr(p1, ",", 1, endp); if (p == NULL) { p = endp; } @@ -2206,7 +2206,7 @@ PHP_FUNCTION(mb_strlen) PHP_FUNCTION(mb_strpos) { int n, reverse = 0; - long offset; + long offset = 0; mbfl_string haystack, needle; char *enc_name = NULL; int enc_name_len; @@ -2368,7 +2368,7 @@ PHP_FUNCTION(mb_strrpos) PHP_FUNCTION(mb_stripos) { int n; - long offset; + long offset = 0; mbfl_string haystack, needle; const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name; int from_encoding_len; @@ -2397,7 +2397,7 @@ PHP_FUNCTION(mb_stripos) PHP_FUNCTION(mb_strripos) { int n; - long offset; + long offset = 0; mbfl_string haystack, needle; const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name; int from_encoding_len; @@ -2694,14 +2694,13 @@ PHP_FUNCTION(mb_substr_count) Returns part of a string */ PHP_FUNCTION(mb_substr) { - size_t argc = ZEND_NUM_ARGS(); - char *str, *encoding; - long from, len; + char *str, *encoding = NULL; + long from, len = LONG_MAX; int mblen, str_len, encoding_len; - zval **z_len = NULL; mbfl_string string, result, *ret; + zend_bool no_len = 1; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|Zs", &str, &str_len, &from, &z_len, &encoding, &encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l!s", &str, &str_len, &from, &len, &no_len, &encoding, &encoding_len) == FAILURE) { return; } @@ -2709,7 +2708,7 @@ PHP_FUNCTION(mb_substr) string.no_language = MBSTRG(language); string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (argc == 4) { + if (encoding != NULL) { string.no_encoding = mbfl_name2no_encoding(encoding); if (string.no_encoding == mbfl_no_encoding_invalid) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encoding); @@ -2720,11 +2719,8 @@ PHP_FUNCTION(mb_substr) string.val = (unsigned char *)str; string.len = str_len; - if (argc < 3 || Z_TYPE_PP(z_len) == IS_NULL) { + if (no_len || len > str_len) { len = str_len; - } else { - convert_to_long_ex(z_len); - len = Z_LVAL_PP(z_len); } /* measures length */ @@ -2771,22 +2767,21 @@ PHP_FUNCTION(mb_substr) Returns part of a string */ PHP_FUNCTION(mb_strcut) { - size_t argc = ZEND_NUM_ARGS(); - char *encoding; - long from, len; + char *encoding = NULL; + long from, len = LONG_MAX; int encoding_len; - zval **z_len = NULL; mbfl_string string, result, *ret; + zend_bool no_len = 1; mbfl_string_init(&string); string.no_language = MBSTRG(language); string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|Zs", (char **)&string.val, (int **)&string.len, &from, &z_len, &encoding, &encoding_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l!s", (char **)&string.val, (int **)&string.len, &from, &len, &no_len, &encoding, &encoding_len) == FAILURE) { return; } - if (argc == 4) { + if (encoding != NULL) { string.no_encoding = mbfl_name2no_encoding(encoding); if (string.no_encoding == mbfl_no_encoding_invalid) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encoding); @@ -2794,11 +2789,8 @@ PHP_FUNCTION(mb_strcut) } } - if (argc < 3 || Z_TYPE_PP(z_len) == IS_NULL) { + if (no_len || len > string.len) { len = string.len; - } else { - convert_to_long_ex(z_len); - len = Z_LVAL_PP(z_len); } /* if "from" position is negative, count start position from the end @@ -2873,7 +2865,7 @@ PHP_FUNCTION(mb_strwidth) Trim the string in terminal width */ PHP_FUNCTION(mb_strimwidth) { - char *str, *trimmarker, *encoding; + char *str, *trimmarker = NULL, *encoding = NULL; long from, width; int str_len, trimmarker_len, encoding_len; mbfl_string string, result, marker, *ret; @@ -2891,7 +2883,7 @@ PHP_FUNCTION(mb_strimwidth) marker.val = NULL; marker.len = 0; - if (ZEND_NUM_ARGS() == 5) { + if (encoding != NULL) { string.no_encoding = marker.no_encoding = mbfl_name2no_encoding(encoding); if (string.no_encoding == mbfl_no_encoding_invalid) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encoding); @@ -2912,7 +2904,7 @@ PHP_FUNCTION(mb_strimwidth) RETURN_FALSE; } - if (ZEND_NUM_ARGS() >= 4) { + if (trimmarker != NULL) { marker.val = (unsigned char *)trimmarker; marker.len = trimmarker_len; } @@ -3020,7 +3012,7 @@ PHP_FUNCTION(mb_convert_encoding) { char *arg_str, *arg_new; int str_len, new_len; - zval *arg_old; + zval *arg_old = NULL; int i; size_t size, l, n; char *_from_encodings = NULL, *ret, *s_free = NULL; @@ -3032,7 +3024,7 @@ PHP_FUNCTION(mb_convert_encoding) return; } - if (ZEND_NUM_ARGS() == 3) { + if (arg_old != NULL) { switch (Z_TYPE_P(arg_old)) { case IS_ARRAY: target_hash = Z_ARRVAL_P(arg_old); @@ -3166,8 +3158,8 @@ PHP_FUNCTION(mb_detect_encoding) { char *str; int str_len; - zend_bool strict=0; - zval *encoding_list; + zend_bool strict = (zend_bool)MBSTRG(strict_detection); + zval *encoding_list = NULL; mbfl_string string; const mbfl_encoding *ret; @@ -3181,7 +3173,7 @@ PHP_FUNCTION(mb_detect_encoding) /* make encoding list */ list = NULL; size = 0; - if (ZEND_NUM_ARGS() >= 2 && !ZVAL_IS_NULL(encoding_list)) { + if (encoding_list != NULL && !ZVAL_IS_NULL(encoding_list)) { switch (Z_TYPE_P(encoding_list)) { case IS_ARRAY: if (FAILURE == php_mb_parse_encoding_array(encoding_list, &list, &size, 0 TSRMLS_CC)) { @@ -3208,10 +3200,6 @@ PHP_FUNCTION(mb_detect_encoding) } } - if (ZEND_NUM_ARGS() < 3) { - strict = (zend_bool)MBSTRG(strict_detection); - } - if (size > 0 && list != NULL) { elist = list; } else { @@ -3689,17 +3677,16 @@ PHP_FUNCTION(mb_convert_variables) static void php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS, int type) { - char *str, *encoding; + char *str, *encoding = NULL; int str_len, encoding_len; zval *zconvmap, **hash_entry; HashTable *target_hash; - size_t argc = ZEND_NUM_ARGS(); int i, *convmap, *mapelm, mapsize=0; zend_bool is_hex = 0; mbfl_string string, result, *ret; enum mbfl_no_encoding no_encoding; - if (zend_parse_parameters(argc TSRMLS_CC, "sz|sb", &str, &str_len, &zconvmap, &encoding, &encoding_len, &is_hex) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|sb", &str, &str_len, &zconvmap, &encoding, &encoding_len, &is_hex) == FAILURE) { return; } @@ -3710,7 +3697,7 @@ php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS, int type) string.len = str_len; /* encoding */ - if ((argc == 3 || argc == 4) && encoding_len > 0) { + if (encoding != NULL && encoding_len > 0) { no_encoding = mbfl_name2no_encoding(encoding); if (no_encoding == mbfl_no_encoding_invalid) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encoding); @@ -3720,11 +3707,9 @@ php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS, int type) } } - if (argc == 4) { if (type == 0 && is_hex) { type = 2; /* output in hex format */ } - } /* conversion map */ convmap = NULL; diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index 4b1b924d0612c..ad029c46c737f 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -655,8 +655,7 @@ _php_mb_regex_init_options(const char *parg, int narg, OnigOptionType *option, O Returns the current encoding for regex as a string. */ PHP_FUNCTION(mb_regex_encoding) { - size_t argc = ZEND_NUM_ARGS(); - char *encoding; + char *encoding = NULL; int encoding_len; OnigEncoding mbctype; @@ -664,7 +663,7 @@ PHP_FUNCTION(mb_regex_encoding) return; } - if (argc == 0) { + if (encoding == NULL) { const char *retval = _php_mb_regex_mbctype2name(MBREX(current_mbctype)); if (retval == NULL) { @@ -672,7 +671,7 @@ PHP_FUNCTION(mb_regex_encoding) } RETURN_STRING((char *)retval, 1); - } else if (argc == 1) { + } else { mbctype = _php_mb_regex_name2mbctype(encoding); if (mbctype == ONIG_ENCODING_UNDEF) { @@ -689,7 +688,7 @@ PHP_FUNCTION(mb_regex_encoding) /* {{{ _php_mb_regex_ereg_exec */ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase) { - zval **arg_pattern, *array; + zval **arg_pattern, *array = NULL; char *string; int string_len; php_mb_regex_t *re; @@ -698,8 +697,6 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase) OnigOptionType options; char *str; - array = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs|z", &arg_pattern, &string, &string_len, &array) == FAILURE) { RETURN_FALSE; } @@ -1177,26 +1174,25 @@ PHP_FUNCTION(mb_ereg_match) static void _php_mb_regex_ereg_search_exec(INTERNAL_FUNCTION_PARAMETERS, int mode) { - size_t argc = ZEND_NUM_ARGS(); - char *arg_pattern, *arg_options; + char *arg_pattern = NULL, *arg_options = NULL; int arg_pattern_len, arg_options_len; int n, i, err, pos, len, beg, end; OnigOptionType option; OnigUChar *str; OnigSyntaxType *syntax; - if (zend_parse_parameters(argc TSRMLS_CC, "|ss", &arg_pattern, &arg_pattern_len, &arg_options, &arg_options_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &arg_pattern, &arg_pattern_len, &arg_options, &arg_options_len) == FAILURE) { return; } option = MBREX(regex_default_options); - if (argc == 2) { + if (arg_options != NULL) { option = 0; _php_mb_regex_init_options(arg_options, arg_options_len, &option, &syntax, NULL); } - if (argc > 0) { + if (arg_pattern != NULL) { /* create regex pattern buffer */ if ((MBREX(search_re) = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, option, MBREX(current_mbctype), MBREX(regex_default_syntax) TSRMLS_CC)) == NULL) { RETURN_FALSE; @@ -1307,18 +1303,17 @@ PHP_FUNCTION(mb_ereg_search_regs) Initialize string and regular expression for search. */ PHP_FUNCTION(mb_ereg_search_init) { - size_t argc = ZEND_NUM_ARGS(); zval *arg_str; char *arg_pattern = NULL, *arg_options = NULL; int arg_pattern_len = 0, arg_options_len = 0; OnigSyntaxType *syntax = NULL; OnigOptionType option; - if (zend_parse_parameters(argc TSRMLS_CC, "z|ss", &arg_str, &arg_pattern, &arg_pattern_len, &arg_options, &arg_options_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ss", &arg_str, &arg_pattern, &arg_pattern_len, &arg_options, &arg_options_len) == FAILURE) { return; } - if (argc > 1 && arg_pattern_len == 0) { + if (arg_pattern != NULL && arg_pattern_len == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty pattern"); RETURN_FALSE; } @@ -1326,12 +1321,12 @@ PHP_FUNCTION(mb_ereg_search_init) option = MBREX(regex_default_options); syntax = MBREX(regex_default_syntax); - if (argc == 3) { + if (arg_options != NULL) { option = 0; _php_mb_regex_init_options(arg_options, arg_options_len, &option, &syntax, NULL); } - if (argc > 1) { + if (arg_pattern != NULL) { /* create regex pattern buffer */ if ((MBREX(search_re) = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, option, MBREX(current_mbctype), syntax TSRMLS_CC)) == NULL) { RETURN_FALSE; diff --git a/ext/mssql/php_mssql.c b/ext/mssql/php_mssql.c index eef472aa3f066..f65e379596cb1 100644 --- a/ext/mssql/php_mssql.c +++ b/ext/mssql/php_mssql.c @@ -551,7 +551,7 @@ static void php_mssql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) mssql_link mssql, *mssql_ptr; char buffer[40]; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sssb", &host, &host_len, &user, &user_len, &passwd, &passwd_len, &new_link) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "|sssb", &host, &host_len, &user, &user_len, &passwd, &passwd_len, &new_link) == FAILURE) { return; } @@ -1326,27 +1326,22 @@ PHP_FUNCTION(mssql_query) char *query; zval *mssql_link_index = NULL; int query_len, retvalue, batchsize, num_fields; - long zbatchsize = 0; + long zbatchsize = MS_SQL_G(batchsize); mssql_link *mssql_ptr; mssql_result *result; int id = -1; dbsettime(MS_SQL_G(timeout)); - batchsize = MS_SQL_G(batchsize); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|rl", &query, &query_len, &mssql_link_index, &zbatchsize) == FAILURE) { return; } - switch(ZEND_NUM_ARGS()) { - case 1: + if(mssql_link_index == NULL) { id = php_mssql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); CHECK_LINK(id); - break; - case 3: - batchsize = (int) zbatchsize; - break; } + batchsize = (int) zbatchsize; ZEND_FETCH_RESOURCE2(mssql_ptr, mssql_link *, &mssql_link_index, id, "MS SQL-Link", le_link, le_plink); @@ -2025,7 +2020,7 @@ PHP_FUNCTION(mssql_bind) return; } - if (ZEND_NUM_ARGS() == 7 && !is_output) { + if (!is_output) { maxlen = -1; } diff --git a/ext/mysql/php_mysql.c b/ext/mysql/php_mysql.c index 3d092b2d6a167..7a79c6337904d 100644 --- a/ext/mysql/php_mysql.c +++ b/ext/mysql/php_mysql.c @@ -775,13 +775,13 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) } else { /* mysql_pconnect does not support new_link parameter */ if (persistent) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!l", &host_and_port, &host_len, + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!l", &host_and_port, &host_len, &user, &user_len, &passwd, &passwd_len, &client_flags)==FAILURE) { return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!bl", &host_and_port, &host_len, + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!bl", &host_and_port, &host_len, &user, &user_len, &passwd, &passwd_len, &new_link, &client_flags)==FAILURE) { return; @@ -1250,7 +1250,7 @@ PHP_FUNCTION(mysql_info) return; } - if (ZEND_NUM_ARGS() == 0) { + if (mysql_link == NULL) { id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); CHECK_LINK(id); } @@ -1277,7 +1277,7 @@ PHP_FUNCTION(mysql_thread_id) return; } - if (ZEND_NUM_ARGS() == 0) { + if (mysql_link == NULL) { id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); CHECK_LINK(id); } @@ -1303,7 +1303,7 @@ PHP_FUNCTION(mysql_stat) return; } - if (ZEND_NUM_ARGS() == 0) { + if (mysql_link == NULL) { id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); CHECK_LINK(id); } @@ -1335,7 +1335,7 @@ PHP_FUNCTION(mysql_client_encoding) return; } - if (ZEND_NUM_ARGS() == 0) { + if (mysql_link == NULL) { id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); CHECK_LINK(id); } @@ -1360,7 +1360,7 @@ PHP_FUNCTION(mysql_set_charset) return; } - if (ZEND_NUM_ARGS() == 1) { + if (mysql_link == NULL) { id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); CHECK_LINK(id); } @@ -1718,7 +1718,7 @@ PHP_FUNCTION(mysql_list_processes) return; } - if (ZEND_NUM_ARGS() == 0) { + if (mysql_link == NULL) { id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); CHECK_LINK(id); } @@ -1866,7 +1866,7 @@ PHP_FUNCTION(mysql_real_escape_string) return; } - if (ZEND_NUM_ARGS() == 1) { + if (mysql_link == NULL) { id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); CHECK_LINK(id); } @@ -2073,7 +2073,7 @@ static void php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, return; } - if (ZEND_NUM_ARGS() < 2) { + if (class_name == NULL) { ce = zend_standard_class_def; } else { ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); @@ -2668,11 +2668,12 @@ PHP_FUNCTION(mysql_ping) int id = -1; php_mysql_conn *mysql; - if (0 == ZEND_NUM_ARGS()) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link)==FAILURE) { + return; + } + if (mysql_link == NULL) { id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); CHECK_LINK(id); - } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &mysql_link)==FAILURE) { - return; } ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 2a5a8c61ff675..acbccdfc696f1 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -1035,37 +1035,20 @@ PHP_FUNCTION(mysqli_stmt_construct) zval *mysql_link; MY_STMT *stmt; MYSQLI_RESOURCE *mysqli_resource; - char *statement; + char *statement = NULL; int statement_len; - switch (ZEND_NUM_ARGS()) - { - case 1: /* mysql_stmt_init */ - if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|s", &mysql_link, mysqli_link_class_entry, &statement, &statement_len)==FAILURE) { return; } MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT)); - stmt->stmt = mysql_stmt_init(mysql->mysql); - break; - case 2: - if (zend_parse_parameters(2 TSRMLS_CC, "Os", &mysql_link, mysqli_link_class_entry, &statement, &statement_len)==FAILURE) { - return; - } - MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); - stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT)); - - if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) { + if(statement != NULL && stmt->stmt) { mysql_stmt_prepare(stmt->stmt, (char *)statement, statement_len); } - break; - default: - WRONG_PARAM_COUNT; - break; - } if (!stmt->stmt) { efree(stmt); @@ -1074,7 +1057,7 @@ PHP_FUNCTION(mysqli_stmt_construct) mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = (void *)stmt; - mysqli_resource->status = (ZEND_NUM_ARGS() == 1) ? MYSQLI_STATUS_INITIALIZED : MYSQLI_STATUS_VALID; + mysqli_resource->status = (statement == NULL) ? MYSQLI_STATUS_INITIALIZED : MYSQLI_STATUS_VALID; ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource; } @@ -1093,20 +1076,9 @@ PHP_FUNCTION(mysqli_result_construct) MYSQLI_RESOURCE *mysqli_resource; long resmode = MYSQLI_STORE_RESULT; - switch (ZEND_NUM_ARGS()) { - case 1: - if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) { - return; - } - break; - case 2: - if (zend_parse_parameters(2 TSRMLS_CC, "Ol", &mysql_link, mysqli_link_class_entry, &resmode)==FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|l", &mysql_link, mysqli_link_class_entry, &resmode)==FAILURE) { return; } - break; - default: - WRONG_PARAM_COUNT; - } MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); @@ -1235,13 +1207,13 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags zend_class_entry *ce = NULL; if (into_object) { - char *class_name; + char *class_name = NULL; int class_name_len; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sz", &mysql_result, mysqli_result_class_entry, &class_name, &class_name_len, &ctor_params) == FAILURE) { return; } - if (ZEND_NUM_ARGS() < (getThis() ? 1 : 2)) { + if (class_name == NULL) { ce = zend_standard_class_def; } else { ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index c2d184bd4d306..022e647ce238a 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -138,8 +138,7 @@ PHP_FUNCTION(mysqli_autocommit) /* {{{ mysqli_stmt_bind_param_do_bind */ #ifndef MYSQLI_USE_MYSQLND static -int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars, - zval ***args, unsigned int start, const char * const types TSRMLS_DC) +int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int offset, unsigned int num_vars, zval ***args, const char * const types TSRMLS_DC) { int i, ofs; MYSQL_BIND *bind; @@ -153,9 +152,8 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in stmt->param.is_null = ecalloc(num_vars, sizeof(char)); bind = (MYSQL_BIND *) ecalloc(num_vars, sizeof(MYSQL_BIND)); - ofs = 0; - for (i = start; i < argc; i++) { - + for (i = 0; i < num_vars; i++) { + ofs = i; /* set specified type */ switch (types[ofs]) { case 'd': /* Double */ @@ -186,11 +184,10 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in break; default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1+offset); rc = 1; goto end_1; } - ofs++; } rc = mysql_stmt_bind_param(stmt->stmt, bind); @@ -202,8 +199,8 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in stmt->param.vars = (zval **)safe_emalloc(num_vars, sizeof(zval), 0); for (i = 0; i < num_vars; i++) { if (bind[i].buffer_type != MYSQL_TYPE_LONG_BLOB) { - Z_ADDREF_P(*args[i+start]); - stmt->param.vars[i] = *args[i+start]; + Z_ADDREF_P(*args[i]); + stmt->param.vars[i] = *args[i]; } else { stmt->param.vars[i] = NULL; } @@ -215,22 +212,21 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in } #else static -int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars, - zval ***args, unsigned int start, const char * const types TSRMLS_DC) +int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int offset, unsigned int num_vars, zval ***args, const char * const types TSRMLS_DC) { unsigned int i; MYSQLND_PARAM_BIND *params; enum_func_status ret = FAIL; /* If no params -> skip binding and return directly */ - if (argc == start) { + if (args == NULL || num_vars == 0) { return PASS; } params = mysqlnd_stmt_alloc_param_bind(stmt->stmt); if (!params) { goto end; } - for (i = 0; i < (argc - start); i++) { + for (i = 0; i < num_vars; i++) { zend_uchar type; switch (types[i]) { case 'd': /* Double */ @@ -251,12 +247,12 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in break; default: /* We count parameters from 1 */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + 1 + offset); ret = FAIL; mysqlnd_stmt_free_param_bind(stmt->stmt, params); goto end; } - params[i].zv = *(args[i + start]); + params[i].zv = *(args[i]); params[i].type = type; } ret = mysqlnd_stmt_bind_param(stmt->stmt, params); @@ -271,42 +267,27 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in Bind variables to a prepared statement as parameters */ PHP_FUNCTION(mysqli_stmt_bind_param) { - zval ***args; - int argc = ZEND_NUM_ARGS(); - int num_vars; - int start = 2; + zval ***args = NULL; + int num_vars = 0; MY_STMT *stmt; zval *mysql_stmt; - char *types; + char *types = NULL; int types_len; unsigned long rc; - /* calculate and check number of parameters */ - if (argc < 2) { - /* there has to be at least one pair */ - WRONG_PARAM_COUNT; - } - - if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, - &types, &types_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os*", &mysql_stmt, mysqli_stmt_class_entry, + &types, &types_len, &args, &num_vars) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); - num_vars = argc - 1; - if (getThis()) { - start = 1; - } else { - /* ignore handle parameter in procedural interface*/ - --num_vars; - } if (!types_len) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type or no types specified"); RETURN_FALSE; } - if (types_len != argc - start) { + if (types_len != num_vars) { /* number of bind variables doesn't match number of elements in type definition string */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables"); RETURN_FALSE; @@ -317,17 +298,12 @@ PHP_FUNCTION(mysqli_stmt_bind_param) RETURN_FALSE; } - args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0); - - if (zend_get_parameters_array_ex(argc, args) == FAILURE) { - zend_wrong_param_count(TSRMLS_C); - rc = 1; - } else { - rc = mysqli_stmt_bind_param_do_bind(stmt, argc, num_vars, args, start, types TSRMLS_CC); + rc = mysqli_stmt_bind_param_do_bind(stmt, 2, num_vars, args, types TSRMLS_CC); MYSQLI_REPORT_STMT_ERROR(stmt->stmt); - } + if(args) { efree(args); + } RETURN_BOOL(!rc); } @@ -339,11 +315,10 @@ PHP_FUNCTION(mysqli_stmt_bind_param) do_alloca, free_alloca */ static int -mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC) +mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int var_cnt TSRMLS_DC) { MYSQL_BIND *bind; int i, ofs; - int var_cnt = argc - start; long col_type; ulong rc; @@ -361,8 +336,8 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, memset(p, 0, size); } - for (i=start; i < var_cnt + start ; i++) { - ofs = i - start; + for (i=0; i < var_cnt; i++) { + ofs = i; col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING; switch (col_type) { @@ -500,10 +475,9 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, } else { stmt->result.var_cnt = var_cnt; stmt->result.vars = (zval **)safe_emalloc((var_cnt), sizeof(zval), 0); - for (i = start; i < var_cnt+start; i++) { - ofs = i-start; + for (i = 0; i < var_cnt; i++) { Z_ADDREF_PP(args[i]); - stmt->result.vars[ofs] = *args[i]; + stmt->result.vars[i] = *args[i]; } } efree(bind); @@ -512,13 +486,13 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, } #else static int -mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC) +mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc TSRMLS_DC) { unsigned int i; MYSQLND_RESULT_BIND * params = mysqlnd_stmt_alloc_result_bind(stmt->stmt); if (params) { - for (i = 0; i < (argc - start); i++) { - params[i].zv = *(args[i + start]); + for (i = 0; i < argc; i++) { + params[i].zv = *(args[i]); } return mysqlnd_stmt_bind_result(stmt->stmt, params); } @@ -531,41 +505,24 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, Bind variables to a prepared statement for result storage */ PHP_FUNCTION(mysqli_stmt_bind_result) { - zval ***args; - int argc = ZEND_NUM_ARGS(); - int start = 1; + zval ***args = NULL; + int num_args; ulong rc; MY_STMT *stmt; zval *mysql_stmt; - if (getThis()) { - start = 0; - } - - if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O+", &mysql_stmt, mysqli_stmt_class_entry, &args, &num_args) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); - if (argc < (getThis() ? 1 : 2)) { - WRONG_PARAM_COUNT; - } - - if ((argc - start) != mysql_stmt_field_count(stmt->stmt)) { + if (num_args != mysql_stmt_field_count(stmt->stmt)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement"); RETURN_FALSE; } - args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0); - - if (zend_get_parameters_array_ex(argc, args) == FAILURE) { - efree(args); - WRONG_PARAM_COUNT; - } - - rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc, start TSRMLS_CC); - + rc = mysqli_stmt_bind_result_do_bind(stmt, args, num_args TSRMLS_CC); efree(args); RETURN_BOOL(!rc); diff --git a/ext/mysqli/mysqli_warning.c b/ext/mysqli/mysqli_warning.c index e100319e6187c..ede03405cd14a 100644 --- a/ext/mysqli/mysqli_warning.c +++ b/ext/mysqli/mysqli_warning.c @@ -273,10 +273,7 @@ PHP_METHOD(mysqli_warning, __construct) MYSQLI_WARNING *w; MYSQLI_RESOURCE *mysqli_resource; - if (ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - if (zend_parse_parameters(1 TSRMLS_CC, "o", &z)==FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &z)==FAILURE) { return; } obj = (mysqli_object *)zend_object_store_get_object(z TSRMLS_CC);\ diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt index 553e71ab6b5fc..146c8c0d1463a 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt @@ -320,8 +320,7 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_stmt_bind_result(): invalid object or resource mysqli_stmt - in %s on line %d +Warning: mysqli_stmt_bind_result() expects at least 2 parameters, 1 given in %s on line %d Warning: mysqli_stmt_bind_result(): Number of bind variables doesn't match number of fields in prepared statement in %s on line %d diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index a890c94dabeb0..adeecf581d5b8 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -2635,7 +2635,7 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg php_oci_out_column *column; ub4 nrows = 1; int i; - long fetch_mode = 0; + long fetch_mode = mode; if (expected_args > 2) { /* only for ocifetchinto BC */ @@ -2644,9 +2644,6 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg return; } - if (ZEND_NUM_ARGS() == 2) { - fetch_mode = mode; - } } else if (expected_args == 2) { /* only for oci_fetch_array() */ @@ -2654,9 +2651,6 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg return; } - if (ZEND_NUM_ARGS() == 1) { - fetch_mode = mode; - } } else { /* for all oci_fetch_*() */ @@ -2664,7 +2658,6 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg return; } - fetch_mode = mode; } if (!(fetch_mode & PHP_OCI_NUM) && !(fetch_mode & PHP_OCI_ASSOC)) { diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index d6a62325f32be..1237d2dc3df1c 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Stig Sæther Bakken | + | Authors: Stig S�ther Bakken | | Thies C. Arntzen | | | | Collection support by Andy Sautins | @@ -141,7 +141,7 @@ PHP_FUNCTION(oci_bind_array_by_name) PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement); - if (ZEND_NUM_ARGS() == 5 && max_item_len <= 0) { + if (max_item_len <= 0) { max_item_len = -1; } @@ -519,7 +519,7 @@ PHP_FUNCTION(oci_lob_write) zval **tmp, *z_descriptor = getThis(); php_oci_descriptor *descriptor; int data_len; - long write_len = 0; + long write_len = LONG_MAX; ub4 bytes_written; char *data; @@ -528,19 +528,15 @@ PHP_FUNCTION(oci_lob_write) return; } - if (ZEND_NUM_ARGS() == 2) { data_len = MIN(data_len, write_len); } - } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|l", &z_descriptor, oci_lob_class_entry_ptr, &data, &data_len, &write_len) == FAILURE) { return; } - if (ZEND_NUM_ARGS() == 3) { data_len = MIN(data_len, write_len); } - } if (zend_hash_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property"); @@ -649,7 +645,7 @@ PHP_FUNCTION(oci_lob_erase) long offset = -1, length = -1; if (getThis()) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &offset, &length) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &offset, &length) == FAILURE) { return; } @@ -664,7 +660,7 @@ PHP_FUNCTION(oci_lob_erase) } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|ll", &z_descriptor, oci_lob_class_entry_ptr, &offset, &length) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "O|ll", &z_descriptor, oci_lob_class_entry_ptr, &offset, &length) == FAILURE) { return; } @@ -799,7 +795,7 @@ PHP_FUNCTION(oci_lob_copy) php_oci_descriptor *descriptor_dest, *descriptor_from; long length = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO|l", &z_descriptor_dest, oci_lob_class_entry_ptr, &z_descriptor_from, oci_lob_class_entry_ptr, &length) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "OO|l", &z_descriptor_dest, oci_lob_class_entry_ptr, &z_descriptor_from, oci_lob_class_entry_ptr, &length) == FAILURE) { return; } @@ -884,9 +880,9 @@ PHP_FUNCTION(oci_lob_export) if (getThis()) { #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5) - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &filename, &filename_len, &start, &length) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &filename, &filename_len, &start, &length) == FAILURE) { #else - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &filename, &filename_len, &start, &length) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &filename, &filename_len, &start, &length) == FAILURE) { #endif return; } @@ -902,9 +898,9 @@ PHP_FUNCTION(oci_lob_export) } else { #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5) - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Op|ll", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len, &start, &length) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "Op|ll", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len, &start, &length) == FAILURE) { #else - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|ll", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len, &start, &length) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "Os|ll", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len, &start, &length) == FAILURE) { #endif return; } @@ -1615,7 +1611,7 @@ PHP_FUNCTION(oci_error) return; } - if (ZEND_NUM_ARGS() > 0) { + if (arg) { statement = (php_oci_statement *) zend_fetch_resource(&arg TSRMLS_CC, -1, NULL, NULL, 1, le_statement); if (statement) { errh = statement->err; diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 4d21b3a136774..81b6f1038d0c7 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Stig Sæther Bakken | + | Authors: Stig S�ther Bakken | | Andreas Karajannis | | Frank M. Kromann Support for DB/2 CLI | | Kevin N. Shallow Birdstep Support| @@ -1966,7 +1966,7 @@ PHP_FUNCTION(odbc_fetch_row) SQLUSMALLINT RowStatus[1]; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &pv_res, &pv_row) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &pv_res, &pv_row) == FAILURE) { return; } @@ -2221,7 +2221,7 @@ PHP_FUNCTION(odbc_result_all) } /* Start table tag */ - if (ZEND_NUM_ARGS() == 1) { + if (pv_format == NULL) { php_printf(""); } else { php_printf("
", pv_format); @@ -2498,7 +2498,6 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) cur_opt = pv_opt; - if (ZEND_NUM_ARGS() > 3) { /* Confirm the cur_opt range */ if (! (cur_opt == SQL_CUR_USE_IF_NEEDED || cur_opt == SQL_CUR_USE_ODBC || @@ -2507,7 +2506,6 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Cursor type (%d)", cur_opt); RETURN_FALSE; } - } if (ODBCG(allow_persistent) <= 0) { persistent = 0; @@ -2956,7 +2954,7 @@ static void php_odbc_lasterror(INTERNAL_FUNCTION_PARAMETERS, int mode) len = SQL_MAX_MESSAGE_LENGTH; } - if (ZEND_NUM_ARGS() == 1) { + if (pv_handle) { ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_handle, -1, "ODBC-Link", le_conn, le_pconn); ptr = ecalloc(len + 1, 1); if (mode == 0) { diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index b7ef4c729c099..c533a9d474d3f 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -759,7 +759,7 @@ PHP_FUNCTION(pcntl_exec) return; } - if (ZEND_NUM_ARGS() > 1) { + if (args != NULL) { /* Build argument list */ args_hash = HASH_OF(args); argc = zend_hash_num_elements(args_hash); @@ -780,7 +780,7 @@ PHP_FUNCTION(pcntl_exec) *(argv+1) = NULL; } - if ( ZEND_NUM_ARGS() == 3 ) { + if ( envs != NULL ) { /* Build environment pair list */ envs_hash = HASH_OF(envs); envc = zend_hash_num_elements(envs_hash); diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 84ad12311dced..7432000596b2d 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1375,9 +1375,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl SEPARATE_ZVAL(regex); SEPARATE_ZVAL(subject); - if (ZEND_NUM_ARGS() > 3) { limit_val = limit; - } if (Z_TYPE_PP(regex) != IS_ARRAY) convert_to_string_ex(regex); @@ -1422,7 +1420,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl } } } - if (ZEND_NUM_ARGS() > 4) { + if (zcount) { zval_dtor(*zcount); ZVAL_LONG(*zcount, replace_count); } diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index d17867d1f9486..b1b7ac4ad9952 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -525,7 +525,7 @@ static PHP_METHOD(PDO, prepare) PDO_DBH_CLEAR_ERR(); PDO_CONSTRUCT_CHECK; - if (ZEND_NUM_ARGS() > 1 && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), PDO_ATTR_STATEMENT_CLASS, (void**)&opt)) { + if (options != NULL && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), PDO_ATTR_STATEMENT_CLASS, (void**)&opt)) { if (Z_TYPE_PP(opt) != IS_ARRAY || zend_hash_index_find(Z_ARRVAL_PP(opt), 0, (void**)&item) == FAILURE || Z_TYPE_PP(item) != IS_STRING || zend_lookup_class(Z_STRVAL_PP(item), Z_STRLEN_PP(item), &pce TSRMLS_CC) == FAILURE diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 2735aede41c08..a497e1e38763b 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -466,7 +466,7 @@ static PHP_METHOD(PDOStatement, execute) param.paramno = -1; } else { /* we're okay to be zero based here */ - if (num_index < 0) { + if ((long)num_index < 0) { pdo_raise_impl_error(stmt->dbh, stmt, "HY093", NULL TSRMLS_CC); RETURN_FALSE; } @@ -1422,7 +1422,7 @@ static PHP_METHOD(PDOStatement, fetchAll) { long how = PDO_FETCH_USE_DEFAULT; zval *data, *return_all; - zval *arg2; + zval *arg2 = NULL; zend_class_entry *old_ce; zval *old_ctor_args, *ctor_args = NULL; int error = 0, flags, old_arg_count; @@ -1444,12 +1444,8 @@ static PHP_METHOD(PDOStatement, fetchAll) switch(how & ~PDO_FETCH_FLAGS) { case PDO_FETCH_CLASS: - switch(ZEND_NUM_ARGS()) { - case 0: - case 1: - stmt->fetch.cls.ce = zend_standard_class_def; - break; - case 3: + if(arg2) { + if(ctor_args) { if (Z_TYPE_P(ctor_args) != IS_NULL && Z_TYPE_P(ctor_args) != IS_ARRAY) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "ctor_args must be either NULL or an array" TSRMLS_CC); error = 1; @@ -1458,8 +1454,8 @@ static PHP_METHOD(PDOStatement, fetchAll) if (Z_TYPE_P(ctor_args) != IS_ARRAY || !zend_hash_num_elements(Z_ARRVAL_P(ctor_args))) { ctor_args = NULL; } - /* no break */ - case 2: + } + stmt->fetch.cls.ctor_args = ctor_args; /* we're not going to free these */ if (Z_TYPE_P(arg2) != IS_STRING) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "Invalid class name (should be a string)" TSRMLS_CC); @@ -1473,42 +1469,38 @@ static PHP_METHOD(PDOStatement, fetchAll) break; } } + } else { + stmt->fetch.cls.ce = zend_standard_class_def; } + if (!error) { do_fetch_class_prepare(stmt TSRMLS_CC); } break; case PDO_FETCH_FUNC: - switch(ZEND_NUM_ARGS()) { - case 0: - case 1: - pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "no fetch function specified" TSRMLS_CC); - error = 1; - break; - case 3: - case 2: + if(arg2) { stmt->fetch.func.function = arg2; if (do_fetch_func_prepare(stmt TSRMLS_CC) == 0) { error = 1; } - break; + } else { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "no fetch function specified" TSRMLS_CC); + error = 1; } break; case PDO_FETCH_COLUMN: - switch(ZEND_NUM_ARGS()) { - case 0: - case 1: - stmt->fetch.column = how & PDO_FETCH_GROUP ? -1 : 0; + if(ctor_args) { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "Third parameter not allowed for PDO::FETCH_COLUMN" TSRMLS_CC); + error = 1; break; - case 2: + } + if(arg2) { convert_to_long(arg2); stmt->fetch.column = Z_LVAL_P(arg2); - break; - case 3: - pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "Third parameter not allowed for PDO::FETCH_COLUMN" TSRMLS_CC); - error = 1; + } else { + stmt->fetch.column = how & PDO_FETCH_GROUP ? -1 : 0; } break; @@ -1877,7 +1869,7 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in { long mode = PDO_FETCH_BOTH; int flags = 0, argc = ZEND_NUM_ARGS() - skip; - zval ***args; + zval ***args = NULL; zend_class_entry **cep; int retval; @@ -1900,25 +1892,24 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in return SUCCESS; } - args = safe_emalloc(ZEND_NUM_ARGS(), sizeof(zval*), 0); - - retval = zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args); + argc = 0; + if(skip) { + zval *dummy; + retval = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl*", &dummy, &mode, &args, &argc); + } else { + retval = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l*", &mode, &args, &argc); + } if (SUCCESS == retval) { - if (Z_TYPE_PP(args[skip]) != IS_LONG) { - pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "mode must be an integer" TSRMLS_CC); - retval = FAILURE; - } else { - mode = Z_LVAL_PP(args[skip]); flags = mode & PDO_FETCH_FLAGS; - retval = pdo_stmt_verify_mode(stmt, mode, 0 TSRMLS_CC); } - } if (FAILURE == retval) { PDO_STMT_CLEAR_ERR(); + if(args) { efree(args); + } return FAILURE; } @@ -1933,7 +1924,7 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in case PDO_FETCH_BOUND: case PDO_FETCH_NAMED: case PDO_FETCH_KEY_PAIR: - if (argc != 1) { + if (argc > 0) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "fetch mode doesn't allow any extra arguments" TSRMLS_CC); } else { retval = SUCCESS; @@ -1941,12 +1932,12 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in break; case PDO_FETCH_COLUMN: - if (argc != 2) { + if (argc != 1) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "fetch mode requires the colno argument" TSRMLS_CC); - } else if (Z_TYPE_PP(args[skip+1]) != IS_LONG) { + } else if (Z_TYPE_PP(args[0]) != IS_LONG) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "colno must be an integer" TSRMLS_CC); } else { - stmt->fetch.column = Z_LVAL_PP(args[skip+1]); + stmt->fetch.column = Z_LVAL_PP(args[0]); retval = SUCCESS; } break; @@ -1954,22 +1945,22 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in case PDO_FETCH_CLASS: /* Gets its class name from 1st column */ if ((flags & PDO_FETCH_CLASSTYPE) == PDO_FETCH_CLASSTYPE) { - if (argc != 1) { + if (argc > 0) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "fetch mode doesn't allow any extra arguments" TSRMLS_CC); } else { stmt->fetch.cls.ce = NULL; retval = SUCCESS; } } else { - if (argc < 2) { + if (argc < 1) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "fetch mode requires the classname argument" TSRMLS_CC); - } else if (argc > 3) { + } else if (argc > 2) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "too many arguments" TSRMLS_CC); - } else if (Z_TYPE_PP(args[skip+1]) != IS_STRING) { + } else if (Z_TYPE_PP(args[0]) != IS_STRING) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "classname must be a string" TSRMLS_CC); } else { - retval = zend_lookup_class(Z_STRVAL_PP(args[skip+1]), - Z_STRLEN_PP(args[skip+1]), &cep TSRMLS_CC); + retval = zend_lookup_class(Z_STRVAL_PP(args[0]), + Z_STRLEN_PP(args[0]), &cep TSRMLS_CC); if (SUCCESS == retval && cep && *cep) { stmt->fetch.cls.ce = *cep; @@ -1984,13 +1975,13 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release"); } #endif - if (argc == 3) { - if (Z_TYPE_PP(args[skip+2]) != IS_NULL && Z_TYPE_PP(args[skip+2]) != IS_ARRAY) { + if (argc == 2) { + if (Z_TYPE_PP(args[1]) != IS_NULL && Z_TYPE_PP(args[1]) != IS_ARRAY) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "ctor_args must be either NULL or an array" TSRMLS_CC); retval = FAILURE; - } else if (Z_TYPE_PP(args[skip+2]) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_PP(args[skip+2]))) { + } else if (Z_TYPE_PP(args[1]) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_PP(args[1]))) { ALLOC_ZVAL(stmt->fetch.cls.ctor_args); - *stmt->fetch.cls.ctor_args = **args[skip+2]; + *stmt->fetch.cls.ctor_args = **args[1]; zval_copy_ctor(stmt->fetch.cls.ctor_args); } } @@ -2003,9 +1994,9 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in break; case PDO_FETCH_INTO: - if (argc != 2) { + if (argc != 1) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "fetch mode requires the object parameter" TSRMLS_CC); - } else if (Z_TYPE_PP(args[skip+1]) != IS_OBJECT) { + } else if (Z_TYPE_PP(args[0]) != IS_OBJECT) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "object must be an object" TSRMLS_CC); } else { retval = SUCCESS; @@ -2020,8 +2011,8 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in MAKE_STD_ZVAL(stmt->fetch.into); Z_TYPE_P(stmt->fetch.into) = IS_OBJECT; - Z_OBJ_HANDLE_P(stmt->fetch.into) = Z_OBJ_HANDLE_PP(args[skip+1]); - Z_OBJ_HT_P(stmt->fetch.into) = Z_OBJ_HT_PP(args[skip+1]); + Z_OBJ_HANDLE_P(stmt->fetch.into) = Z_OBJ_HANDLE_PP(args[0]); + Z_OBJ_HT_P(stmt->fetch.into) = Z_OBJ_HT_PP(args[0]); zend_objects_store_add_ref(stmt->fetch.into TSRMLS_CC); } @@ -2043,8 +2034,9 @@ int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, in * */ PDO_STMT_CLEAR_ERR(); - + if(args) { efree(args); + } return retval; } diff --git a/ext/pdo/tests/bug_44173.phpt b/ext/pdo/tests/bug_44173.phpt index f13abaa5d500a..3d310e0cd5016 100644 --- a/ext/pdo/tests/bug_44173.phpt +++ b/ext/pdo/tests/bug_44173.phpt @@ -61,7 +61,7 @@ bool(false) Warning: PDO::query(): SQLSTATE[HY000]: General error: fetch mode doesn't allow any extra arguments in %s bool(false) -Warning: PDO::query(): SQLSTATE[HY000]: General error: mode must be an integer in %s +Warning: PDO::query() expects parameter 2 to be long, string given in %s bool(false) Warning: PDO::query(): SQLSTATE[HY000]: General error: too many arguments in %s diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index bd9a3f6f11b6a..4cf129afd5ee0 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -92,6 +92,17 @@ #define PQfreemem free #endif +#define PGSQL_GET_LINK(pgsql_link) \ + if ((pgsql_link) == NULL) { \ + id = PGG(default_link); \ + CHECK_DEFAULT_LINK(id); \ + } \ + if ((pgsql_link) == NULL && id == -1) { \ + RETURN_FALSE; \ + } \ + ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &(pgsql_link), id, "PostgreSQL link", le_link, le_plink); + + ZEND_DECLARE_MODULE_GLOBALS(pgsql) static PHP_GINIT_FUNCTION(pgsql); @@ -1243,7 +1254,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) PGresult *pg_result; if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 5 - || zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { + || zend_get_parameters_array_nodefault(ZEND_NUM_ARGS(), args) == FAILURE) { WRONG_PARAM_COUNT; } @@ -1476,14 +1487,14 @@ PHP_FUNCTION(pg_pconnect) PHP_FUNCTION(pg_close) { zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int id = -1; PGconn *pgsql; - if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { return; } - if (argc == 0) { + if (ZEND_NUM_ARGS() == 0) { id = PGG(default_link); CHECK_DEFAULT_LINK(id); } @@ -1523,15 +1534,15 @@ PHP_FUNCTION(pg_close) static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) { zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int id = -1; PGconn *pgsql; char *msgbuf; - if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { return; } - if (argc == 0) { + if (ZEND_NUM_ARGS() == 0) { id = PGG(default_link); CHECK_DEFAULT_LINK(id); } @@ -1755,19 +1766,13 @@ PHP_FUNCTION(pg_query) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query, &query_len) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &query, &query_len) == FAILURE) { return; } } - if (pgsql_link == NULL && id == -1) { - RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (PQ_SETNONBLOCKING(pgsql, 0)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode"); @@ -1857,19 +1862,13 @@ PHP_FUNCTION(pg_query_params) if (zend_parse_parameters(argc TSRMLS_CC, "sa", &query, &query_len, &pv_param_arr) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else { if (zend_parse_parameters(argc TSRMLS_CC, "rsa", &pgsql_link, &query, &query_len, &pv_param_arr) == FAILURE) { return; } } - if (pgsql_link == NULL && id == -1) { - RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (PQ_SETNONBLOCKING(pgsql, 0)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode"); @@ -1978,8 +1977,6 @@ PHP_FUNCTION(pg_prepare) if (zend_parse_parameters(argc TSRMLS_CC, "ss", &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else { if (zend_parse_parameters(argc TSRMLS_CC, "rss", &pgsql_link, &stmtname, &stmtname_len, &query, &query_len) == FAILURE) { return; @@ -2064,19 +2061,13 @@ PHP_FUNCTION(pg_execute) if (zend_parse_parameters(argc TSRMLS_CC, "sa/", &stmtname, &stmtname_len, &pv_param_arr)==FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else { if (zend_parse_parameters(argc TSRMLS_CC, "rsa/", &pgsql_link, &stmtname, &stmtname_len, &pv_param_arr) == FAILURE) { return; } } - if (pgsql_link == NULL && id == -1) { - RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (PQ_SETNONBLOCKING(pgsql, 0)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE,"Cannot set connection to blocking mode"); @@ -2639,7 +2630,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, RETURN_FALSE; } } - use_row = ZEND_NUM_ARGS() > 1 && row != -1; + use_row = zrow != NULL && row != -1; if (!(result_type & PGSQL_BOTH)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type"); @@ -3038,10 +3029,11 @@ PHP_FUNCTION(pg_last_oid) Enable tracing a PostgreSQL connection */ PHP_FUNCTION(pg_trace) { + int argc = ZEND_NUM_ARGS(); char *z_filename, *mode = "w"; int z_filename_len, mode_len; zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int id = -1; PGconn *pgsql; FILE *fp = NULL; php_stream *stream; @@ -3082,13 +3074,14 @@ PHP_FUNCTION(pg_trace) PHP_FUNCTION(pg_untrace) { zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int id = -1; PGconn *pgsql; - if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { return; } +<<<<<<< HEAD if (argc == 0) { id = PGG(default_link); CHECK_DEFAULT_LINK(id); @@ -3097,8 +3090,10 @@ PHP_FUNCTION(pg_untrace) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; } +======= + PGSQL_GET_LINK(pgsql_link); +>>>>>>> Cherry pick 7682dfc by stas - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); PQuntrace(pgsql); RETURN_TRUE; } @@ -3108,29 +3103,28 @@ PHP_FUNCTION(pg_untrace) Create a large object */ PHP_FUNCTION(pg_lo_create) { +<<<<<<< HEAD zval *pgsql_link = NULL, *oid = NULL; PGconn *pgsql; Oid pgsql_oid, wanted_oid = InvalidOid; int id = -1, argc = ZEND_NUM_ARGS(); - - if (zend_parse_parameters(argc TSRMLS_CC, "|zz", &pgsql_link, &oid) == FAILURE) { +======= + zval *pgsql_link = NULL, *oid = NULL; + PGconn *pgsql; + Oid pgsql_oid, wanted_oid = InvalidOid; + int id = -1; +>>>>>>> Cherry pick 7682dfc by stas + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &pgsql_link, &oid) == FAILURE) { return; } - if ((argc == 1) && (Z_TYPE_P(pgsql_link) != IS_RESOURCE)) { + if ((oid == NULL) && (Z_TYPE_P(pgsql_link) != IS_RESOURCE)) { oid = pgsql_link; pgsql_link = NULL; } - if (pgsql_link == NULL) { - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); - if (id == -1) { - RETURN_FALSE; - } - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (oid) { #ifndef HAVE_PG_LO_CREATE @@ -3216,8 +3210,6 @@ PHP_FUNCTION(pg_lo_unlink) php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed"); RETURN_FALSE; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "l", &oid_long) == SUCCESS) { @@ -3226,18 +3218,19 @@ PHP_FUNCTION(pg_lo_unlink) RETURN_FALSE; } oid = (Oid)oid_long; - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires 1 or 2 arguments"); RETURN_FALSE; } +<<<<<<< HEAD if (pgsql_link == NULL && id == -1) { RETURN_FALSE; } +======= +>>>>>>> Cherry pick 7682dfc by stas - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (lo_unlink(pgsql, oid) == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to delete PostgreSQL large object %u", oid); @@ -3288,8 +3281,6 @@ PHP_FUNCTION(pg_lo_open) php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed"); RETURN_FALSE; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "ls", &oid_long, &mode_string, &mode_strlen) == SUCCESS) { @@ -3298,18 +3289,19 @@ PHP_FUNCTION(pg_lo_open) RETURN_FALSE; } oid = (Oid)oid_long; - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires 1 or 2 arguments"); RETURN_FALSE; } +<<<<<<< HEAD if (pgsql_link == NULL && id == -1) { RETURN_FALSE; } +======= +>>>>>>> Cherry pick 7682dfc by stas - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); /* r/w/+ is little bit more PHP-like than INV_READ/INV_WRITE and a lot of faster to type. Unfortunately, doesn't behave the same way as fopen()... @@ -3399,21 +3391,25 @@ PHP_FUNCTION(pg_lo_close) Read a large object */ PHP_FUNCTION(pg_lo_read) { +<<<<<<< HEAD zval *pgsql_id; long len; int buf_len = PGSQL_LO_READ_BUF_SIZE, nbytes, argc = ZEND_NUM_ARGS(); +======= + zval *pgsql_id; + long len = PGSQL_LO_READ_BUF_SIZE; + int buf_len = PGSQL_LO_READ_BUF_SIZE, nbytes; +>>>>>>> Cherry pick 7682dfc by stas char *buf; pgLofp *pgsql; - if (zend_parse_parameters(argc TSRMLS_CC, "r|l", &pgsql_id, &len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &pgsql_id, &len) == FAILURE) { return; } ZEND_FETCH_RESOURCE(pgsql, pgLofp *, &pgsql_id, -1, "PostgreSQL large object", le_lofp); - if (argc > 1) { buf_len = len; - } buf = (char *) safe_emalloc(sizeof(char), (buf_len+1), 0); if ((nbytes = lo_read((PGconn *)pgsql->conn, pgsql->lofd, buf, buf_len))<0) { @@ -3438,7 +3434,7 @@ PHP_FUNCTION(pg_lo_write) pgLofp *pgsql; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rs|l", &pgsql_id, &str, &str_len, &z_len) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, argc TSRMLS_CC, "rs|l", &pgsql_id, &str, &str_len, &z_len) == FAILURE) { return; } @@ -3509,8 +3505,6 @@ PHP_FUNCTION(pg_lo_import) } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "p|z", &file_in, &name_len, &oid) == SUCCESS) { - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } /* old calling convention, deprecated since PHP 4.2 */ else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, @@ -3525,11 +3519,15 @@ PHP_FUNCTION(pg_lo_import) RETURN_FALSE; } +<<<<<<< HEAD if (pgsql_link == NULL && id == -1) { RETURN_FALSE; } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); +======= + PGSQL_GET_LINK(pgsql_link); +>>>>>>> Cherry pick 7682dfc by stas if (oid) { #ifndef HAVE_PG_LO_IMPORT_WITH_OID @@ -3617,8 +3615,6 @@ PHP_FUNCTION(pg_lo_export) RETURN_FALSE; } oid = (Oid)oid_long; - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "sp", &oid_string, &oid_strlen, &file_out, &name_len) == SUCCESS) { @@ -3628,8 +3624,6 @@ PHP_FUNCTION(pg_lo_export) php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong OID value passed"); RETURN_FALSE; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "spr", &oid_string, &oid_strlen, &file_out, &name_len, &pgsql_link) == SUCCESS) { @@ -3654,16 +3648,12 @@ PHP_FUNCTION(pg_lo_export) RETURN_FALSE; } - if (php_check_open_basedir(file_out TSRMLS_CC)) { - RETURN_FALSE; - } + PGSQL_GET_LINK(pgsql_link); - if (pgsql_link == NULL && id == -1) { + if (php_check_open_basedir(file_out TSRMLS_CC)) { RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - if (lo_export(pgsql, oid, file_out)) { RETURN_TRUE; } @@ -3678,9 +3668,8 @@ PHP_FUNCTION(pg_lo_seek) zval *pgsql_id = NULL; long result, offset = 0, whence = SEEK_CUR; pgLofp *pgsql; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rl|l", &pgsql_id, &offset, &whence) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &pgsql_id, &offset, &whence) == FAILURE) { return; } if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) { @@ -3714,9 +3703,8 @@ PHP_FUNCTION(pg_lo_tell) zval *pgsql_id = NULL; long offset = 0; pgLofp *pgsql; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "r", &pgsql_id) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_id) == FAILURE) { return; } @@ -3784,19 +3772,13 @@ PHP_FUNCTION(pg_set_error_verbosity) if (zend_parse_parameters(argc TSRMLS_CC, "l", &verbosity) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else { if (zend_parse_parameters(argc TSRMLS_CC, "rl", &pgsql_link, &verbosity) == FAILURE) { return; } } - if (pgsql_link == NULL && id == -1) { - RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (verbosity & (PQERRORS_TERSE|PQERRORS_DEFAULT|PQERRORS_VERBOSE)) { Z_LVAL_P(return_value) = PQsetErrorVerbosity(pgsql, verbosity); @@ -3823,19 +3805,21 @@ PHP_FUNCTION(pg_set_client_encoding) if (zend_parse_parameters(argc TSRMLS_CC, "s", &encoding, &encoding_len) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else { if (zend_parse_parameters(argc TSRMLS_CC, "rs", &pgsql_link, &encoding, &encoding_len) == FAILURE) { return; } } +<<<<<<< HEAD if (pgsql_link == NULL && id == -1) { RETURN_FALSE; } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); +======= + PGSQL_GET_LINK(pgsql_link); +>>>>>>> Cherry pick 7682dfc by stas Z_LVAL_P(return_value) = PQsetClientEncoding(pgsql, encoding); Z_TYPE_P(return_value) = IS_LONG; @@ -3847,23 +3831,14 @@ PHP_FUNCTION(pg_set_client_encoding) PHP_FUNCTION(pg_client_encoding) { zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int id = -1; PGconn *pgsql; - if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { return; } - if (argc == 0) { - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); - } - - if (pgsql_link == NULL && id == -1) { - RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); /* Just do the same as found in PostgreSQL sources... */ @@ -3884,14 +3859,15 @@ PHP_FUNCTION(pg_client_encoding) PHP_FUNCTION(pg_end_copy) { zval *pgsql_link = NULL; - int id = -1, argc = ZEND_NUM_ARGS(); + int id = -1; PGconn *pgsql; int result = 0; - if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { return; } +<<<<<<< HEAD if (argc == 0) { id = PGG(default_link); CHECK_DEFAULT_LINK(id); @@ -3902,6 +3878,9 @@ PHP_FUNCTION(pg_end_copy) } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); +======= + PGSQL_GET_LINK(pgsql_link); +>>>>>>> Cherry pick 7682dfc by stas result = PQendcopy(pgsql); @@ -3928,19 +3907,13 @@ PHP_FUNCTION(pg_put_line) if (zend_parse_parameters(argc TSRMLS_CC, "s", &query, &query_len) == FAILURE) { return; } - id = PGG(default_link); - CHECK_DEFAULT_LINK(id); } else { if (zend_parse_parameters(argc TSRMLS_CC, "rs", &pgsql_link, &query, &query_len) == FAILURE) { return; } } - if (pgsql_link == NULL && id == -1) { - RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); result = PQputline(pgsql, query); if (result==EOF) { @@ -3969,9 +3942,8 @@ PHP_FUNCTION(pg_copy_to) #endif char *csv = (char *)NULL; int ret; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rs|ss", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|ss", &pgsql_link, &table_name, &table_name_len, &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len) == FAILURE) { return; @@ -3980,7 +3952,7 @@ PHP_FUNCTION(pg_copy_to) pg_delim = "\t"; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (!pg_null_as) { pg_null_as = safe_estrdup("\\\\N"); @@ -4102,9 +4074,8 @@ PHP_FUNCTION(pg_copy_from) PGconn *pgsql; PGresult *pgsql_result; ExecStatusType status; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|ss", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|ss", &pgsql_link, &table_name, &table_name_len, &pg_rows, &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len) == FAILURE) { return; @@ -4117,7 +4088,7 @@ PHP_FUNCTION(pg_copy_from) pg_null_as_free = 1; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); spprintf(&query, 0, "COPY %s FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, *pg_delim, pg_null_as); while ((pgsql_result = PQgetResult(pgsql))) { @@ -4444,8 +4415,6 @@ static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_l if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &from, &from_len) == FAILURE) { return; } - pgsql_link = NULL; - id = PGG(default_link); break; default: @@ -4455,12 +4424,8 @@ static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_l break; } - if (pgsql_link == NULL && id == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot get default pgsql link"); - RETURN_FALSE; - } + PGSQL_GET_LINK(pgsql_link); - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); if (pgsql == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot get pgsql link"); RETURN_FALSE; @@ -4584,7 +4549,7 @@ PHP_FUNCTION(pg_connection_status) RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); RETURN_LONG(PQstatus(pgsql)); } @@ -4606,7 +4571,7 @@ PHP_FUNCTION(pg_transaction_status) RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); RETURN_LONG(PQtransactionStatus(pgsql)); } @@ -4619,7 +4584,7 @@ PHP_FUNCTION(pg_transaction_status) Reset connection (reconnect) */ PHP_FUNCTION(pg_connection_reset) { - zval *pgsql_link; + zval *pgsql_link = NULL; int id = -1; PGconn *pgsql; @@ -4628,7 +4593,7 @@ PHP_FUNCTION(pg_connection_reset) RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); PQreset(pgsql); if (PQstatus(pgsql) == CONNECTION_BAD) { @@ -4668,7 +4633,7 @@ static int php_pgsql_flush_query(PGconn *pgsql TSRMLS_DC) */ static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) { - zval *pgsql_link; + zval *pgsql_link = NULL; int id = -1; PGconn *pgsql; PGresult *pgsql_result; @@ -4678,7 +4643,7 @@ static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (PQ_SETNONBLOCKING(pgsql, 1)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); @@ -4728,7 +4693,7 @@ PHP_FUNCTION(pg_connection_busy) Send asynchronous query */ PHP_FUNCTION(pg_send_query) { - zval *pgsql_link; + zval *pgsql_link = NULL; char *query; int len; int id = -1; @@ -4742,7 +4707,7 @@ PHP_FUNCTION(pg_send_query) return; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (PQ_SETNONBLOCKING(pgsql, 1)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); @@ -4783,7 +4748,7 @@ PHP_FUNCTION(pg_send_query) Send asynchronous parameterized query */ PHP_FUNCTION(pg_send_query_params) { - zval *pgsql_link, *pv_param_arr, **tmp; + zval *pgsql_link = NULL, *pv_param_arr, **tmp; int num_params = 0; char **params = NULL; char *query; @@ -4797,11 +4762,7 @@ PHP_FUNCTION(pg_send_query_params) return; } - if (pgsql_link == NULL && id == -1) { - RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (PQ_SETNONBLOCKING(pgsql, 1)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); @@ -4879,7 +4840,7 @@ PHP_FUNCTION(pg_send_query_params) Asynchronously prepare a query for future execution */ PHP_FUNCTION(pg_send_prepare) { - zval *pgsql_link; + zval *pgsql_link = NULL; char *query, *stmtname; int stmtname_len, query_len, id = -1; PGconn *pgsql; @@ -4891,11 +4852,15 @@ PHP_FUNCTION(pg_send_prepare) return; } +<<<<<<< HEAD if (pgsql_link == NULL && id == -1) { RETURN_FALSE; } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); +======= + PGSQL_GET_LINK(pgsql_link); +>>>>>>> Cherry pick 7682dfc by stas if (PQ_SETNONBLOCKING(pgsql, 1)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); @@ -4937,7 +4902,7 @@ PHP_FUNCTION(pg_send_prepare) Executes prevriously prepared stmtname asynchronously */ PHP_FUNCTION(pg_send_execute) { - zval *pgsql_link; + zval *pgsql_link = NULL; zval *pv_param_arr, **tmp; int num_params = 0; char **params = NULL; @@ -4952,11 +4917,7 @@ PHP_FUNCTION(pg_send_execute) return; } - if (pgsql_link == NULL && id == -1) { - RETURN_FALSE; - } - - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (PQ_SETNONBLOCKING(pgsql, 1)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode"); @@ -5033,7 +4994,7 @@ PHP_FUNCTION(pg_send_execute) Get asynchronous query result */ PHP_FUNCTION(pg_get_result) { - zval *pgsql_link; + zval *pgsql_link = NULL; int id = -1; PGconn *pgsql; PGresult *pgsql_result; @@ -5043,7 +5004,7 @@ PHP_FUNCTION(pg_get_result) RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); pgsql_result = PQgetResult(pgsql); if (!pgsql_result) { @@ -5095,7 +5056,7 @@ PHP_FUNCTION(pg_result_status) Get asynchronous notification */ PHP_FUNCTION(pg_get_notify) { - zval *pgsql_link; + zval *pgsql_link = NULL; int id = -1; long result_type = PGSQL_ASSOC; PGconn *pgsql; @@ -5106,7 +5067,7 @@ PHP_FUNCTION(pg_get_notify) RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); if (!(result_type & PGSQL_BOTH)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type"); @@ -5154,7 +5115,7 @@ PHP_FUNCTION(pg_get_notify) Get backend(server) pid */ PHP_FUNCTION(pg_get_pid) { - zval *pgsql_link; + zval *pgsql_link = NULL; int id = -1; PGconn *pgsql; @@ -5163,7 +5124,7 @@ PHP_FUNCTION(pg_get_pid) RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); RETURN_LONG(PQbackendPID(pgsql)); } @@ -5285,7 +5246,7 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z Get meta_data */ PHP_FUNCTION(pg_meta_data) { - zval *pgsql_link; + zval *pgsql_link = NULL; char *table_name; uint table_name_len; zend_bool extended=0; @@ -5297,8 +5258,13 @@ PHP_FUNCTION(pg_meta_data) return; } +<<<<<<< HEAD ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); +======= + PGSQL_GET_LINK(pgsql_link); + +>>>>>>> Cherry pick 7682dfc by stas array_init(return_value); if (php_pgsql_meta_data(pgsql, table_name, return_value, extended TSRMLS_CC) == FAILURE) { zval_dtor(return_value); /* destroy array */ @@ -6367,17 +6333,23 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var Insert values (filed=>value) to table */ PHP_FUNCTION(pg_insert) { - zval *pgsql_link, *values; + zval *pgsql_link = NULL, *values; char *table, *sql = NULL; int table_len; +<<<<<<< HEAD ulong option = PGSQL_DML_EXEC, return_sql; PGconn *pg_link; PGresult *pg_result; ExecStatusType status; pgsql_result_handle *pgsql_handle; int id = -1, argc = ZEND_NUM_ARGS(); +======= + ulong option = PGSQL_DML_EXEC; + PGconn *pgsql; + int id = -1; +>>>>>>> Cherry pick 7682dfc by stas - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|l", &pgsql_link, &table, &table_len, &values, &option) == FAILURE) { return; } @@ -6386,11 +6358,12 @@ PHP_FUNCTION(pg_insert) RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); - if (php_pgsql_flush_query(pg_link TSRMLS_CC)) { + if (php_pgsql_flush_query(pgsql TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection"); } +<<<<<<< HEAD return_sql = option & PGSQL_DML_STRING; if (option & PGSQL_DML_EXEC) { /* return resource when executed */ @@ -6437,6 +6410,9 @@ PHP_FUNCTION(pg_insert) break; } } else if (php_pgsql_insert(pg_link, table, values, option, &sql TSRMLS_CC) == FAILURE) { +======= + if (php_pgsql_insert(pgsql, table, values, option, &sql TSRMLS_CC) == FAILURE) { +>>>>>>> Cherry pick 7682dfc by stas RETURN_FALSE; } if (return_sql) { @@ -6593,10 +6569,10 @@ PHP_FUNCTION(pg_update) char *table, *sql = NULL; int table_len; ulong option = PGSQL_DML_EXEC; - PGconn *pg_link; - int id = -1, argc = ZEND_NUM_ARGS(); + PGconn *pgsql; + int id = -1; - if (zend_parse_parameters(argc TSRMLS_CC, "rsaa|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsaa|l", &pgsql_link, &table, &table_len, &values, &ids, &option) == FAILURE) { return; } @@ -6605,12 +6581,12 @@ PHP_FUNCTION(pg_update) RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); - if (php_pgsql_flush_query(pg_link TSRMLS_CC)) { + if (php_pgsql_flush_query(pgsql TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection"); } - if (php_pgsql_update(pg_link, table, values, ids, option, &sql TSRMLS_CC) == FAILURE) { + if (php_pgsql_update(pgsql, table, values, ids, option, &sql TSRMLS_CC) == FAILURE) { RETURN_FALSE; } if (option & PGSQL_DML_STRING) { @@ -6685,10 +6661,10 @@ PHP_FUNCTION(pg_delete) char *table, *sql = NULL; int table_len; ulong option = PGSQL_DML_EXEC; - PGconn *pg_link; - int id = -1, argc = ZEND_NUM_ARGS(); + PGconn *pgsql; + int id = -1; - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|l", &pgsql_link, &table, &table_len, &ids, &option) == FAILURE) { return; } @@ -6696,13 +6672,12 @@ PHP_FUNCTION(pg_delete) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option is specified"); RETURN_FALSE; } + PGSQL_GET_LINK(pgsql_link); - ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - - if (php_pgsql_flush_query(pg_link TSRMLS_CC)) { + if (php_pgsql_flush_query(pgsql TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection"); } - if (php_pgsql_delete(pg_link, table, ids, option, &sql TSRMLS_CC) == FAILURE) { + if (php_pgsql_delete(pgsql, table, ids, option, &sql TSRMLS_CC) == FAILURE) { RETURN_FALSE; } if (option & PGSQL_DML_STRING) { @@ -6823,10 +6798,10 @@ PHP_FUNCTION(pg_select) char *table, *sql = NULL; int table_len; ulong option = PGSQL_DML_EXEC; - PGconn *pg_link; - int id = -1, argc = ZEND_NUM_ARGS(); + PGconn *pgsql; + int id = -1; - if (zend_parse_parameters(argc TSRMLS_CC, "rsa|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|l", &pgsql_link, &table, &table_len, &ids, &option) == FAILURE) { return; } @@ -6835,13 +6810,13 @@ PHP_FUNCTION(pg_select) RETURN_FALSE; } - ZEND_FETCH_RESOURCE2(pg_link, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); + PGSQL_GET_LINK(pgsql_link); - if (php_pgsql_flush_query(pg_link TSRMLS_CC)) { + if (php_pgsql_flush_query(pgsql TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected unhandled result(s) in connection"); } array_init(return_value); - if (php_pgsql_select(pg_link, table, ids, return_value, option, &sql TSRMLS_CC) == FAILURE) { + if (php_pgsql_select(pgsql, table, ids, return_value, option, &sql TSRMLS_CC) == FAILURE) { zval_dtor(return_value); RETURN_FALSE; } diff --git a/ext/pspell/pspell.c b/ext/pspell/pspell.c index 85199d621dff7..ac1cc58a80acc 100644 --- a/ext/pspell/pspell.c +++ b/ext/pspell/pspell.c @@ -262,7 +262,6 @@ static PHP_FUNCTION(pspell_new) char *language, *spelling = NULL, *jargon = NULL, *encoding = NULL; int language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0; long mode = 0L, speed = 0L; - int argc = ZEND_NUM_ARGS(); int ind; #ifdef PHP_WIN32 @@ -277,7 +276,7 @@ static PHP_FUNCTION(pspell_new) PspellManager *manager; PspellConfig *config; - if (zend_parse_parameters(argc TSRMLS_CC, "s|sssl", &language, &language_len, &spelling, &spelling_len, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sssl", &language, &language_len, &spelling, &spelling_len, &jargon, &jargon_len, &encoding, &encoding_len, &mode) == FAILURE) { return; } @@ -319,7 +318,7 @@ static PHP_FUNCTION(pspell_new) pspell_config_replace(config, "encoding", encoding); } - if (argc > 4) { + if (mode) { speed = mode & PSPELL_SPEED_MASK_INTERNAL; /* First check what mode we want (how many suggestions) */ @@ -359,7 +358,6 @@ static PHP_FUNCTION(pspell_new_personal) char *personal, *language, *spelling = NULL, *jargon = NULL, *encoding = NULL; int personal_len, language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0; long mode = 0L, speed = 0L; - int argc = ZEND_NUM_ARGS(); int ind; #ifdef PHP_WIN32 @@ -374,7 +372,7 @@ static PHP_FUNCTION(pspell_new_personal) PspellManager *manager; PspellConfig *config; - if (zend_parse_parameters(argc TSRMLS_CC, "ps|sssl", &personal, &personal_len, &language, &language_len, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ps|sssl", &personal, &personal_len, &language, &language_len, &spelling, &spelling_len, &jargon, &jargon_len, &encoding, &encoding_len, &mode) == FAILURE) { return; } @@ -424,7 +422,7 @@ static PHP_FUNCTION(pspell_new_personal) pspell_config_replace(config, "encoding", encoding); } - if (argc > 5) { + if (mode) { speed = mode & PSPELL_SPEED_MASK_INTERNAL; /* First check what mode we want (how many suggestions) */ diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index a24153dc2078c..aae8499e97f8a 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -3793,18 +3793,14 @@ ZEND_METHOD(reflection_class, getMethods) { reflection_object *intern; zend_class_entry *ce; - long filter = 0; + /* If no parameters given, default to "return all" */ + long filter = ZEND_ACC_PPP_MASK | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL | ZEND_ACC_STATIC; int argc = ZEND_NUM_ARGS(); METHOD_NOTSTATIC(reflection_class_ptr); - if (argc) { if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) { return; } - } else { - /* No parameters given, default to "return all" */ - filter = ZEND_ACC_PPP_MASK | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL | ZEND_ACC_STATIC; - } GET_REFLECTION_OBJECT_PTR(ce); @@ -3983,18 +3979,14 @@ ZEND_METHOD(reflection_class, getProperties) { reflection_object *intern; zend_class_entry *ce; - long filter = 0; + /* If no parameters given, default to "return all" */ + long filter = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC; int argc = ZEND_NUM_ARGS(); METHOD_NOTSTATIC(reflection_class_ptr); - if (argc) { if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) { return; } - } else { - /* No parameters given, default to "return all" */ - filter = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC; - } GET_REFLECTION_OBJECT_PTR(ce); @@ -4315,7 +4307,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs) reflection_object *intern; zend_class_entry *ce, *old_scope; int argc = 0; - HashTable *args; + HashTable *args = NULL; zend_function *constructor; @@ -4325,8 +4317,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &args) == FAILURE) { return; } - - if (ZEND_NUM_ARGS() > 0) { + if (args != NULL) { argc = args->nNumOfElements; } @@ -4388,7 +4379,9 @@ ZEND_METHOD(reflection_class, newInstanceArgs) if (params) { efree(params); } - } else if (argc) { + } else if (args == NULL || !argc) { + object_init_ex(return_value, ce); + } else { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name); } } diff --git a/ext/session/session.c b/ext/session/session.c index 38aee7d6800e6..64494a728e5d2 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1910,6 +1910,12 @@ static PHP_FUNCTION(session_set_save_handler) if (zend_parse_parameters(argc TSRMLS_CC, "+", &args, &num_args) == FAILURE) { return; } + if(num_args != 6 && num_args != 7) { + if(args) { + efree(args); + } + WRONG_PARAM_COUNT; + } /* remove shutdown function */ remove_user_shutdown_function("session_shutdown", sizeof("session_shutdown") TSRMLS_CC); @@ -2054,15 +2060,14 @@ static PHP_FUNCTION(session_cache_limiter) static PHP_FUNCTION(session_cache_expire) { zval **expires = NULL; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "|Z", &expires) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Z", &expires) == FAILURE) { return; } RETVAL_LONG(PS(cache_expire)); - if (argc == 1) { + if (expires != NULL) { convert_to_string_ex(expires); zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(expires), Z_STRLEN_PP(expires), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); } diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 363ea1fc44b0b..1bf5691687acb 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1361,18 +1361,14 @@ SXE_METHOD(asXML) xmlOutputBufferPtr outbuf; xmlChar *strval; int strval_len; - char *filename; + char *filename = NULL; int filename_len; - if (ZEND_NUM_ARGS() > 1) { - RETURN_FALSE; - } - - if (ZEND_NUM_ARGS() == 1) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|p", &filename, &filename_len) == FAILURE) { RETURN_FALSE; } + if(filename) { sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); GET_NODE(sxe, node); node = php_sxe_get_first_node(sxe, node TSRMLS_CC); diff --git a/ext/skeleton/create_stubs b/ext/skeleton/create_stubs index f9f39b1795f7e..5b030308955d6 100755 --- a/ext/skeleton/create_stubs +++ b/ext/skeleton/create_stubs @@ -195,7 +195,7 @@ END { if (maxargs[i]>0) { fetchargs = "\tif (zend_parse_parameters(" ints = ints "\tint argc = ZEND_NUM_ARGS();\n" - fetchargs = fetchargs "argc TSRMLS_CC, " specs[i] + fetchargs = fetchargs "ZEND_NUM_ARGS() TSRMLS_CC, " specs[i] } else { fetchargs = fetchargs "\tif (zend_parse_parameters_none() == FAILURE) {\n\t\treturn;\n\t}" xmlparams = xmlparams " \n" diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index 4dd4badcd2cd6..2adc7f44afd58 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -1816,13 +1816,12 @@ PHP_METHOD(snmp, __construct) long timeout = SNMP_DEFAULT_TIMEOUT; long retries = SNMP_DEFAULT_RETRIES; long version = SNMP_DEFAULT_VERSION; - int argc = ZEND_NUM_ARGS(); zend_error_handling error_handling; snmp_object = (php_snmp_object *)zend_object_store_get_object(object TSRMLS_CC); zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); - if (zend_parse_parameters(argc TSRMLS_CC, "lss|ll", &version, &a1, &a1_len, &a2, &a2_len, &timeout, &retries) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lss|ll", &version, &a1, &a1_len, &a2, &a2_len, &timeout, &retries) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } @@ -1915,11 +1914,10 @@ PHP_METHOD(snmp, setSecurity) zval *object = getThis(); char *a1 = "", *a2 = "", *a3 = "", *a4 = "", *a5 = "", *a6 = "", *a7 = ""; int a1_len = 0, a2_len = 0, a3_len = 0, a4_len = 0, a5_len = 0, a6_len = 0, a7_len = 0; - int argc = ZEND_NUM_ARGS(); snmp_object = (php_snmp_object *)zend_object_store_get_object(object TSRMLS_CC); - if (zend_parse_parameters(argc TSRMLS_CC, "s|ssssss", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ssssss", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, &a4, &a4_len, &a5, &a5_len, &a6, &a6_len, &a7, &a7_len) == FAILURE) { RETURN_FALSE; } diff --git a/ext/soap/soap.c b/ext/soap/soap.c index a8c6cb936995b..5069cbfc4bf76 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -1559,8 +1559,15 @@ PHP_METHOD(SoapServer, handle) php_error_docref(NULL TSRMLS_CC, E_ERROR,"ob_start failed"); } +<<<<<<< HEAD if (ZEND_NUM_ARGS() == 0) { if (SG(request_info).request_body && 0 == php_stream_rewind(SG(request_info).request_body)) { +======= + if (arg == NULL) { + if (SG(request_info).raw_post_data) { + char *post_data = SG(request_info).raw_post_data; + int post_data_length = SG(request_info).raw_post_data_length; +>>>>>>> Cherry pick 7682dfc by stas zval **server_vars, **encoding; php_stream_filter *zf = NULL; diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index bd0a8f2f70d2d..6698b1d0a7dd9 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -1087,7 +1087,7 @@ PHP_FUNCTION(socket_write) zval *arg1; php_socket *php_sock; int retval, str_len; - long length = 0; + long length = LONG_MAX; char *str; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &arg1, &str, &str_len, &length) == FAILURE) { @@ -1096,14 +1096,14 @@ PHP_FUNCTION(socket_write) ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket); - if (ZEND_NUM_ARGS() < 3) { + if (length > str_len) { length = str_len; } #ifndef PHP_WIN32 - retval = write(php_sock->bsd_socket, str, MIN(length, str_len)); + retval = write(php_sock->bsd_socket, str, length); #else - retval = send(php_sock->bsd_socket, str, min(length, str_len), 0); + retval = send(php_sock->bsd_socket, str, length, 0); #endif if (retval < 0) { @@ -1382,7 +1382,7 @@ PHP_FUNCTION(socket_connect) long port = 0; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rs|l", &arg1, &addr, &addr_len, &port) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, argc TSRMLS_CC, "rs|l", &arg1, &addr, &addr_len, &port) == FAILURE) { return; } @@ -1766,7 +1766,7 @@ PHP_FUNCTION(socket_sendto) char *buf, *addr; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rslls|l", &arg1, &buf, &buf_len, &len, &flags, &addr, &addr_len, &port) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, argc TSRMLS_CC, "rslls|l", &arg1, &buf, &buf_len, &len, &flags, &addr, &addr_len, &port) == FAILURE) { return; } diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index 5927e05562885..45a240e3dfced 100644 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -480,7 +480,7 @@ PHP_FUNCTION(spl_autoload_register) return; } - if (ZEND_NUM_ARGS()) { + if (zcallable != NULL) { if (Z_TYPE_P(zcallable) == IS_STRING) { if (Z_STRLEN_P(zcallable) == sizeof("spl_autoload_call") - 1) { if (!zend_binary_strcasecmp(Z_STRVAL_P(zcallable), sizeof("spl_autoload_call"), "spl_autoload_call", sizeof("spl_autoload_call"))) { diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index f41d0fb9cd9a2..fea45c9cd85c6 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1191,12 +1191,12 @@ SPL_METHOD(Array, __construct) intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|lC", &array, &ar_flags, &ce_get_iterator) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|lC!", &array, &ar_flags, &ce_get_iterator) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } - if (ZEND_NUM_ARGS() > 2) { + if (ce_get_iterator != NULL && ce_get_iterator != spl_ce_Iterator) { intern->ce_get_iterator = ce_get_iterator; } @@ -1456,7 +1456,7 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, arg? 2 : 1, tmp, arg TSRMLS_CC); aht->nApplyCount--; } else { - if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) { + if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE || !arg) { Z_TYPE_P(tmp) = IS_NULL; zval_ptr_dtor(&tmp); zend_throw_exception(spl_ce_BadMethodCallException, "Function expects exactly one argument", 0 TSRMLS_CC); diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 5f32feaaf078e..64ce3557f6002 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -2582,36 +2582,35 @@ SPL_METHOD(SplFileObject, fgetcsv) char *delim = NULL, *enclo = NULL, *esc = NULL; int d_len = 0, e_len = 0, esc_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) { - switch(ZEND_NUM_ARGS()) - { - case 3: + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == FAILURE) { + return; + } + + if(esc) { if (esc_len != 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be a character"); RETURN_FALSE; } escape = esc[0]; - /* no break */ - case 2: + } + + if(enclo) { if (e_len != 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character"); RETURN_FALSE; } enclosure = enclo[0]; - /* no break */ - case 1: + } + + if(delim) { if (d_len != 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character"); RETURN_FALSE; } delimiter = delim[0]; - /* no break */ - case 0: - break; } spl_filesystem_file_read_csv(intern, delimiter, enclosure, escape, return_value TSRMLS_CC); } -} /* }}} */ /* {{{ proto int SplFileObject::fputcsv(array fields, [string delimiter [, string enclosure]]) @@ -2624,31 +2623,28 @@ SPL_METHOD(SplFileObject, fputcsv) int d_len = 0, e_len = 0, ret; zval *fields = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|ss", &fields, &delim, &d_len, &enclo, &e_len) == SUCCESS) { - switch(ZEND_NUM_ARGS()) - { - case 3: + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|ss", &fields, &delim, &d_len, &enclo, &e_len) == FAILURE) { + return; + } + + if(enclo) { if (e_len != 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character"); RETURN_FALSE; } enclosure = enclo[0]; - /* no break */ - case 2: + } + + if(delim) { if (d_len != 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character"); RETURN_FALSE; } delimiter = delim[0]; - /* no break */ - case 1: - case 0: - break; } ret = php_fputcsv(intern->u.file.stream, fields, delimiter, enclosure, escape TSRMLS_CC); RETURN_LONG(ret); } -} /* }}} */ /* {{{ proto void SplFileObject::setCsvControl([string delimiter = ',' [, string enclosure = '"' [, string escape = '\\']]]) @@ -2660,38 +2656,37 @@ SPL_METHOD(SplFileObject, setCsvControl) char *delim = NULL, *enclo = NULL, *esc = NULL; int d_len = 0, e_len = 0, esc_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) { - switch(ZEND_NUM_ARGS()) - { - case 3: + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == FAILURE) { + return; + } + if(esc) { if (esc_len != 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be a character"); RETURN_FALSE; } escape = esc[0]; - /* no break */ - case 2: + } + + if(enclo) { if (e_len != 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character"); RETURN_FALSE; } enclosure = enclo[0]; - /* no break */ - case 1: + } + + if(delim) { if (d_len != 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character"); RETURN_FALSE; } delimiter = delim[0]; - /* no break */ - case 0: - break; } + intern->u.file.delimiter = delimiter; intern->u.file.enclosure = enclosure; intern->u.file.escape = escape; } -} /* }}} */ /* {{{ proto array SplFileObject::getCsvControl() @@ -2832,20 +2827,23 @@ SPL_METHOD(SplFileObject, fwrite) spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); char *str; int str_len; - long length = 0; + long length = LONG_MAX; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &length) == FAILURE) { return; } - if (ZEND_NUM_ARGS() > 1) { - str_len = MAX(0, MIN(length, str_len)); + if(length > str_len) { + length = str_len; + } + if(length < 0) { + length = 0; } - if (!str_len) { + if (!length) { RETURN_LONG(0); } - RETURN_LONG(php_stream_write(intern->u.file.stream, str, str_len)); + RETURN_LONG(php_stream_write(intern->u.file.stream, str, length)); } /* }}} */ /* {{{ proto bool SplFileObject::fstat() diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index a89fd548c5789..547982a3d8d22 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -1432,7 +1432,7 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z } ce = Z_OBJCE_P(zobject); if (!instanceof_function(ce, zend_ce_iterator TSRMLS_CC)) { - if (ZEND_NUM_ARGS() > 1) { + if (class_name != NULL) { if (zend_lookup_class(class_name, class_name_len, &pce_cast TSRMLS_CC) == FAILURE || !instanceof_function(ce, *pce_cast TSRMLS_CC) || !(*pce_cast)->get_iterator diff --git a/ext/standard/array.c b/ext/standard/array.c index b108d077c7116..370c5f1d0619d 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1497,10 +1497,10 @@ PHP_FUNCTION(compact) if (ZEND_NUM_ARGS() == 1 && Z_TYPE_PP(args[0]) == IS_ARRAY) { array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_PP(args[0]))); } else { - array_init_size(return_value, ZEND_NUM_ARGS()); + array_init_size(return_value, num_args); } - for (i=0; i 1) { if (num_req <= 0 || num_req > num_avail) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument has to be between 1 and the number of elements in the array"); return; } - } + /* Make the return value an array only if we need to pass back more than one result. */ if (num_req > 1) { @@ -4158,7 +4175,7 @@ PHP_FUNCTION(array_reduce) return; } - if (ZEND_NUM_ARGS() > 2) { + if (initial != NULL) { ALLOC_ZVAL(result); MAKE_COPY_ZVAL(&initial, result); } else { @@ -4234,7 +4251,7 @@ PHP_FUNCTION(array_filter) return; } - if (ZEND_NUM_ARGS() > 1) { + if (fci.size > 0) { have_callback = 1; fci.no_separation = 0; fci.retval_ptr_ptr = &retval; @@ -4480,7 +4497,7 @@ PHP_FUNCTION(array_key_exists) Split array into chunks */ PHP_FUNCTION(array_chunk) { - int argc = ZEND_NUM_ARGS(), key_type, num_in; + int key_type, num_in; long size, current = 0; char *str_key; uint str_key_len; @@ -4491,7 +4508,7 @@ PHP_FUNCTION(array_chunk) zval **entry; HashPosition pos; - if (zend_parse_parameters(argc TSRMLS_CC, "al|b", &input, &size, &preserve_keys) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|b", &input, &size, &preserve_keys) == FAILURE) { return; } /* Do bounds checking for size parameter. */ diff --git a/ext/standard/assert.c b/ext/standard/assert.c index a9567f3b0a7cd..6333c01d54031 100644 --- a/ext/standard/assert.c +++ b/ext/standard/assert.c @@ -266,16 +266,15 @@ PHP_FUNCTION(assert_options) zval **value = NULL; long what; int oldint; - int ac = ZEND_NUM_ARGS(); - if (zend_parse_parameters(ac TSRMLS_CC, "l|Z", &what, &value) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|Z", &what, &value) == FAILURE) { return; } switch (what) { case ASSERT_ACTIVE: oldint = ASSERTG(active); - if (ac == 2) { + if (value != NULL) { convert_to_string_ex(value); zend_alter_ini_entry_ex("assert.active", sizeof("assert.active"), Z_STRVAL_PP(value), Z_STRLEN_PP(value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC); } @@ -284,7 +283,7 @@ PHP_FUNCTION(assert_options) case ASSERT_BAIL: oldint = ASSERTG(bail); - if (ac == 2) { + if (value != NULL) { convert_to_string_ex(value); zend_alter_ini_entry_ex("assert.bail", sizeof("assert.bail"), Z_STRVAL_PP(value), Z_STRLEN_PP(value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC); } @@ -293,7 +292,7 @@ PHP_FUNCTION(assert_options) case ASSERT_QUIET_EVAL: oldint = ASSERTG(quiet_eval); - if (ac == 2) { + if (value != NULL) { convert_to_string_ex(value); zend_alter_ini_entry_ex("assert.quiet_eval", sizeof("assert.quiet_eval"), Z_STRVAL_PP(value), Z_STRLEN_PP(value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC); } @@ -302,7 +301,7 @@ PHP_FUNCTION(assert_options) case ASSERT_WARNING: oldint = ASSERTG(warning); - if (ac == 2) { + if (value != NULL) { convert_to_string_ex(value); zend_alter_ini_entry_ex("assert.warning", sizeof("assert.warning"), Z_STRVAL_PP(value), Z_STRLEN_PP(value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC); } @@ -317,7 +316,7 @@ PHP_FUNCTION(assert_options) } else { RETVAL_NULL(); } - if (ac == 2) { + if (value != NULL) { if (ASSERTG(callback)) { zval_ptr_dtor(&ASSERTG(callback)); } diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 897b1a9e49427..52c7cc9855182 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -4653,16 +4653,14 @@ PHP_FUNCTION(error_log) { char *message, *opt = NULL, *headers = NULL; int message_len, opt_len = 0, headers_len = 0; - int opt_err = 0, argc = ZEND_NUM_ARGS(); + int opt_err = 0; long erropt = 0; - if (zend_parse_parameters(argc TSRMLS_CC, "s|lps", &message, &message_len, &erropt, &opt, &opt_len, &headers, &headers_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lps", &message, &message_len, &erropt, &opt, &opt_len, &headers, &headers_len) == FAILURE) { return; } - if (argc > 1) { - opt_err = erropt; - } + opt_err = (int)erropt; if (_php_error_log_ex(opt_err, message, message_len, opt, headers TSRMLS_CC) == FAILURE) { RETURN_FALSE; @@ -4935,8 +4933,10 @@ void user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_ int i; for (i = 0; i < shutdown_function_entry->arg_count; i++) { + if(shutdown_function_entry->arguments[i]) { zval_ptr_dtor(&shutdown_function_entry->arguments[i]); } + } efree(shutdown_function_entry->arguments); } /* }}} */ @@ -4946,8 +4946,10 @@ void user_tick_function_dtor(user_tick_function_entry *tick_function_entry) /* { int i; for (i = 0; i < tick_function_entry->arg_count; i++) { + if(tick_function_entry->arguments[i]) { zval_ptr_dtor(&tick_function_entry->arguments[i]); } + } efree(tick_function_entry->arguments); } /* }}} */ @@ -5092,7 +5094,6 @@ PHP_FUNCTION(register_shutdown_function) int i; shutdown_function_entry.arg_count = ZEND_NUM_ARGS(); - if (shutdown_function_entry.arg_count < 1) { WRONG_PARAM_COUNT; } @@ -5105,7 +5106,7 @@ PHP_FUNCTION(register_shutdown_function) } /* Prevent entering of anything but valid callback (syntax check only!) */ - if (!zend_is_callable(shutdown_function_entry.arguments[0], 0, &callback_name TSRMLS_CC)) { + if (!shutdown_function_entry.arguments[0] || !zend_is_callable(shutdown_function_entry.arguments[0], 0, &callback_name TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid shutdown callback '%s' passed", callback_name); efree(shutdown_function_entry.arguments); RETVAL_FALSE; @@ -5116,8 +5117,10 @@ PHP_FUNCTION(register_shutdown_function) } for (i = 0; i < shutdown_function_entry.arg_count; i++) { + if(shutdown_function_entry.arguments[i]) { Z_ADDREF_P(shutdown_function_entry.arguments[i]); } + } zend_hash_next_index_insert(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL); } if (callback_name) { @@ -5705,7 +5708,7 @@ PHP_FUNCTION(register_tick_function) RETURN_FALSE; } - if (!zend_is_callable(tick_fe.arguments[0], 0, &function_name TSRMLS_CC)) { + if (!tick_fe.arguments[0] || !zend_is_callable(tick_fe.arguments[0], 0, &function_name TSRMLS_CC)) { efree(tick_fe.arguments); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid tick callback '%s' passed", function_name); efree(function_name); @@ -5727,8 +5730,10 @@ PHP_FUNCTION(register_tick_function) } for (i = 0; i < tick_fe.arg_count; i++) { + if(tick_fe.arguments[i]) { Z_ADDREF_P(tick_fe.arguments[i]); } + } zend_llist_add_element(BG(user_tick_functions), &tick_fe); diff --git a/ext/standard/dir.c b/ext/standard/dir.c index c64f37c2d61cd..d45b5f611352d 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -78,7 +78,7 @@ static zend_class_entry *dir_class_entry_ptr; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &id) == FAILURE) { \ return; \ } \ - if (ZEND_NUM_ARGS() == 0) { \ + if (id == NULL) { \ myself = getThis(); \ if (myself) { \ if (zend_hash_find(Z_OBJPROP_P(myself), "handle", sizeof("handle"), (void **)&tmp) == FAILURE) { \ diff --git a/ext/standard/file.c b/ext/standard/file.c index 74df6dc75923a..8bf5e75e1d7fc 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1002,11 +1002,12 @@ PHPAPI PHP_FUNCTION(feof) PHPAPI PHP_FUNCTION(fgets) { zval *arg1; - long len = 1024; + long len = LONG_MIN; char *buf = NULL; int argc = ZEND_NUM_ARGS(); size_t line_len = 0; php_stream *stream; + int alloc_buf = 1; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &arg1, &len) == FAILURE) { RETURN_FALSE; @@ -1014,28 +1015,33 @@ PHPAPI PHP_FUNCTION(fgets) PHP_STREAM_TO_ZVAL(stream, &arg1); - if (argc == 1) { - /* ask streams to give us a buffer of an appropriate size */ - buf = php_stream_get_line(stream, NULL, 0, &line_len); - if (buf == NULL) { - goto exit_failed; + if(len == LONG_MIN) { + len = 1024; + alloc_buf = 0; } - } else if (argc > 1) { + if (len <= 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0"); RETURN_FALSE; } + if(alloc_buf) { buf = ecalloc(len + 1, sizeof(char)); if (php_stream_get_line(stream, buf, len, &line_len) == NULL) { goto exit_failed; } + } else { + /* ask streams to give us a buffer of an appropriate size */ + buf = php_stream_get_line(stream, NULL, 0, &line_len); + if (buf == NULL) { + goto exit_failed; + } } ZVAL_STRINGL(return_value, buf, line_len, 0); /* resize buffer if it's much larger than the result. * Only needed if the user requested a buffer size. */ - if (argc > 1 && Z_STRLEN_P(return_value) < len / 2) { + if (alloc_buf && Z_STRLEN_P(return_value) < len / 2) { Z_STRVAL_P(return_value) = erealloc(buf, line_len + 1); } return; @@ -1081,7 +1087,7 @@ PHPAPI PHP_FUNCTION(fgetc) PHPAPI PHP_FUNCTION(fgetss) { zval *fd; - long bytes = 0; + long bytes = LONG_MIN; size_t len = 0; size_t actual_len, retval_len; char *buf = NULL, *retval; @@ -1095,7 +1101,7 @@ PHPAPI PHP_FUNCTION(fgetss) PHP_STREAM_TO_ZVAL(stream, &fd); - if (ZEND_NUM_ARGS() >= 2) { + if (bytes != LONG_MIN) { if (bytes <= 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0"); RETURN_FALSE; @@ -1177,7 +1183,7 @@ PHPAPI PHP_FUNCTION(fwrite) int arg2len; int ret; int num_bytes; - long arg3 = 0; + long arg3 = LONG_MIN; char *buffer = NULL; php_stream *stream; @@ -1185,7 +1191,7 @@ PHPAPI PHP_FUNCTION(fwrite) RETURN_FALSE; } - if (ZEND_NUM_ARGS() == 2) { + if (arg3 == LONG_MIN) { num_bytes = arg2len; } else { num_bytes = MAX(0, MIN((int)arg3, arg2len)); @@ -1394,6 +1400,7 @@ PHP_FUNCTION(umask) if (BG(umask) == -1) { BG(umask) = oldumask; } + arg1 = oldumask; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &arg1) == FAILURE) { RETURN_FALSE; diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 2ec4ec3808f43..7e30c459592e7 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -721,6 +721,8 @@ PHP_FUNCTION(touch) struct utimbuf *newtime = &newtimebuf; php_stream_wrapper *wrapper; + filetime = fileatime = time(NULL); + if (zend_parse_parameters(argc TSRMLS_CC, "p|ll", &filename, &filename_len, &filetime, &fileatime) == FAILURE) { return; } @@ -734,7 +736,7 @@ PHP_FUNCTION(touch) #ifdef HAVE_UTIME_NULL newtime = NULL; #else - newtime->modtime = newtime->actime = time(NULL); + newtime->modtime = newtime->actime = filetime; #endif break; case 2: diff --git a/ext/standard/head.c b/ext/standard/head.c index eca032a97b1fb..37e5f04ab5ec7 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -59,7 +59,7 @@ PHP_FUNCTION(header_remove) &ctr.line_len) == FAILURE) return; - sapi_header_op(ZEND_NUM_ARGS() == 0 ? SAPI_HEADER_DELETE_ALL : SAPI_HEADER_DELETE, &ctr TSRMLS_CC); + sapi_header_op(ctr.line == NULL ? SAPI_HEADER_DELETE_ALL : SAPI_HEADER_DELETE, &ctr TSRMLS_CC); } /* }}} */ diff --git a/ext/standard/image.c b/ext/standard/image.c index 27f60c95a70fd..3dcb0a103a29b 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -1389,13 +1389,12 @@ static void php_getimagesize_from_any(INTERNAL_FUNCTION_PARAMETERS, int mode) { php_stream *stream = NULL; char *input; int input_len; - const int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "s|Z", &input, &input_len, &info) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Z", &input, &input_len, &info) == FAILURE) { return; } - if (argc == 2) { + if (info != NULL) { zval_dtor(*info); array_init(*info); } diff --git a/ext/standard/math.c b/ext/standard/math.c index 65702ddf146ee..fcb1f7d6723b7 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -352,9 +352,7 @@ PHP_FUNCTION(round) return; } - if (ZEND_NUM_ARGS() >= 2) { places = (int) precision; - } convert_scalar_to_number_ex(value); switch (Z_TYPE_PP(value)) { @@ -660,7 +658,7 @@ PHP_FUNCTION(log1p) Returns the natural logarithm of the number, or the base log if base is specified */ PHP_FUNCTION(log) { - double num, base = 0; + double num, base = M_E; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|d", &num, &base) == FAILURE) { return; diff --git a/ext/standard/rand.c b/ext/standard/rand.c index b0af30aa9ddd3..155c722a3f89a 100644 --- a/ext/standard/rand.c +++ b/ext/standard/rand.c @@ -232,7 +232,7 @@ PHP_FUNCTION(srand) { long seed = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &seed) == FAILURE) + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "|l", &seed) == FAILURE) return; if (ZEND_NUM_ARGS() == 0) @@ -248,7 +248,7 @@ PHP_FUNCTION(mt_srand) { long seed = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &seed) == FAILURE) + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "|l", &seed) == FAILURE) return; if (ZEND_NUM_ARGS() == 0) diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index b62344765160f..869d58660d06a 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -1377,9 +1377,8 @@ PHP_FUNCTION(stream_set_timeout) long seconds, microseconds = 0; struct timeval t; php_stream *stream; - int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rl|l", &socket, &seconds, µseconds) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &socket, &seconds, µseconds) == FAILURE) { return; } @@ -1387,7 +1386,7 @@ PHP_FUNCTION(stream_set_timeout) t.tv_sec = seconds; - if (argc == 3) { + if (microseconds != 0) { t.tv_usec = microseconds % 1000000; t.tv_sec += microseconds / 1000000; } else { @@ -1499,7 +1498,7 @@ PHP_FUNCTION(stream_set_read_buffer) Enable or disable a specific kind of crypto on the stream */ PHP_FUNCTION(stream_socket_enable_crypto) { - long cryptokind = 0; + long cryptokind = -1; zval *zstream, *zsessstream = NULL; php_stream *stream, *sessstream = NULL; zend_bool enable; @@ -1511,7 +1510,7 @@ PHP_FUNCTION(stream_socket_enable_crypto) php_stream_from_zval(stream, &zstream); - if (ZEND_NUM_ARGS() >= 3) { + if (cryptokind != -1) { if (zsessstream) { php_stream_from_zval(sessstream, &zsessstream); } diff --git a/ext/standard/string.c b/ext/standard/string.c index b47319be310b3..7b4df3a9af85b 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -289,7 +289,7 @@ static void php_spn_common_handler(INTERNAL_FUNCTION_PARAMETERS, int behavior) / int len1, len2; long start = 0, len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll", &s11, &len1, + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll", &s11, &len1, &s22, &len2, &start, &len) == FAILURE) { return; } @@ -1271,7 +1271,7 @@ PHP_FUNCTION(strtok) return; } - if (ZEND_NUM_ARGS() == 1) { + if (tok == NULL) { tok = str; tok_len = str_len; } else { @@ -2230,22 +2230,17 @@ PHP_FUNCTION(chunk_split) PHP_FUNCTION(substr) { char *str; - long l = 0, f; + long l = LONG_MAX, f; int str_len; - int argc = ZEND_NUM_ARGS(); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &str, &str_len, &f, &l) == FAILURE) { return; } - if (argc > 2) { - if ((l < 0 && -l > str_len)) { - RETURN_FALSE; - } else if (l > str_len) { - l = str_len; - } - } else { + if (l > str_len) { l = str_len; + } else if ((l < 0 && -l > str_len)) { + RETURN_FALSE; } if (f > str_len) { @@ -2302,7 +2297,6 @@ PHP_FUNCTION(substr_replace) int result_len; int l = 0; int f; - int argc = ZEND_NUM_ARGS(); HashPosition pos_str, pos_from, pos_repl, pos_len; zval **tmp_str = NULL, **tmp_from = NULL, **tmp_repl = NULL, **tmp_len= NULL; @@ -2330,7 +2324,7 @@ PHP_FUNCTION(substr_replace) convert_to_long_ex(from); } - if (argc > 3) { + if (len != NULL) { SEPARATE_ZVAL(len); if (Z_TYPE_PP(len) != IS_ARRAY) { convert_to_long_ex(len); @@ -2344,13 +2338,13 @@ PHP_FUNCTION(substr_replace) if (Z_TYPE_PP(str) == IS_STRING) { if ( - (argc == 3 && Z_TYPE_PP(from) == IS_ARRAY) || - (argc == 4 && Z_TYPE_PP(from) != Z_TYPE_PP(len)) + (len == NULL && Z_TYPE_PP(from) == IS_ARRAY) || + (len != NULL && Z_TYPE_PP(from) != Z_TYPE_PP(len)) ) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "'from' and 'len' should be of same type - numerical or array "); RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); } - if (argc == 4 && Z_TYPE_PP(from) == IS_ARRAY) { + if (len != NULL && Z_TYPE_PP(from) == IS_ARRAY) { if (zend_hash_num_elements(Z_ARRVAL_PP(from)) != zend_hash_num_elements(Z_ARRVAL_PP(len))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "'from' and 'len' should have the same number of elements"); RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); @@ -2428,7 +2422,7 @@ PHP_FUNCTION(substr_replace) zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(from), &pos_from); } - if (argc > 3 && Z_TYPE_PP(len) == IS_ARRAY) { + if (len != NULL && Z_TYPE_PP(len) == IS_ARRAY) { zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(len), &pos_len); } @@ -2490,7 +2484,7 @@ PHP_FUNCTION(substr_replace) } } - if (argc > 3 && Z_TYPE_PP(len) == IS_ARRAY) { + if (len != NULL && Z_TYPE_PP(len) == IS_ARRAY) { if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(len), (void **) &tmp_len, &pos_len)) { if(Z_TYPE_PP(tmp_len) != IS_LONG) { zval dummy = **tmp_len; @@ -2504,7 +2498,7 @@ PHP_FUNCTION(substr_replace) } else { l = Z_STRLEN_P(orig_str); } - } else if (argc > 3) { + } else if (len != NULL) { l = Z_LVAL_PP(len); } else { l = Z_STRLEN_P(orig_str); @@ -3124,13 +3118,12 @@ PHP_FUNCTION(strtr) zval **from; char *str, *to = NULL; int str_len, to_len = 0; - int ac = ZEND_NUM_ARGS(); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ|s", &str, &str_len, &from, &to, &to_len) == FAILURE) { return; } - if (ac == 2 && Z_TYPE_PP(from) != IS_ARRAY) { + if (to == NULL && Z_TYPE_PP(from) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument is not an array"); RETURN_FALSE; } @@ -3140,7 +3133,7 @@ PHP_FUNCTION(strtr) RETURN_EMPTY_STRING(); } - if (ac == 2) { + if (to == NULL) { php_strtr_array(return_value, str, str_len, HASH_OF(*from)); } else { convert_to_string_ex(from); @@ -3236,7 +3229,6 @@ PHP_FUNCTION(similar_text) { char *t1, *t2; zval **percent = NULL; - int ac = ZEND_NUM_ARGS(); int sim; int t1_len, t2_len; @@ -3244,12 +3236,12 @@ PHP_FUNCTION(similar_text) return; } - if (ac > 2) { + if (percent != NULL) { convert_to_double_ex(percent); } if (t1_len + t2_len == 0) { - if (ac > 2) { + if (percent != NULL) { Z_DVAL_PP(percent) = 0; } @@ -3258,7 +3250,7 @@ PHP_FUNCTION(similar_text) sim = php_similar_char(t1, t1_len, t2, t2_len); - if (ac > 2) { + if (percent != NULL) { Z_DVAL_PP(percent) = sim * 200.0 / (t1_len + t2_len); } @@ -3959,7 +3951,6 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit uint string_key_len; ulong num_key; int count = 0; - int argc = ZEND_NUM_ARGS(); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|Z", &search, &replace, &subject, &zcount) == FAILURE) { return; @@ -3988,7 +3979,7 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit if (Z_TYPE_PP(subject_entry) != IS_ARRAY && Z_TYPE_PP(subject_entry) != IS_OBJECT) { MAKE_STD_ZVAL(result); SEPARATE_ZVAL(subject_entry); - php_str_replace_in_subject(*search, *replace, subject_entry, result, case_sensitivity, (argc > 3) ? &count : NULL); + php_str_replace_in_subject(*search, *replace, subject_entry, result, case_sensitivity, (zcount) ? &count : NULL); } else { ALLOC_ZVAL(result); Z_ADDREF_P(*subject_entry); @@ -4009,9 +4000,9 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit zend_hash_move_forward(Z_ARRVAL_PP(subject)); } } else { /* if subject is not an array */ - php_str_replace_in_subject(*search, *replace, subject, return_value, case_sensitivity, (argc > 3) ? &count : NULL); + php_str_replace_in_subject(*search, *replace, subject, return_value, case_sensitivity, (zcount) ? &count : NULL); } - if (argc > 3) { + if (zcount) { zval_dtor(*zcount); ZVAL_LONG(*zcount, count); } @@ -5587,7 +5578,7 @@ PHP_FUNCTION(substr_compare) zend_bool cs=0; uint cmp_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl|lb", &s1, &s1_len, &s2, &s2_len, &offset, &len, &cs) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "ssl|lb", &s1, &s1_len, &s2, &s2_len, &offset, &len, &cs) == FAILURE) { RETURN_FALSE; } diff --git a/ext/standard/tests/array/array_rand.phpt b/ext/standard/tests/array/array_rand.phpt index 1f495f4b129c0..27acb9d973d63 100644 --- a/ext/standard/tests/array/array_rand.phpt +++ b/ext/standard/tests/array/array_rand.phpt @@ -18,6 +18,8 @@ echo "Done\n"; --EXPECTF-- Warning: array_rand() expects at least 1 parameter, 0 given in %s on line %d NULL + +Warning: array_rand(): Second argument has to be between 1 and the number of elements in the array in %s on line %d NULL Warning: array_rand(): Second argument has to be between 1 and the number of elements in the array in %s on line %d diff --git a/ext/standard/type.c b/ext/standard/type.c index dcc8083e41025..fd78fc3e93685 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -134,27 +134,13 @@ PHP_FUNCTION(settype) PHP_FUNCTION(intval) { zval **num; - long arg_base; + long arg_base = 10; int base; - switch (ZEND_NUM_ARGS()) { - case 1: - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|l", &num, &arg_base) == FAILURE) { return; } - base = 10; - break; - - case 2: - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zl", &num, &arg_base) == FAILURE) { - return; - } - base = arg_base; - break; - - default: - WRONG_PARAM_COUNT; - } + base = (int)arg_base; RETVAL_ZVAL(*num, 1, 0); convert_to_long_base(return_value, base); @@ -384,7 +370,7 @@ PHP_FUNCTION(is_callable) if (syntax_only) { check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY; } - if (ZEND_NUM_ARGS() > 2) { + if (callable_name != NULL) { retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, NULL, &error TSRMLS_CC); zval_dtor(*callable_name); ZVAL_STRING(*callable_name, name, 0); diff --git a/ext/standard/versioning.c b/ext/standard/versioning.c index 9eb3829a08a52..209076766b268 100644 --- a/ext/standard/versioning.c +++ b/ext/standard/versioning.c @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Stig Sæther Bakken | + | Author: Stig S�ther Bakken | +----------------------------------------------------------------------+ */ @@ -212,15 +212,14 @@ PHP_FUNCTION(version_compare) { char *v1, *v2, *op = NULL; int v1_len, v2_len, op_len = 0; - int compare, argc; + int compare; - argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "ss|s", &v1, &v1_len, &v2, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", &v1, &v1_len, &v2, &v2_len, &op, &op_len) == FAILURE) { return; } compare = php_version_compare(v1, v2); - if (argc == 2) { + if (op == NULL) { RETURN_LONG(compare); } if (!strncmp(op, "<", op_len) || !strncmp(op, "lt", op_len)) { diff --git a/ext/sybase_ct/php_sybase_ct.c b/ext/sybase_ct/php_sybase_ct.c index 73db73e984ff9..f28270071ea2d 100644 --- a/ext/sybase_ct/php_sybase_ct.c +++ b/ext/sybase_ct/php_sybase_ct.c @@ -1982,7 +1982,7 @@ PHP_FUNCTION(sybase_fetch_field) long field_offset = -1; sybase_result *result; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &sybase_result_index, &field_offset) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_NODEFAULT, ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &sybase_result_index, &field_offset) == FAILURE) { return; } ZEND_FETCH_RESOURCE(result, sybase_result *, &sybase_result_index, -1, "Sybase result", le_result); diff --git a/ext/tokenizer/tokenizer.c b/ext/tokenizer/tokenizer.c index 8e2aaab92308f..bf736fa5feac6 100644 --- a/ext/tokenizer/tokenizer.c +++ b/ext/tokenizer/tokenizer.c @@ -180,12 +180,11 @@ static void tokenize(zval *return_value TSRMLS_DC) PHP_FUNCTION(token_get_all) { char *source = NULL; - int argc = ZEND_NUM_ARGS(); int source_len; zval source_z; zend_lex_state original_lex_state; - if (zend_parse_parameters(argc TSRMLS_CC, "s", &source, &source_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) { return; } @@ -210,10 +209,9 @@ PHP_FUNCTION(token_get_all) */ PHP_FUNCTION(token_name) { - int argc = ZEND_NUM_ARGS(); long type; - if (zend_parse_parameters(argc TSRMLS_CC, "l", &type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &type) == FAILURE) { return; } RETVAL_STRING(get_token_type_name(type), 1); diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c index 799b47b3ef44a..9c67b58ce519b 100644 --- a/ext/xmlrpc/xmlrpc-epi-php.c +++ b/ext/xmlrpc/xmlrpc-epi-php.c @@ -1098,17 +1098,12 @@ PHP_FUNCTION(xmlrpc_server_call_method) char *rawxml; int rawxml_len, type; php_output_options out; - int argc =ZEND_NUM_ARGS(); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsZ|a", &handle, &rawxml, &rawxml_len, &caller_params, &output_opts) != SUCCESS) { return; } - /* user output options */ - if (argc == 3) { - set_output_options(&out, NULL); - } else { + /* user output options, will set to NULL if omitted */ set_output_options(&out, output_opts); - } server = zend_list_find(Z_LVAL_P(handle), &type); diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index f464e1e92a0ab..6f93940c74b52 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -1521,8 +1521,8 @@ static PHP_MINFO_FUNCTION(cgi) PHP_FUNCTION(apache_child_terminate) /* {{{ */ { - if (ZEND_NUM_ARGS() > 0) { - WRONG_PARAM_COUNT; + if (zend_parse_parameters_none() == FAILURE) { + return; } if (fcgi_is_fastcgi()) { fcgi_terminate(); @@ -1580,8 +1580,8 @@ static void add_request_header(char *var, unsigned int var_len, char *val, unsig PHP_FUNCTION(apache_request_headers) /* {{{ */ { - if (ZEND_NUM_ARGS() > 0) { - WRONG_PARAM_COUNT; + if (zend_parse_parameters_none() == FAILURE) { + return; } array_init(return_value); if (fcgi_is_fastcgi()) {