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

* MDF [core/sp/supplemental] Handle the case when nni_zalloc fails #592

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/core/aio.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,10 @@ nni_aio_sys_init(void)

nni_aio_expire_q_list =
nni_zalloc(sizeof(nni_aio_expire_q *) * num_thr);
if (nni_aio_expire_q_list == NULL) {
return NNG_ENOMEM;
}

nni_aio_expire_q_cnt = num_thr;
for (int i = 0; i < num_thr; i++) {
nni_aio_expire_q *eq;
Expand All @@ -828,4 +832,4 @@ nni_aio_sys_init(void)
return (0);
}

// NANOMQ APIs
// NANOMQ APIs
5 changes: 5 additions & 0 deletions src/sp/protocol/mqtt/mqtt_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,11 @@ bool
topic_filtern(const char *origin, const char *input, size_t n)
{
char *buff = nni_zalloc(n + 1);
if (buff == NULL) {
log_error("Cannot allocate memory");
return false;
}

strncpy(buff, input, n);
bool res = false;
size_t len = strlen(origin);
Expand Down
8 changes: 8 additions & 0 deletions src/supplemental/mqtt/mqtt_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -3465,6 +3465,10 @@ property *
property_alloc(void)
{
property *p = nni_zalloc(sizeof(property));
if (p == NULL) {
log_error("Cannot allocate memory");
return NULL;
}
p->next = NULL;
return p;
}
Expand Down Expand Up @@ -4230,6 +4234,10 @@ nni_mqtt_msgack_encode(nng_msg *msg, uint16_t packet_id, uint8_t reason_code,
property *prop, uint8_t proto_ver)
{
uint8_t *rbuf = nni_zalloc(2);
if (rbuf == NULL) {
log_error("Cannot allocate memory");
return MQTT_ERR_NOMEM;
}
NNI_PUT16(rbuf, packet_id);
nni_msg_clear(msg);
nni_msg_append(msg, rbuf, 2);
Expand Down
12 changes: 12 additions & 0 deletions src/supplemental/mqtt/mqtt_qos_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,10 @@ nni_mqtt_qos_db_find_retain(sqlite3 *db, const char *topic_pattern)

size_t full_sql_sz = strlen(sql) + strlen(topic_str) + 10;
char * full_sql = nni_zalloc(full_sql_sz);
if (full_sql == NULL) {
log_error("Cannot allocate memory");
return NULL;
}
snprintf(full_sql, full_sql_sz, "%s '%s'", sql, topic_str);

sqlite3_stmt *stmt;
Expand Down Expand Up @@ -1265,6 +1269,10 @@ nni_mqtt_msg_serialize(nni_msg *msg, size_t *out_len, uint8_t proto_ver)
// time: nni_time(uint64)
// aio: address value
uint8_t *bytes = nng_zalloc(len);
if (bytes == NULL) {
log_error("Cannot allocate memory");
return NULL;
}

struct pos_buf buf = { .curpos = &bytes[0], .endpos = &bytes[len] };

Expand Down Expand Up @@ -1372,6 +1380,10 @@ nni_msg_serialize(nni_msg *msg, size_t *out_len)
// body: body_len(uint32) + body(body_len)
// time: nni_time(uint64)
uint8_t *bytes = nng_zalloc(len);
if (bytes == NULL) {
log_error("Cannot allocate memory");
return NULL;
}

struct pos_buf buf = { .curpos = &bytes[0], .endpos = &bytes[len] };

Expand Down
30 changes: 29 additions & 1 deletion src/supplemental/nanolib/acl_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ acl_parse_str_array_item(cJSON *obj, const char *key, acl_rule_ct *content)
content->type = ACL_RULE_STRING_ARRAY;
content->count = size;
content->value.str_array = nni_zalloc(size * sizeof(char *));
if (content->value.str_array == NULL) {
log_error("Cannot allocate memory");
return false;
}

for (int i = 0; i < size; i++) {
cJSON *item = cJSON_GetArrayItem(array, i);
if (cJSON_IsString(item)) {
Expand All @@ -48,6 +53,10 @@ bool
acl_parse_json_rule(cJSON *obj, size_t id, acl_rule **rule)
{
acl_rule *r = nni_zalloc(sizeof(acl_rule));
if (r == NULL) {
log_error("Cannot allocate memory");
return false;
}

r->id = id;
r->action = ACL_ALL;
Expand Down Expand Up @@ -90,6 +99,11 @@ acl_parse_json_rule(cJSON *obj, size_t id, acl_rule **rule)
int size = cJSON_GetArraySize(topics);
r->topic_count = size;
r->topics = nni_zalloc(size * sizeof(char *));
if (r->topics == NULL) {
log_error("Cannot allocate memory");
goto err;
}

for (int i = 0; i < size; i++) {
cJSON *item = cJSON_GetArrayItem(topics, i);
if (cJSON_IsString(item)) {
Expand Down Expand Up @@ -133,11 +147,21 @@ acl_parse_json_rule(cJSON *obj, size_t id, acl_rule **rule)
int size = cJSON_GetArraySize(op);
acl_sub_rules_array *rule_list = &r->rule_ct.array;
rule_list->rules = nni_zalloc(sizeof(acl_sub_rule *) * size);
if (rule_list->rules == NULL) {
log_error("Cannot allocate memory");
goto err;
}

rule_list->count = 0;
for (int i = 0; i < size; i++) {
cJSON * sub_item = cJSON_GetArrayItem(op, i);
acl_sub_rule *sub_rule =
nni_zalloc(sizeof(acl_sub_rule));
if (sub_rule == NULL) {
log_error("Cannot allocate memory");
nni_free(rule_list->rules, sizeof(acl_sub_rule *) * size);
goto err;
}

if (acl_parse_str_item(
sub_item, "clientid", &sub_rule->rule_ct)) {
Expand Down Expand Up @@ -166,6 +190,10 @@ acl_parse_json_rule(cJSON *obj, size_t id, acl_rule **rule)
return true;

err:
if (r->topics != NULL) {
nni_free(r->topics, cJSON_GetArraySize(topics) * sizeof(char *));
}

nni_free(r, sizeof(acl_rule));
return false;
}
Expand Down Expand Up @@ -402,4 +430,4 @@ print_acl_conf(conf_acl *acl)
log_info("");
}
}
}
}
45 changes: 44 additions & 1 deletion src/supplemental/nanolib/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ conf_update_var2(const char *fpath, const char *key1, const char *key2,
{
size_t sz = strlen(key1) + strlen(key2) + strlen(key3) + 2;
char * key = nni_zalloc(sz);
if (key == NULL) {
log_error("Cannot allocate memory");
return;
}
snprintf(key, sz, "%s%s%s", key1, key2, key3);
conf_update_var(fpath, key, type, var);
nng_free(key, sz);
Expand Down Expand Up @@ -232,6 +236,10 @@ conf_update2(const char *fpath, const char *key1, const char *key2,
{
size_t sz = strlen(key1) + strlen(key2) + strlen(key3) + 2;
char * key = nni_zalloc(sz);
if (key == NULL) {
log_error("Cannot allocate memory");
return;
}
snprintf(key, sz, "%s%s%s", key1, key2, key3);
conf_update(fpath, key, value);
nng_free(key, sz);
Expand All @@ -258,8 +266,19 @@ get_conf_value(char *line, size_t len, const char *key)
}

char *prefix = nni_zalloc(len);
char *trim = strtrim_head_tail(line, len);
if (prefix == NULL) {
log_error("Cannot allocate memory");
return NULL;
}

char *value = nni_zalloc(len);
if (value == NULL) {
nni_free(prefix, len);
log_error("Cannot allocate memory");
return NULL;
}

char *trim = strtrim_head_tail(line, len);
int match = sscanf(trim, "%[^=]=%[^\n]s", prefix, value);
char *res = NULL;
nni_strfree(trim);
Expand All @@ -281,6 +300,10 @@ get_conf_value_with_prefix(
{
size_t sz = strlen(prefix) + strlen(key) + 2;
char * str = nni_zalloc(sz);
if (str == NULL) {
log_error("Cannot allocate memory");
return NULL;
}
snprintf(str, sz, "%s%s", prefix, key);
char *value = get_conf_value(line, len, str);
free(str);
Expand All @@ -296,6 +319,10 @@ get_conf_value_with_prefix2(char *line, size_t len, const char *prefix,
size_t sz = prefix_sz + name_sz + strlen(key) + 2;

char *str = nni_zalloc(sz);
if (str == NULL) {
log_error("Cannot allocate memory");
return NULL;
}
snprintf(str, sz, "%s%s%s", prefix, name ? name : "", key ? key : "");
char *value = get_conf_value(line, len, str);
free(str);
Expand Down Expand Up @@ -1750,6 +1777,10 @@ conf_rule_fdb_parse(conf_rule *cr, char *path)
size_t sz = 0;
FILE * fp;
rule_key *rk = (rule_key *) nni_zalloc(sizeof(rule_key));
if (rk == NULL) {
log_error("Cannot allocate memory");
return;
}
memset(rk, 0, sizeof(rule_key));

if (NULL == (fp = fopen(path, "r"))) {
Expand Down Expand Up @@ -2464,6 +2495,10 @@ get_bridge_group_names(const char *path, const char *prefix, size_t *count)

size_t len = strlen(prefix) + 34;
char * pattern = nni_zalloc(len);
if (pattern == NULL) {
log_error("Cannot allocate memory");
return NULL;
}
snprintf(
pattern, len, "%sbridge.mqtt.%%[^.].%%*[^=]=%%*[^\n]", prefix);

Expand Down Expand Up @@ -2699,6 +2734,10 @@ conf_bridge_content_parse(conf *nanomq_conf, conf_bridge *bridge,
// 1. parse sqlite config from nanomq_bridge.conf
size_t sz = strlen(prefix) + 15;
char * key = nni_zalloc(sz);
if (key == NULL) {
log_error("Cannot allocate memory");
return;
}
snprintf(key, sz, "%sbridge.sqlite", prefix);
conf_sqlite_parse(&bridge->sqlite, path, "bridge.sqlite");
nni_strfree(key);
Expand Down Expand Up @@ -3260,6 +3299,10 @@ conf_parse_http_headers(

size_t len = strlen(key_prefix) + 23;
char * pattern = nni_zalloc(len);
if (pattern == NULL) {
log_error("Cannot allocate memory");
return NULL;
}
snprintf(pattern, len, "%s.headers.%%[^=]=%%[^\n]", key_prefix);

size_t header_count = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/supplemental/nanolib/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ file_rotation(FILE *fp, conf_log *config)

size_t log_name_len = strlen(config->abs_path) + 20;
char * log_name = nni_zalloc(log_name_len);
if (log_name == NULL) {
return;
}
snprintf(
log_name, log_name_len, "%s.%lu", config->file, index);
char *backup_log_path =
Expand Down
41 changes: 41 additions & 0 deletions src/supplemental/nanolib/mqtt_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,23 @@ topic_parse(char *topic)

// Here we will get (cnt + 1) memory, one for NULL end
char **topic_queue = (char **) nni_zalloc(sizeof(char *) * (cnt + 1));
if (topic_queue == NULL) {
log_error("Cannot allocate memory");
return NULL;
}

while ((pos = strchr(b_pos, '/')) != NULL) {

len = pos - b_pos + 1;
topic_queue[row] = (char *) nni_zalloc(sizeof(char) * len);
if (topic_queue[row] == NULL) {
for (int i = 0; i < row; i++) {
nni_strfree(topic_queue[i]);
}
nni_free(topic_queue, sizeof(char *) * (cnt + 1));
log_error("Cannot allocate memory");
return NULL;
}
memcpy(topic_queue[row], b_pos, (len - 1));
topic_queue[row][len - 1] = '\0';
b_pos = pos + 1;
Expand All @@ -149,6 +161,15 @@ topic_parse(char *topic)
len = strlen(b_pos);

topic_queue[row] = (char *) nni_zalloc(sizeof(char) * (len + 1));
if (topic_queue[row] == NULL) {
for (int i = 0; i < row; i++) {
nni_strfree(topic_queue[i]);
}
nni_free(topic_queue, sizeof(char *) * (cnt + 1));
log_error("Cannot allocate memory");
return NULL;
}

memcpy(topic_queue[row], b_pos, (len));
topic_queue[row][len] = '\0';
topic_queue[++row] = NULL;
Expand Down Expand Up @@ -199,6 +220,14 @@ dbtree_get_tree(dbtree *db, void *(*cb)(uint32_t pipe_id))
dbtree_info **ret_line_ping = NULL;
for (size_t i = 0; i < cvector_size(nodes); i++) {
dbtree_info *vn = nni_zalloc(sizeof(dbtree_info));
if (vn == NULL) {
for (int j = 0; j < cvector_size(ret_line_ping); j++) {
nni_free(ret_line_ping[j], sizeof(dbtree_info));
}
cvector_free(ret_line_ping);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check that using cvector_free to release memory is correct or not ? @JaylinYu

Copy link
Member

@JaylinYu JaylinYu Jun 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesnt need this?
@lee-emqx

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you noticed any issues with cvector_free?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had any issues yet.
Just curious about the rationality of this approach :P

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When dealing with pointer arrays such as ret_line_ping, it's important to remember to free its members before freeing the array itself (use cvector_free). This ensures that memory is properly deallocated and avoids any potential issues.

Copy link
Contributor Author

@RanMaoyi RanMaoyi Jun 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just looked at the cvector_free function and did not free all the members, so I added the following code. @JaylinYu @lee-emqx

for (int j = 0; j < cvector_size(ret_line_ping); j++) {
	nni_free(ret_line_ping[j], sizeof(dbtree_info));
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vn's member also need :P

log_error("Cannot allocate memory");
return NULL;
}
vn->clients = NULL;
if (cb) {
for (size_t j = 0;
Expand Down Expand Up @@ -228,6 +257,14 @@ dbtree_get_tree(dbtree *db, void *(*cb)(uint32_t pipe_id))
dbtree_info **ret_line_pang = NULL;
for (size_t i = 0; i < cvector_size(nodes_t); i++) {
dbtree_info *vn = nni_zalloc(sizeof(dbtree_info));
if (vn == NULL) {
for (int j = 0; j < cvector_size(ret_line_pang); j++) {
nni_free(ret_line_pang[j], sizeof(dbtree_info));
}
cvector_free(ret_line_pang);
log_error("Cannot allocate memory");
return NULL;
}
vn->clients = NULL;
if (cb) {
for (size_t j = 0;
Expand Down Expand Up @@ -424,6 +461,10 @@ void
dbtree_create(dbtree **db)
{
*db = (dbtree *) nni_zalloc(sizeof(dbtree));
if (*db == NULL) {
log_error("Cannot allocate memory");
return;
}
memset(*db, 0, sizeof(dbtree));

dbtree_node *node = dbtree_node_new("\0");
Expand Down
4 changes: 4 additions & 0 deletions src/supplemental/nanolib/rule.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,10 @@ parse_where(char *where, rule *info)
char *p_b = where;

info->filter = (char **) nni_zalloc(sizeof(char *) * 8);
if (info->filter == NULL) {
log_error("Cannot allocate memory");
return NNG_ENOMEM;
}
memset(info->filter, 0, 8 * sizeof(char *));

while ((p = nng_strcasestr(p, "and"))) {
Expand Down