mirror of https://github.com/sipwise/kamailio.git
When iterating through entry keys while searching for proper key, reset manual key count when going to next entry key to avoid writing beyond manaul key array. Also fix memleak when deleting via table scan, where scanned keys and manual keys were not properly deleted. Also fix memleak when deleting in general, where type keys were not properly deleted. Change-Id: I60bb57ec95d863ace89a927341a9031bf67723adchanges/86/21686/13
parent
fe695b324a
commit
a3b1703991
@ -1 +1,3 @@
|
||||
.pc
|
||||
*~
|
||||
.*.swp
|
||||
|
||||
@ -0,0 +1,189 @@
|
||||
Index: kamailio/src/modules/db_redis/redis_dbase.c
|
||||
===================================================================
|
||||
--- kamailio.orig/src/modules/db_redis/redis_dbase.c
|
||||
+++ kamailio/src/modules/db_redis/redis_dbase.c
|
||||
@@ -236,6 +236,7 @@ static int db_redis_build_entry_manual_k
|
||||
for (key = table->entry_keys; key; key = key->next) {
|
||||
int subkey_found = 0;
|
||||
int i;
|
||||
+ *manual_key_count = 0;
|
||||
LM_DBG("checking for existence of entry key '%.*s' in query to get manual key\n",
|
||||
key->key.len, key->key.s);
|
||||
for (i = 0; i < _n; ++i) {
|
||||
@@ -1080,7 +1081,12 @@ static int db_redis_perform_query(const
|
||||
RES_COL_N(*_r) = _nc;
|
||||
|
||||
if (!(*keys_count) && do_table_scan) {
|
||||
- LM_DBG("performing full table scan\n");
|
||||
+ LM_WARN("performing full table scan on table '%.*s' while performing query\n",
|
||||
+ CON_TABLE(_h)->len, CON_TABLE(_h)->s);
|
||||
+ for(i = 0; i < _n; ++i) {
|
||||
+ LM_WARN(" scan key %d is '%.*s'\n",
|
||||
+ i, _k[i]->len, _k[i]->s);
|
||||
+ }
|
||||
if (db_redis_scan_query_keys(con, CON_TABLE(_h), _k, _n,
|
||||
keys, keys_count,
|
||||
manual_keys, manual_keys_count) != 0) {
|
||||
@@ -1119,7 +1125,7 @@ static int db_redis_perform_query(const
|
||||
LM_ERR("Failed to append redis command\n");
|
||||
goto error;
|
||||
}
|
||||
- tmp = db_redis_key_unshift(&query_v);
|
||||
+ tmp = db_redis_key_shift(&query_v);
|
||||
if (tmp)
|
||||
db_redis_key_free(&tmp);
|
||||
|
||||
@@ -1232,10 +1238,10 @@ error:
|
||||
|
||||
static int db_redis_perform_delete(const db1_con_t* _h, km_redis_con_t *con, const db_key_t* _k,
|
||||
const db_val_t* _v, const db_op_t *_op, const int _n,
|
||||
- redis_key_t *keys, int keys_count,
|
||||
- int *manual_keys, int manual_keys_count, int do_table_scan) {
|
||||
+ redis_key_t **keys, int *keys_count,
|
||||
+ int **manual_keys, int *manual_keys_count, int do_table_scan) {
|
||||
|
||||
- int j = 0;
|
||||
+ int i = 0, j = 0;
|
||||
redis_key_t *k = NULL;
|
||||
int type_keys_count = 0;
|
||||
int all_type_keys_count = 0;
|
||||
@@ -1249,11 +1255,16 @@ static int db_redis_perform_delete(const
|
||||
db_key_t *db_keys = NULL;
|
||||
redis_key_t *type_key;
|
||||
|
||||
- if (!keys_count && do_table_scan) {
|
||||
- LM_DBG("performing full table scan\n");
|
||||
+ if (!*keys_count && do_table_scan) {
|
||||
+ LM_WARN("performing full table scan on table '%.*s' while performing delete\n",
|
||||
+ CON_TABLE(_h)->len, CON_TABLE(_h)->s);
|
||||
+ for(i = 0; i < _n; ++i) {
|
||||
+ LM_WARN(" scan key %d is '%.*s'\n",
|
||||
+ i, _k[i]->len, _k[i]->s);
|
||||
+ }
|
||||
if (db_redis_scan_query_keys(con, CON_TABLE(_h), _k, _n,
|
||||
- &keys, &keys_count,
|
||||
- &manual_keys, &manual_keys_count) != 0) {
|
||||
+ keys, keys_count,
|
||||
+ manual_keys, manual_keys_count) != 0) {
|
||||
LM_ERR("failed to scan query keys\n");
|
||||
goto error;
|
||||
}
|
||||
@@ -1270,7 +1281,7 @@ static int db_redis_perform_delete(const
|
||||
}
|
||||
|
||||
LM_DBG("delete all keys\n");
|
||||
- for (k = keys; k; k = k->next) {
|
||||
+ for (k = *keys; k; k = k->next) {
|
||||
redis_key_t *all_type_key;
|
||||
str *key = &k->key;
|
||||
redis_key_t *tmp = NULL;
|
||||
@@ -1292,10 +1303,11 @@ static int db_redis_perform_delete(const
|
||||
if (reply->integer == 0) {
|
||||
LM_DBG("key does not exist in redis, skip deleting\n");
|
||||
db_redis_free_reply(&reply);
|
||||
+ db_redis_key_free(&query_v);
|
||||
continue;
|
||||
}
|
||||
db_redis_free_reply(&reply);
|
||||
- tmp = db_redis_key_unshift(&query_v);
|
||||
+ tmp = db_redis_key_shift(&query_v);
|
||||
if (tmp)
|
||||
db_redis_key_free(&tmp);
|
||||
|
||||
@@ -1305,8 +1317,8 @@ static int db_redis_perform_delete(const
|
||||
}
|
||||
|
||||
// add all manual keys to query
|
||||
- for (j = 0; j < manual_keys_count; ++j) {
|
||||
- int idx = manual_keys[j];
|
||||
+ for (j = 0; j < *manual_keys_count; ++j) {
|
||||
+ int idx = (*manual_keys)[j];
|
||||
str *col = _k[idx];
|
||||
|
||||
if (db_redis_key_add_str(&query_v, col) != 0) {
|
||||
@@ -1331,8 +1343,8 @@ static int db_redis_perform_delete(const
|
||||
// manually filter non-matching replies
|
||||
row_match = 1;
|
||||
for (col = 0; col < reply->elements; ++col) {
|
||||
- if (col < manual_keys_count) {
|
||||
- int idx = manual_keys[col];
|
||||
+ if (col < *manual_keys_count) {
|
||||
+ int idx = (*manual_keys)[col];
|
||||
db_key_t k = _k[idx];
|
||||
db_val_t v = _v[idx];
|
||||
db_op_t o = _op[idx];
|
||||
@@ -1370,7 +1382,7 @@ static int db_redis_perform_delete(const
|
||||
for (j = 0, all_type_key = all_type_keys; all_type_key; ++j, all_type_key = all_type_key->next) {
|
||||
db_val_t *v = &(db_vals[j]);
|
||||
str *key = &all_type_key->key;
|
||||
- char *value = reply->element[manual_keys_count + j]->str;
|
||||
+ char *value = reply->element[*manual_keys_count + j]->str;
|
||||
int coltype = db_redis_schema_get_column_type(con, CON_TABLE(_h), key);
|
||||
if (value == NULL) {
|
||||
VAL_NULL(v) = 1;
|
||||
@@ -1422,11 +1434,9 @@ static int db_redis_perform_delete(const
|
||||
db_redis_check_reply(con, reply, error);
|
||||
db_redis_free_reply(&reply);
|
||||
}
|
||||
-
|
||||
- //db_redis_key_free(&type_keys);
|
||||
LM_DBG("done with loop '%.*s'\n", k->key.len, k->key.s);
|
||||
+ db_redis_key_free(&type_keys);
|
||||
}
|
||||
- db_redis_key_free(&type_keys);
|
||||
db_redis_key_free(&all_type_keys);
|
||||
db_redis_key_free(&query_v);
|
||||
|
||||
@@ -1461,7 +1471,12 @@ static int db_redis_perform_update(const
|
||||
size_t col;
|
||||
|
||||
if (!(*keys_count) && do_table_scan) {
|
||||
- LM_DBG("performing full table scan\n");
|
||||
+ LM_WARN("performing full table scan on table '%.*s' while performing update\n",
|
||||
+ CON_TABLE(_h)->len, CON_TABLE(_h)->s);
|
||||
+ for(i = 0; i < _n; ++i) {
|
||||
+ LM_WARN(" scan key %d is '%.*s'\n",
|
||||
+ i, _k[i]->len, _k[i]->s);
|
||||
+ }
|
||||
if (db_redis_scan_query_keys(con, CON_TABLE(_h), _k, _n,
|
||||
keys, keys_count,
|
||||
manual_keys, manual_keys_count) != 0) {
|
||||
@@ -2027,7 +2042,7 @@ int db_redis_delete(const db1_con_t* _h,
|
||||
}
|
||||
|
||||
if (db_redis_perform_delete(_h, con, _k, _v, query_ops, _n,
|
||||
- keys, keys_count, manual_keys, manual_keys_count, do_table_scan) != 0) {
|
||||
+ &keys, &keys_count, &manual_keys, &manual_keys_count, do_table_scan) != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
Index: kamailio/src/modules/db_redis/redis_table.c
|
||||
===================================================================
|
||||
--- kamailio.orig/src/modules/db_redis/redis_table.c
|
||||
+++ kamailio/src/modules/db_redis/redis_table.c
|
||||
@@ -103,7 +103,7 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
-redis_key_t * db_redis_key_unshift(redis_key_t **list) {
|
||||
+redis_key_t * db_redis_key_shift(redis_key_t **list) {
|
||||
redis_key_t *k;
|
||||
|
||||
k = *list;
|
||||
Index: kamailio/src/modules/db_redis/redis_table.h
|
||||
===================================================================
|
||||
--- kamailio.orig/src/modules/db_redis/redis_table.h
|
||||
+++ kamailio/src/modules/db_redis/redis_table.h
|
||||
@@ -58,9 +58,9 @@ int db_redis_key_add_string(redis_key_t*
|
||||
int db_redis_key_add_str(redis_key_t **list, const str* entry);
|
||||
int db_redis_key_prepend_string(redis_key_t **list, const char* entry, int len);
|
||||
int db_redis_key_list2arr(redis_key_t *list, char ***arr);
|
||||
-redis_key_t * db_redis_key_unshift(redis_key_t **list);
|
||||
+redis_key_t * db_redis_key_shift(redis_key_t **list);
|
||||
void db_redis_key_free(redis_key_t **list);
|
||||
|
||||
int db_redis_keys_spec(char *spec);
|
||||
|
||||
-#endif /* _REDIS_TABLE_H_ */
|
||||
\ No newline at end of file
|
||||
+#endif /* _REDIS_TABLE_H_ */
|
||||
Loading…
Reference in new issue