mirror of
https://github.com/php/php-src.git
synced 2026-04-02 05:32:28 +02:00
Fix various little leaks and segfaults.
Fix scripts like this:
$obj = new COM('Foo');
$obj2 = $obj->get_object();
$obj2->method(); // <-- would segfault here
This commit is contained in:
@@ -491,26 +491,18 @@ static int com_call(rpc_string method_name, void **data, zval *return_value, int
|
||||
DISPID dispid;
|
||||
DISPPARAMS dispparams;
|
||||
HRESULT hr;
|
||||
OLECHAR *funcname;
|
||||
VARIANT *variant_args, *result;
|
||||
OLECHAR *funcname = NULL;
|
||||
VARIANT *variant_args;
|
||||
VARIANT result;
|
||||
int current_arg, current_variant;
|
||||
char *ErrString;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
funcname = php_char_to_OLECHAR(method_name.str, method_name.len, CP_ACP, FALSE);
|
||||
/* if the length of the name is 0, we are dealing with a pointer to a dispid */
|
||||
assert(method_name.len == 0);
|
||||
dispid = *(DISPID*)method_name.str;
|
||||
|
||||
if (FAILED(hr = php_COM_get_ids_of_names((comval *) *data, funcname, &dispid))) {
|
||||
char *error_message;
|
||||
|
||||
error_message = php_COM_error_message(hr);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,"Unable to lookup %s: %s", method_name.str, error_message);
|
||||
LocalFree(error_message);
|
||||
efree(funcname);
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
variant_args = (VARIANT *) emalloc(sizeof(VARIANT) * num_args);
|
||||
variant_args = num_args ? (VARIANT *) emalloc(sizeof(VARIANT) * num_args) : NULL;
|
||||
|
||||
for (current_arg = 0; current_arg < num_args; current_arg++) {
|
||||
current_variant = num_args - current_arg - 1;
|
||||
@@ -522,10 +514,9 @@ static int com_call(rpc_string method_name, void **data, zval *return_value, int
|
||||
dispparams.cArgs = num_args;
|
||||
dispparams.cNamedArgs = 0;
|
||||
|
||||
result = (VARIANT *) emalloc(sizeof(VARIANT));
|
||||
VariantInit(result);
|
||||
VariantInit(&result);
|
||||
|
||||
hr = php_COM_invoke((comval *) *data, dispid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, result, &ErrString);
|
||||
hr = php_COM_invoke((comval *) *data, dispid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, &result, &ErrString);
|
||||
|
||||
for (current_arg=0;current_arg<num_args;current_arg++) {
|
||||
/* don't release IDispatch pointers as they are used afterwards */
|
||||
@@ -535,13 +526,14 @@ static int com_call(rpc_string method_name, void **data, zval *return_value, int
|
||||
}
|
||||
}
|
||||
|
||||
efree(result);
|
||||
efree(funcname);
|
||||
if (variant_args) {
|
||||
efree(variant_args);
|
||||
variant_args = NULL;
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
char *error_message;
|
||||
|
||||
efree(result);
|
||||
error_message = php_COM_error_message(hr);
|
||||
if (ErrString) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,"Invoke() failed: %s %s", error_message, ErrString);
|
||||
@@ -553,7 +545,8 @@ static int com_call(rpc_string method_name, void **data, zval *return_value, int
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
RETVAL_VARIANT(result, C_CODEPAGE((comval *) *data));
|
||||
RETVAL_VARIANT(&result, C_CODEPAGE((comval *) *data));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +289,9 @@ ZEND_API HRESULT php_COM_destruct(comval *obj)
|
||||
C_ENUMVARIANT_VT(obj)->Release(C_ENUMVARIANT(obj));
|
||||
}
|
||||
|
||||
hr = C_DISPATCH_VT(obj)->Release(C_DISPATCH(obj));
|
||||
if (C_DISPATCH(obj)) {
|
||||
hr = C_DISPATCH_VT(obj)->Release(C_DISPATCH(obj));
|
||||
}
|
||||
efree(obj);
|
||||
|
||||
return hr;
|
||||
@@ -908,15 +910,13 @@ ZEND_API int php_COM_load_typelib(ITypeLib *TypeLib, int mode)
|
||||
PHPAPI zval *php_COM_object_from_dispatch(IDispatch *disp)
|
||||
{
|
||||
comval *obj;
|
||||
zval *zobj;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
ALLOC_COM(obj);
|
||||
MAKE_STD_ZVAL(zobj);
|
||||
php_COM_set(obj, &disp, FALSE);
|
||||
ZVAL_COM(zobj, obj);
|
||||
|
||||
return zobj;
|
||||
return rpc_object_from_data(NULL, com, obj, NULL);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,20 +33,13 @@
|
||||
|
||||
#define ZVAL_VARIANT(z, v, cp) \
|
||||
if (V_VT(v) == VT_DISPATCH) { \
|
||||
rpc_internal *intern; \
|
||||
comval *obj; \
|
||||
ALLOC_COM(obj); \
|
||||
Z_TYPE_P(z) = IS_OBJECT; \
|
||||
(z)->value.obj = rpc_objects_new(com_class_entry TSRMLS_CC); \
|
||||
if (GET_INTERNAL_EX(intern, (z)) != SUCCESS) { \
|
||||
/* TODO: exception */ \
|
||||
} \
|
||||
php_COM_set(obj, &V_DISPATCH(v), TRUE); \
|
||||
intern->data = obj; \
|
||||
rpc_object_from_data(z, com, obj, NULL); \
|
||||
} else { \
|
||||
php_variant_to_zval((v), (z), cp); \
|
||||
VariantClear(v); \
|
||||
efree(v); \
|
||||
}
|
||||
|
||||
#define RETVAL_VARIANT(v, cp) ZVAL_VARIANT(return_value, v, cp)
|
||||
|
||||
Reference in New Issue
Block a user