Browse Source

Arguments taken by internal functions using zend_parse_parameters() with "+" and "*" specifications must not be deallocated anymore.

pull/678/head
Dmitry Stogov 13 years ago
parent
commit
040dea8b82
  1. 17
      Zend/zend_API.c
  2. 21
      ext/reflection/php_reflection.c
  3. 2
      ext/session/session.c
  4. 32
      ext/standard/array.c
  5. 14
      ext/standard/basic_functions.c
  6. 9
      ext/standard/file.c
  7. 8
      ext/standard/formatted_print.c
  8. 4
      ext/standard/pack.c
  9. 13
      ext/standard/string.c
  10. 2
      ext/standard/var.c

17
Zend/zend_API.c

@ -920,22 +920,11 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
type_spec++;
if (num_varargs > 0) {
int iv = 0;
zval *p = (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count - i));
*n_varargs = num_varargs;
/* allocate space for array and store args */
*varargs = (zval*)safe_emalloc(num_varargs, sizeof(zval), 0);
while (num_varargs-- > 0) {
ZVAL_COPY_VALUE(&(*varargs)[iv], p);
iv++;
p++;
}
*varargs = (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count - i));
/* adjust how many args we have left and restart loop */
num_args = num_args + 1 - iv;
i += iv;
num_args += 1 - num_varargs;
i += num_varargs;
continue;
} else {
*varargs = NULL;

21
ext/reflection/php_reflection.c

@ -1908,10 +1908,6 @@ ZEND_METHOD(reflection_function, invoke)
result = zend_call_function(&fci, &fcc TSRMLS_CC);
if (num_args) {
efree(params);
}
if (result == FAILURE) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
"Invocation of function %s() failed", fptr->common.function_name->val);
@ -2854,7 +2850,6 @@ ZEND_METHOD(reflection_method, invoke)
obj_ce = mptr->common.scope;
} else {
if (Z_TYPE(params[0]) != IS_OBJECT) {
efree(params);
_DO_THROW("Non-object passed to Invoke()");
/* Returns from this function */
}
@ -2862,9 +2857,6 @@ ZEND_METHOD(reflection_method, invoke)
obj_ce = Z_OBJCE(params[0]);
if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) {
if (params) {
efree(params);
}
_DO_THROW("Given object is not an instance of the class this method was declared in");
/* Returns from this function */
}
@ -2890,10 +2882,6 @@ ZEND_METHOD(reflection_method, invoke)
result = zend_call_function(&fci, &fcc TSRMLS_CC);
if (params) {
efree(params);
}
if (result == FAILURE) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
"Invocation of method %s::%s() failed", mptr->common.scope->name->val, mptr->common.function_name->val);
@ -4207,9 +4195,6 @@ ZEND_METHOD(reflection_class, newInstance)
}
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &params, &num_args) == FAILURE) {
if (params) {
efree(params);
}
zval_dtor(return_value);
RETURN_FALSE;
}
@ -4231,9 +4216,6 @@ ZEND_METHOD(reflection_class, newInstance)
ZVAL_COPY_VALUE(&fcc.object, return_value);
if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
if (params) {
efree(params);
}
if (!ZVAL_IS_UNDEF(&retval)) {
zval_ptr_dtor(&retval);
}
@ -4244,9 +4226,6 @@ ZEND_METHOD(reflection_class, newInstance)
if (!ZVAL_IS_UNDEF(&retval)) {
zval_ptr_dtor(&retval);
}
if (params) {
efree(params);
}
} else if (ZEND_NUM_ARGS()) {
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->val);
}

2
ext/session/session.c

@ -1875,7 +1875,6 @@ static PHP_FUNCTION(session_set_save_handler)
/* at this point argc can only be 6 or 7 */
for (i = 0; i < argc; i++) {
if (!zend_is_callable(*args[i], 0, &name TSRMLS_CC)) {
efree(args);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
efree(name);
RETURN_FALSE;
@ -1895,7 +1894,6 @@ static PHP_FUNCTION(session_set_save_handler)
PS(mod_user_names).names[i] = *args[i];
}
efree(args);
RETURN_TRUE;
}
/* }}} */

32
ext/standard/array.c

@ -969,10 +969,6 @@ PHP_FUNCTION(min)
RETVAL_ZVAL_FAST(min);
}
if (args) {
efree(args);
}
}
/* }}} */
@ -1020,10 +1016,6 @@ PHP_FUNCTION(max)
RETVAL_ZVAL_FAST(max);
}
if (args) {
efree(args);
}
}
/* }}} */
@ -1474,10 +1466,6 @@ PHP_FUNCTION(compact)
for (i=0; i<ZEND_NUM_ARGS(); i++) {
php_compact_var(EG(active_symbol_table), return_value, &args[i] TSRMLS_CC);
}
if (args) {
efree(args);
}
}
/* }}} */
@ -1906,13 +1894,11 @@ PHP_FUNCTION(array_push)
if (zend_hash_next_index_insert(Z_ARRVAL_P(stack), &new_var) == NULL) {
if (Z_REFCOUNTED(new_var)) Z_DELREF(new_var);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element to the array as the next element is already occupied");
efree(args);
RETURN_FALSE;
}
}
/* Clean up and return the number of values in the stack */
efree(args);
RETVAL_LONG(zend_hash_num_elements(Z_ARRVAL_P(stack)));
}
/* }}} */
@ -2029,7 +2015,6 @@ PHP_FUNCTION(array_unshift)
zend_hash_destroy(&old_hash);
/* Clean up and return the number of elements in the stack */
efree(args);
RETVAL_LONG(zend_hash_num_elements(Z_ARRVAL_P(stack)));
}
/* }}} */
@ -2353,7 +2338,6 @@ static void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETERS, int
for (i = 0; i < argc; i++) {
if (Z_TYPE(args[i]) != IS_ARRAY) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1);
efree(args);
RETURN_NULL();
} else {
int num = zend_hash_num_elements(Z_ARRVAL(args[i]));
@ -2375,8 +2359,6 @@ static void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETERS, int
zend_hash_merge(Z_ARRVAL_P(return_value), Z_ARRVAL(args[i]), zval_add_ref, 1);
}
}
efree(args);
}
/* }}} */
@ -3164,7 +3146,6 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
efree(ptrs);
efree(lists);
efree(args);
RETURN_FALSE;
}
lists[i] = list;
@ -3303,7 +3284,6 @@ out:
efree(ptrs);
efree(lists);
efree(args);
}
/* }}} */
@ -3408,8 +3388,7 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
for (i = 0; i < argc; i++) {
if (Z_TYPE(args[i]) != IS_ARRAY) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1);
RETVAL_NULL();
goto out;
RETURN_NULL();
}
}
@ -3450,8 +3429,6 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
}
}
}
out:
efree(args);
}
/* }}} */
@ -3585,7 +3562,6 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
efree(ptrs);
efree(lists);
efree(args);
RETURN_FALSE;
}
lists[i] = list;
@ -3720,7 +3696,6 @@ out:
efree(ptrs);
efree(lists);
efree(args);
}
/* }}} */
@ -3936,7 +3911,6 @@ PHP_FUNCTION(array_multisort)
efree(ARRAYG(multisort_flags)[k]);
}
efree(arrays);
efree(args);
RETURN_TRUE;
}
@ -3993,7 +3967,6 @@ PHP_FUNCTION(array_multisort)
efree(ARRAYG(multisort_flags)[k]);
}
efree(arrays);
efree(args);
RETURN_TRUE;
}
/* }}} */
@ -4314,7 +4287,6 @@ PHP_FUNCTION(array_map)
for (i = 0; i < n_arrays; i++) {
if (Z_TYPE(arrays[i]) != IS_ARRAY) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d should be an array", i + 2);
efree(arrays);
efree(args);
efree(array_len);
efree(array_pos);
@ -4333,7 +4305,6 @@ PHP_FUNCTION(array_map)
/* Short-circuit: if no callback and only one array, just return it. */
if (!ZEND_FCI_INITIALIZED(fci) && n_arrays == 1) {
RETVAL_ZVAL(args[0], 1, 0);
efree(arrays);
efree(array_len);
efree(array_pos);
efree(args);
@ -4408,7 +4379,6 @@ PHP_FUNCTION(array_map)
}
}
efree(arrays);
efree(params);
efree(array_len);
efree(array_pos);

14
ext/standard/basic_functions.c

@ -4785,10 +4785,6 @@ PHP_FUNCTION(call_user_func)
if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
COPY_PZVAL_TO_ZVAL(*return_value, &retval);
}
if (fci.params) {
efree(fci.params);
}
}
/* }}} */
@ -4832,9 +4828,6 @@ PHP_FUNCTION(call_user_method)
Z_TYPE_P(object) != IS_STRING
) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument is not an object or class name");
if (params) {
efree(params);
}
RETURN_FALSE;
}
@ -4847,9 +4840,6 @@ PHP_FUNCTION(call_user_method)
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", Z_STRVAL_P(callback));
}
if (n_params) {
efree(params);
}
}
/* }}} */
@ -4925,10 +4915,6 @@ PHP_FUNCTION(forward_static_call)
if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
COPY_PZVAL_TO_ZVAL(*return_value, &retval);
}
if (fci.params) {
efree(fci.params);
}
}
/* }}} */

9
ext/standard/file.c

@ -1143,25 +1143,16 @@ PHP_FUNCTION(fscanf)
* with a leak if we have an invalid filehandle. This needs changing
* if the code behind ZEND_VERIFY_RESOURCE changed. - cc */
if (!what) {
if (args) {
efree(args);
}
RETURN_FALSE;
}
buf = php_stream_get_line((php_stream *) what, NULL, 0, &len);
if (buf == NULL) {
if (args) {
efree(args);
}
RETURN_FALSE;
}
result = php_sscanf_internal(buf, format, argc, args, 0, return_value TSRMLS_CC);
if (args) {
efree(args);
}
efree(buf);
if (SCAN_ERROR_WRONG_PARAM_COUNT == result) {

8
ext/standard/formatted_print.c

@ -385,7 +385,6 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC)
/* verify the number of args */
if ((use_array && argc != (2 + format_offset))
|| (!use_array && argc < (1 + format_offset))) {
efree(args);
WRONG_PARAM_COUNT_WITH_RETVAL(NULL);
}
@ -408,7 +407,6 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC)
ZVAL_COPY_VALUE(&newargs[i], zv);
i++;
}
efree(args);
zval_dtor(&array);
args = newargs;
format_offset = 0;
@ -450,7 +448,6 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC)
if (argnum <= 0) {
efree(result);
efree(args);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument number must be greater than zero");
return NULL;
}
@ -491,7 +488,6 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC)
PRINTF_DEBUG(("sprintf: getting width\n"));
if ((width = php_sprintf_getnumber(format, &inpos)) < 0) {
efree(result);
efree(args);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Width must be greater than zero and less than %d", INT_MAX);
return NULL;
}
@ -508,7 +504,6 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC)
if (isdigit((int)format[inpos])) {
if ((precision = php_sprintf_getnumber(format, &inpos)) < 0) {
efree(result);
efree(args);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Precision must be greater than zero and less than %d", INT_MAX);
return NULL;
}
@ -528,7 +523,6 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC)
if (argnum >= argc) {
efree(result);
efree(args);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments");
return NULL;
}
@ -649,8 +643,6 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC)
}
}
efree(args);
/* possibly, we have to make sure we have room for the terminating null? */
result->val[outpos]=0;
result->len = outpos;

4
ext/standard/pack.c

@ -174,7 +174,6 @@ PHP_FUNCTION(pack)
case 'h':
case 'H':
if (currentarg >= num_args) {
efree(argv);
efree(formatcodes);
efree(formatargs);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: not enough arguments", code);
@ -220,7 +219,6 @@ PHP_FUNCTION(pack)
currentarg += arg;
if (currentarg > num_args) {
efree(argv);
efree(formatcodes);
efree(formatargs);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: too few arguments", code);
@ -229,7 +227,6 @@ PHP_FUNCTION(pack)
break;
default:
efree(argv);
efree(formatcodes);
efree(formatargs);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: unknown format code", code);
@ -485,7 +482,6 @@ PHP_FUNCTION(pack)
}
}
efree(argv);
efree(formatcodes);
efree(formatargs);
output[outputpos] = '\0';

13
ext/standard/string.c

@ -4333,9 +4333,6 @@ PHP_FUNCTION(setlocale)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid locale category name %s, must be one of LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, or LC_TIME", category);
zval_dtor(&tmp);
if (args) {
efree(args);
}
RETURN_FALSE;
}
zval_dtor(&tmp);
@ -4385,9 +4382,6 @@ PHP_FUNCTION(setlocale)
}
zval_dtor(&tmp);
if (args) {
efree(args);
}
RETURN_STRING(retval);
}
zval_dtor(&tmp);
@ -4400,9 +4394,6 @@ PHP_FUNCTION(setlocale)
}
#endif
if (args) {
efree(args);
}
RETURN_FALSE;
}
/* }}} */
@ -5272,10 +5263,6 @@ PHP_FUNCTION(sscanf)
result = php_sscanf_internal(str, format, num_args, args, 0, return_value TSRMLS_CC);
if (args) {
efree(args);
}
if (SCAN_ERROR_WRONG_PARAM_COUNT == result) {
WRONG_PARAM_COUNT;
}

2
ext/standard/var.c

@ -187,7 +187,6 @@ PHP_FUNCTION(var_dump)
for (i = 0; i < argc; i++) {
php_var_dump(&args[i], 1 TSRMLS_CC);
}
efree(args);
}
/* }}} */
@ -338,7 +337,6 @@ PHP_FUNCTION(debug_zval_dump)
for (i = 0; i < argc; i++) {
php_debug_zval_dump(&args[i], 1 TSRMLS_CC);
}
efree(args);
}
/* }}} */

Loading…
Cancel
Save