diff --git a/src/include/pythoncapi_compat.h b/src/include/pythoncapi_compat.h index b4c818104..f8cc2fd59 100644 --- a/src/include/pythoncapi_compat.h +++ b/src/include/pythoncapi_compat.h @@ -1134,6 +1134,7 @@ static inline int PyTime_PerfCounter(PyTime_t *result) } PyObject *res = PyObject_CallNoArgs(func); + Py_XDECREF(func); if (res == NULL) { return -1; } @@ -1165,6 +1166,7 @@ static inline int PyTime_PerfCounter(PyTime_t *result) } PyObject *res = PyObject_CallNoArgs(func); + Py_XDECREF(func); if (res == NULL) { return -1; } diff --git a/src/main/client/batch_write.c b/src/main/client/batch_write.c index 888eed5ef..c3826112e 100644 --- a/src/main/client/batch_write.c +++ b/src/main/client/batch_write.c @@ -62,11 +62,10 @@ as_error_update(err, AEROSPIKE_ERR_PARAM, \ "batch_type: %s, policy must be a dict", \ __batch_type); \ - Py_DECREF(py___policy); \ goto CLEANUP_ON_ERROR; \ } \ } \ - Py_DECREF(py___policy); \ + Py_XDECREF(py___policy); \ } // TODO replace this with type checking the batch_records @@ -247,7 +246,7 @@ static PyObject *AerospikeClient_BatchWriteInvoke(AerospikeClient *self, FIELD_NAME_BATCH_TYPE); goto CLEANUP1; } - + py_ops_list = PyObject_GetAttrString(py_batch_record, FIELD_NAME_BATCH_OPS); if (py_ops_list == NULL || !PyList_Check(py_ops_list) || @@ -262,7 +261,7 @@ static PyObject *AerospikeClient_BatchWriteInvoke(AerospikeClient *self, FIELD_NAME_BATCH_OPS); // TODO: mem leak if ops is not a list? // Fix later - goto CLEANUP1; + goto CLEANUP0; } // the batch record object had no ops attribute but some don't, so this is ok. @@ -376,8 +375,8 @@ static PyObject *AerospikeClient_BatchWriteInvoke(AerospikeClient *self, Py_XDECREF(py_mod); goto CLEANUP_ON_ERROR; } - Py_DECREF(py_mod); const char *mod = PyUnicode_AsUTF8(py_mod); + Py_DECREF(py_mod); PyObject *py_func = PyObject_GetAttrString( py_batch_record, FIELD_NAME_BATCH_FUNCTION); @@ -387,8 +386,8 @@ static PyObject *AerospikeClient_BatchWriteInvoke(AerospikeClient *self, Py_XDECREF(py_func); goto CLEANUP_ON_ERROR; } - Py_DECREF(py_func); const char *func = PyUnicode_AsUTF8(py_func); + Py_DECREF(py_func); PyObject *py_args = PyObject_GetAttrString(py_batch_record, FIELD_NAME_BATCH_ARGS); @@ -403,11 +402,10 @@ static PyObject *AerospikeClient_BatchWriteInvoke(AerospikeClient *self, as_list *arglist = NULL; pyobject_to_list(self, err, py_args, &arglist, &static_pool, SERIALIZER_PYTHON); + Py_DECREF(py_args); if (err->code != AEROSPIKE_OK) { - Py_DECREF(py_args); goto CLEANUP_ON_ERROR; } - Py_DECREF(py_args); garb->udf_args_to_free = arglist; as_batch_apply_record *ar; @@ -522,6 +520,7 @@ static PyObject *AerospikeClient_BatchWriteInvoke(AerospikeClient *self, CLEANUP_ON_ERROR: Py_XDECREF(py_meta); +CLEANUP0: Py_XDECREF(py_ops_list); CLEANUP1: Py_XDECREF(py_batch_type); diff --git a/src/main/conversions.c b/src/main/conversions.c index 142dc485d..a770cb0a4 100644 --- a/src/main/conversions.c +++ b/src/main/conversions.c @@ -2705,13 +2705,19 @@ as_status get_cdt_ctx(AerospikeClient *self, as_error *err, as_cdt_ctx *cdt_ctx, as_static_pool *static_pool, int serializer_type) { PyObject *py_ctx = PyDict_GetItemString(op_dict, CTX_KEY); - long int_val = 0; - as_val *val = NULL; if (!py_ctx) { return AEROSPIKE_OK; } + long int_val = 0; + as_val *val = NULL; + + as_status status = 0; + PyObject *id_temp = NULL; + PyObject *value_temp = NULL; + PyObject *extra_args_temp = NULL; + if (PyList_Check(py_ctx)) { Py_ssize_t py_list_size = PyList_Size(py_ctx); as_cdt_ctx_init(cdt_ctx, (int)py_list_size); @@ -2719,34 +2725,37 @@ as_status get_cdt_ctx(AerospikeClient *self, as_error *err, as_cdt_ctx *cdt_ctx, for (int i = 0; i < py_list_size; i++) { PyObject *py_val = PyList_GetItem(py_ctx, (Py_ssize_t)i); - PyObject *id_temp = PyObject_GetAttrString(py_val, "id"); + id_temp = PyObject_GetAttrString(py_val, "id"); if (PyErr_Occurred()) { as_cdt_ctx_destroy(cdt_ctx); - return as_error_update(err, AEROSPIKE_ERR_PARAM, + status = as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s, id", CTX_KEY); + goto CLEANUP4; } - PyObject *value_temp = PyObject_GetAttrString(py_val, "value"); + value_temp = PyObject_GetAttrString(py_val, "value"); if (PyErr_Occurred()) { as_cdt_ctx_destroy(cdt_ctx); - return as_error_update(err, AEROSPIKE_ERR_PARAM, + status = as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s, value", CTX_KEY); + goto CLEANUP3; } - PyObject *extra_args_temp = - PyObject_GetAttrString(py_val, "extra_args"); + extra_args_temp = PyObject_GetAttrString(py_val, "extra_args"); if (PyErr_Occurred()) { as_cdt_ctx_destroy(cdt_ctx); - return as_error_update(err, AEROSPIKE_ERR_PARAM, + status = as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s", CTX_KEY); + goto CLEANUP2; } uint64_t item_type = PyLong_AsUnsignedLongLong(id_temp); if (PyErr_Occurred()) { as_cdt_ctx_destroy(cdt_ctx); - return as_error_update(err, AEROSPIKE_ERR_PARAM, + status = as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s, id to uint64_t", CTX_KEY); + goto CLEANUP1; } // add an as_cdt_ctx with value to cdt_ctx @@ -2754,9 +2763,10 @@ as_status get_cdt_ctx(AerospikeClient *self, as_error *err, as_cdt_ctx *cdt_ctx, int_val = PyLong_AsLong(value_temp); if (PyErr_Occurred()) { as_cdt_ctx_destroy(cdt_ctx); - return as_error_update( + status = as_error_update( err, AEROSPIKE_ERR_PARAM, "Failed to convert %s, value to long", CTX_KEY); + goto CLEANUP1; } switch (item_type) { case AS_CDT_CTX_LIST_INDEX: @@ -2783,9 +2793,10 @@ as_status get_cdt_ctx(AerospikeClient *self, as_error *err, as_cdt_ctx *cdt_ctx, break; default: as_cdt_ctx_destroy(cdt_ctx); - return as_error_update( + status = as_error_update( err, AEROSPIKE_ERR_PARAM, "Failed to convert, unknown ctx operation %s", CTX_KEY); + goto CLEANUP1; } } else { @@ -2793,9 +2804,10 @@ as_status get_cdt_ctx(AerospikeClient *self, as_error *err, as_cdt_ctx *cdt_ctx, static_pool, serializer_type) != AEROSPIKE_OK) { as_cdt_ctx_destroy(cdt_ctx); - return as_error_update( + status = as_error_update( err, AEROSPIKE_ERR_PARAM, "Failed to convert %s, value to as_val", CTX_KEY); + goto CLEANUP1; } switch (item_type) { case AS_CDT_CTX_LIST_VALUE: @@ -2815,24 +2827,35 @@ as_status get_cdt_ctx(AerospikeClient *self, as_error *err, as_cdt_ctx *cdt_ctx, break; default: as_cdt_ctx_destroy(cdt_ctx); - return as_error_update( + status = as_error_update( err, AEROSPIKE_ERR_PARAM, "Failed to convert, unknown ctx operation %s", CTX_KEY); + goto CLEANUP1; } } Py_DECREF(id_temp); Py_DECREF(value_temp); - Py_XDECREF(extra_args_temp); + Py_DECREF(extra_args_temp); } } else { - return as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s", + status = as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s", CTX_KEY); + goto CLEANUP4; } *ctx_in_use = true; return AEROSPIKE_OK; + +CLEANUP1: + Py_DECREF(extra_args_temp); +CLEANUP2: + Py_DECREF(value_temp); +CLEANUP3: + Py_DECREF(id_temp); +CLEANUP4: + return status; } static bool requires_int(uint64_t op)