Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CLIENT-2539] Prevent potential crashes if C client receives invalid string data from the server #588

Draft
wants to merge 9 commits into
base: dev
Choose a base branch
from
5 changes: 5 additions & 0 deletions src/main/client/get_cdtctx_base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ PyObject *AerospikeClient_GetCDTCTXBase64(AerospikeClient *self, PyObject *args,
}

py_response = PyUnicode_FromString((const char *)base64);
if (!py_response) {
PyErr_Clear();
as_error_update(&err, AEROSPIKE_ERR_CLIENT,
"Unable to parse base64 string");
}

CLEANUP:

Expand Down
5 changes: 5 additions & 0 deletions src/main/client/get_expression_base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ PyObject *AerospikeClient_GetExpressionBase64(AerospikeClient *self,
base64_filter = as_exp_compile_b64(exp_list_p);

py_response = PyUnicode_FromString((const char *)base64_filter);
if (!py_response) {
PyErr_Clear();
as_error_update(&err, AEROSPIKE_ERR_CLIENT,
"Unable to parse base64 string");
}

CLEANUP:

Expand Down
6 changes: 6 additions & 0 deletions src/main/client/info_random_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ static PyObject *AerospikeClient_InfoRandomNode_Invoke(as_error *err,
if (err->code == AEROSPIKE_OK) {
if (response_p != NULL && status == AEROSPIKE_OK) {
py_response = PyUnicode_FromString(response_p);
if (!py_response) {
PyErr_Clear();
as_error_update(err, AEROSPIKE_ERR_CLIENT,
"Unable to parse info operation response");
goto CLEANUP;
}
}
else if (response_p == NULL) {
as_error_update(err, AEROSPIKE_ERR_CLIENT,
Expand Down
6 changes: 6 additions & 0 deletions src/main/client/info_single_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ static PyObject *AerospikeClient_InfoSingleNode_Invoke(as_error *err,
if (err->code == AEROSPIKE_OK) {
if (response_p != NULL && status == AEROSPIKE_OK) {
py_response = PyUnicode_FromString(response_p);
if (!py_response) {
PyErr_Clear();
as_error_update(err, AEROSPIKE_ERR_CLIENT,
"Unable to parse info operation response");
goto CLEANUP;
}
}
else if (response_p == NULL) {
as_error_update(err, AEROSPIKE_ERR_CLIENT,
Expand Down
6 changes: 6 additions & 0 deletions src/main/client/set_xdr_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ PyObject *AerospikeClient_SetXDRFilter(AerospikeClient *self, PyObject *args,
if (err.code == AEROSPIKE_OK) {
if (response_p != NULL && status == AEROSPIKE_OK) {
py_response = PyUnicode_FromString(response_p);
if (!py_response) {
PyErr_Clear();
as_error_update(&err, AEROSPIKE_ERR_CLIENT,
"Unable to parse info operation response");
goto CLEANUP;
}
}
else if (response_p == NULL) {
as_error_update(&err, AEROSPIKE_ERR_CLIENT,
Expand Down
64 changes: 64 additions & 0 deletions src/main/conversions.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,19 @@ as_status as_udf_file_to_pyobject(as_error *err, as_udf_file *entry,
as_error_reset(err);

*py_file = PyDict_New();
if (*py_file == NULL) {
PyErr_Clear();
return as_error_update(err, AEROSPIKE_ERR_CLIENT,
"Unable to create UDF file object");
}

PyObject *py_name = PyUnicode_FromString(entry->name);
if (!py_name) {
PyErr_Clear();
Py_DECREF(py_file);
return as_error_update(err, AEROSPIKE_ERR,
"Unable to parse UDF file name");
}
PyDict_SetItemString(*py_file, "name", py_name);
Py_DECREF(py_name);

Expand Down Expand Up @@ -177,9 +188,21 @@ as_status as_user_array_to_pyobject(as_error *err, as_user **users,
int i;

PyObject *py_users = PyDict_New();
if (py_users == NULL) {
PyErr_Clear();
return as_error_update(err, AEROSPIKE_ERR_CLIENT,
"Unable to create users object");
}

for (i = 0; i < users_size; i++) {

PyObject *py_user = PyUnicode_FromString(users[i]->name);
if (!py_user) {
PyErr_Clear();
Py_DECREF(py_users);
return as_error_update(err, AEROSPIKE_ERR,
"Unable to parse user name at index %d", i);
}
PyObject *py_roles = PyList_New(0);
str_array_of_roles_to_py_list(err, users[i]->roles_size,
users[i]->roles, py_roles);
Expand Down Expand Up @@ -295,9 +318,21 @@ as_status as_role_array_to_pyobject_old(as_error *err, as_role **roles,
int i;

PyObject *py_roles = PyDict_New();
if (py_roles == NULL) {
PyErr_Clear();
return as_error_update(err, AEROSPIKE_ERR_CLIENT,
"Unable to create roles object");
}

for (i = 0; i < roles_size; i++) {

PyObject *py_role = PyUnicode_FromString(roles[i]->name);
if (!py_role) {
PyErr_Clear();
Py_DECREF(py_roles);
return as_error_update(err, AEROSPIKE_ERR_CLUSTER,
"Unable to parse role name at index %d", i);
}
PyObject *py_privileges = PyList_New(0);

as_privilege_to_pyobject(err, roles[i]->privileges, py_privileges,
Expand Down Expand Up @@ -632,7 +667,18 @@ as_status as_privilege_to_pyobject(as_error *err, as_privilege privileges[],
PyObject *py_code = NULL;
for (int i = 0; i < privilege_size; i++) {
py_ns = PyUnicode_FromString(privileges[i].ns);
if (!py_ns) {
return as_error_update(
err, AEROSPIKE_ERR,
"Unable to parse namespace for privilege at index %d", i);
}
py_set = PyUnicode_FromString(privileges[i].set);
if (!py_set) {
Py_DECREF(py_ns);
return as_error_update(
err, AEROSPIKE_ERR,
"Unable to parse set for privilege at index %d", i);
}
py_code = PyLong_FromLong(privileges[i].code);

PyObject *py_privilege = PyDict_New();
Expand Down Expand Up @@ -1781,6 +1827,13 @@ as_status do_val_to_pyobject(AerospikeClient *self, as_error *err,
as_geojson *gp = as_geojson_fromval(val);
char *locstr = as_geojson_get(gp);
PyObject *py_locstr = PyUnicode_FromString(locstr);
if (!py_locstr) {
// An invalid C string was passed (cannot be parsed into unicode)
PyErr_Clear();
as_error_update(err, AEROSPIKE_ERR_CLIENT,
"Unable to parse GeoJSON string");
return err->code;
}
PyObject *py_loads = AerospikeGeospatial_DoLoads(py_locstr, err);
Py_DECREF(py_locstr);
if (err->code != AEROSPIKE_OK) {
Expand Down Expand Up @@ -2143,10 +2196,21 @@ as_status key_to_pyobject(as_error *err, const as_key *key, PyObject **obj)

if (strlen(key->ns) > 0) {
py_namespace = PyUnicode_FromString(key->ns);
if (!py_namespace) {
PyErr_Clear();
return as_error_update(err, AEROSPIKE_ERR_CLIENT,
"Unable to parse key namespace");
}
}

if (strlen(key->set) > 0) {
py_set = PyUnicode_FromString(key->set);
if (!py_set) {
PyErr_Clear();
Py_DECREF(py_namespace);
return as_error_update(err, AEROSPIKE_ERR_CLIENT,
"Unable to parse key namespace");
}
}

if (key->valuep) {
Expand Down
18 changes: 11 additions & 7 deletions src/main/geospatial/type.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,20 +160,24 @@ AerospikeGeospatial *self;
snprintf(new_repr_str, strlen(initresult_str) + 3, "\'%s\'",
initresult_str);

CLEANUP:
py_return = PyUnicode_FromString(new_repr_str);
if (!py_return) {
PyErr_Clear();
as_error_update(&err, AEROSPIKE_ERR_CLIENT,
"Unable to parse GeoJSON string into a unicode object");
}

CLEANUP:
Py_XDECREF(initresult);
if (new_repr_str) {
free(new_repr_str);
}
// If an error occurred, tell Python.
if (err.code != AEROSPIKE_OK) {
raise_exception(&err);
if (new_repr_str) {
free(new_repr_str);
}
return NULL;
}

py_return = PyUnicode_FromString(new_repr_str);
Py_XDECREF(initresult);
free(new_repr_str);
return py_return;
}

Expand Down
7 changes: 7 additions & 0 deletions src/main/serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,13 @@ void execute_user_callback(user_serializer_callback *user_callback_info,
char *bytes_val_p = (char *)bytes_pointer->value;
py_value =
PyUnicode_FromStringAndSize(bytes_val_p, as_bytes_size(*bytes));
if (!py_value) {
PyErr_Clear();
as_error_update(error_p, AEROSPIKE_ERR_CLIENT,
"Failed to convert bytes to Python unicode object");
Py_DECREF(py_arglist);
goto CLEANUP;
}
if (PyTuple_SetItem(py_arglist, 0, py_value) != 0) {
Py_DECREF(py_arglist);
goto CLEANUP;
Expand Down
Loading