[asterisk-commits] seanbright: branch 10 r374135 - in /branches/10: apps/ include/asterisk/ main...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Oct 1 12:52:41 CDT 2012
Author: seanbright
Date: Mon Oct 1 12:52:38 2012
New Revision: 374135
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=374135
Log:
Use ast_copy_string instead of strncpy to guarantee a NUL terminated string.
........
Merged revisions 374132 from http://svn.asterisk.org/svn/asterisk/branches/10
Modified:
branches/10/apps/app_queue.c
branches/10/include/asterisk/astdb.h
branches/10/main/db.c
branches/10/tests/test_db.c
Modified: branches/10/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/apps/app_queue.c?view=diff&rev=374135&r1=374134&r2=374135
==============================================================================
--- branches/10/apps/app_queue.c (original)
+++ branches/10/apps/app_queue.c Mon Oct 1 12:52:38 2012
@@ -927,8 +927,6 @@
/*! \brief Persistent Members astdb family */
static const char * const pm_family = "Queue/PersistentMembers";
-/* The maximum length of each persistent member queue database entry */
-#define PM_MAX_LEN 8192
/*! \brief queues.conf [general] option */
static int queue_persistent_members = 0;
@@ -5311,15 +5309,18 @@
static void dump_queue_members(struct call_queue *pm_queue)
{
struct member *cur_member;
- char value[PM_MAX_LEN];
- int value_len = 0;
- int res;
+ struct ast_str *value;
struct ao2_iterator mem_iter;
- memset(value, 0, sizeof(value));
-
- if (!pm_queue)
+ if (!pm_queue) {
return;
+ }
+
+ /* 4K is a reasonable default for most applications, but we grow to
+ * accommodate more if necessary. */
+ if (!(value = ast_str_create(4096))) {
+ return;
+ }
mem_iter = ao2_iterator_init(pm_queue->members, 0);
while ((cur_member = ao2_iterator_next(&mem_iter))) {
@@ -5328,25 +5329,27 @@
continue;
}
- res = snprintf(value + value_len, sizeof(value) - value_len, "%s%s;%d;%d;%s;%s",
- value_len ? "|" : "", cur_member->interface, cur_member->penalty, cur_member->paused, cur_member->membername, cur_member->state_interface);
+ ast_str_append(&value, 0, "%s%s;%d;%d;%s;%s",
+ ast_str_strlen(value) ? "|" : "",
+ cur_member->interface,
+ cur_member->penalty,
+ cur_member->paused,
+ cur_member->membername,
+ cur_member->state_interface);
ao2_ref(cur_member, -1);
-
- if (res != strlen(value + value_len)) {
- ast_log(LOG_WARNING, "Could not create persistent member string, out of space\n");
- break;
- }
- value_len += res;
}
ao2_iterator_destroy(&mem_iter);
-
- if (value_len && !cur_member) {
- if (ast_db_put(pm_family, pm_queue->name, value))
+
+ if (ast_str_strlen(value) && !cur_member) {
+ if (ast_db_put(pm_family, pm_queue->name, ast_str_buffer(value)))
ast_log(LOG_WARNING, "failed to create persistent dynamic entry!\n");
- } else
+ } else {
/* Delete the entry if the queue is empty or there is an error */
ast_db_del(pm_family, pm_queue->name);
+ }
+
+ ast_free(value);
}
/*! \brief Remove member from queue
@@ -5678,7 +5681,7 @@
struct ast_db_entry *db_tree;
struct ast_db_entry *entry;
struct call_queue *cur_queue;
- char queue_data[PM_MAX_LEN];
+ char *queue_data;
/* Each key in 'pm_family' is the name of a queue */
db_tree = ast_db_gettree(pm_family, NULL);
@@ -5704,7 +5707,7 @@
continue;
}
- if (ast_db_get(pm_family, queue_name, queue_data, PM_MAX_LEN)) {
+ if (ast_db_get_allocated(pm_family, queue_name, &queue_data)) {
queue_t_unref(cur_queue, "Expire reload reference");
continue;
}
@@ -5748,6 +5751,7 @@
}
}
queue_t_unref(cur_queue, "Expire reload reference");
+ ast_free(queue_data);
}
if (db_tree) {
Modified: branches/10/include/asterisk/astdb.h
URL: http://svnview.digium.com/svn/asterisk/branches/10/include/asterisk/astdb.h?view=diff&rev=374135&r1=374134&r2=374135
==============================================================================
--- branches/10/include/asterisk/astdb.h (original)
+++ branches/10/include/asterisk/astdb.h Mon Oct 1 12:52:38 2012
@@ -36,6 +36,17 @@
/*!\brief Get key value specified by family/key */
int ast_db_get(const char *family, const char *key, char *out, int outlen);
+/*!\brief Get key value specified by family/key as a heap allocated string.
+ *
+ * Given a \a family and \a key, sets \a out to a pointer to a heap
+ * allocated string. In the event of an error, \a out will be set to
+ * NULL. The string must be freed by calling ast_free().
+ *
+ * \retval -1 An error occurred
+ * \retval 0 Success
+ */
+int ast_db_get_allocated(const char *family, const char *key, char **out);
+
/*!\brief Store value addressed by family/key */
int ast_db_put(const char *family, const char *key, const char *value);
Modified: branches/10/main/db.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/main/db.c?view=diff&rev=374135&r1=374134&r2=374135
==============================================================================
--- branches/10/main/db.c (original)
+++ branches/10/main/db.c Mon Oct 1 12:52:38 2012
@@ -307,7 +307,21 @@
return res;
}
-int ast_db_get(const char *family, const char *key, char *value, int valuelen)
+/*!
+ * \internal
+ * \brief Get key value specified by family/key.
+ *
+ * Gets the value associated with the specified \a family and \a key, and
+ * stores it, either into the fixed sized buffer specified by \a buffer
+ * and \a bufferlen, or as a heap allocated string if \a bufferlen is -1.
+ *
+ * \note If \a bufferlen is -1, \a buffer points to heap allocated memory
+ * and must be freed by calling ast_free().
+ *
+ * \retval -1 An error occurred
+ * \retval 0 Success
+ */
+static int db_get_common(const char *family, const char *key, char **buffer, int bufferlen)
{
const unsigned char *result;
char fullkey[MAX_DB_FIELD];
@@ -332,12 +346,35 @@
ast_log(LOG_WARNING, "Couldn't get value\n");
res = -1;
} else {
- ast_copy_string(value, (const char *) result, valuelen);
+ const char *value = (const char *) result;
+
+ if (bufferlen == -1) {
+ *buffer = ast_strdup(value);
+ } else {
+ ast_copy_string(*buffer, value, bufferlen);
+ }
}
sqlite3_reset(get_stmt);
ast_mutex_unlock(&dblock);
return res;
+}
+
+int ast_db_get(const char *family, const char *key, char *value, int valuelen)
+{
+ ast_assert(value != NULL);
+
+ /* Make sure we initialize */
+ value[0] = 0;
+
+ return db_get_common(family, key, &value, valuelen);
+}
+
+int ast_db_get_allocated(const char *family, const char *key, char **out)
+{
+ *out = NULL;
+
+ return db_get_common(family, key, out, -1);
}
int ast_db_del(const char *family, const char *key)
Modified: branches/10/tests/test_db.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/tests/test_db.c?view=diff&rev=374135&r1=374134&r2=374135
==============================================================================
--- branches/10/tests/test_db.c (original)
+++ branches/10/tests/test_db.c Mon Oct 1 12:52:38 2012
@@ -232,11 +232,70 @@
return res;
}
+
+AST_TEST_DEFINE(put_get_long)
+{
+ int res = AST_TEST_PASS;
+ struct ast_str *s;
+ int i, j;
+
+#define STR_FILL_32 "abcdefghijklmnopqrstuvwxyz123456"
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "put_get_long";
+ info->category = "/main/astdb/";
+ info->summary = "ast_db_(put|get_allocated) unit test";
+ info->description =
+ "Ensures that the ast_db_put and ast_db_get_allocated functions work";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(s = ast_str_create(4096))) {
+ return AST_TEST_FAIL;
+ }
+
+ for (i = 1024; i <= 1024 * 1024 * 8; i *= 2) {
+ char *out = NULL;
+
+ ast_str_reset(s);
+
+ for (j = 0; j < i; j += sizeof(STR_FILL_32) - 1) {
+ ast_str_append(&s, 0, "%s", STR_FILL_32);
+ }
+
+ if (ast_db_put("astdbtest", "long", ast_str_buffer(s))) {
+ ast_test_status_update(test, "Failed to put value of %zu bytes\n", ast_str_strlen(s));
+ res = AST_TEST_FAIL;
+ } else if (ast_db_get_allocated("astdbtest", "long", &out)) {
+ ast_test_status_update(test, "Failed to get value of %zu bytes\n", ast_str_strlen(s));
+ res = AST_TEST_FAIL;
+ } else if (strcmp(ast_str_buffer(s), out)) {
+ ast_test_status_update(test, "Failed to match value of %zu bytes\n", ast_str_strlen(s));
+ res = AST_TEST_FAIL;
+ } else if (ast_db_del("astdbtest", "long")) {
+ ast_test_status_update(test, "Failed to delete astdbtest/long\n");
+ res = AST_TEST_FAIL;
+ }
+
+ if (out) {
+ ast_free(out);
+ }
+ }
+
+ ast_free(s);
+
+ return res;
+}
+
static int unload_module(void)
{
AST_TEST_UNREGISTER(put_get_del);
AST_TEST_UNREGISTER(gettree_deltree);
AST_TEST_UNREGISTER(perftest);
+ AST_TEST_UNREGISTER(put_get_long);
return 0;
}
@@ -245,6 +304,7 @@
AST_TEST_REGISTER(put_get_del);
AST_TEST_REGISTER(gettree_deltree);
AST_TEST_REGISTER(perftest);
+ AST_TEST_REGISTER(put_get_long);
return AST_MODULE_LOAD_SUCCESS;
}
More information about the asterisk-commits
mailing list