summaryrefslogtreecommitdiff
path: root/funcs
diff options
context:
space:
mode:
authorScott Griepentrog <sgriepentrog@digium.com>2014-01-02 19:38:09 +0000
committerScott Griepentrog <sgriepentrog@digium.com>2014-01-02 19:38:09 +0000
commitff02c8e254f4836a66363b981ad7d956fbaaf565 (patch)
tree9feb41162c4068444b5707b4e9f0c67bcb782c59 /funcs
parent821ab5138118b36c95f80ea0a54c4b6457a4f572 (diff)
func_strings: use memmove to prevent overlapping memory on strcpy
When calling REPLACE() with an empty replace-char argument, strcpy is used to overwrite the the matching <find-char>. However as the src and dest arguments to strcpy must not overlap, it causes other parts of the string to be overwritten with adjacent characters and the result is mangled. Patch replaces call to strcpy with memmove and adds a test suite case for REPLACE. (closes issue ASTERISK-22910) Reported by: Gareth Palmer Review: https://reviewboard.asterisk.org/r/3083/ Patches: func_strings.patch uploaded by Gareth Palmer (license 5169) ........ Merged revisions 404674 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 404675 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 404676 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@404677 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'funcs')
-rw-r--r--funcs/func_strings.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/funcs/func_strings.c b/funcs/func_strings.c
index 1bd07d652..3dd0168f1 100644
--- a/funcs/func_strings.c
+++ b/funcs/func_strings.c
@@ -841,8 +841,7 @@ static int replace(struct ast_channel *chan, const char *cmd, char *data, struct
* directly there */
if (strchr(find, *strptr)) {
if (ast_strlen_zero(replace)) {
- /* Remove character */
- strcpy(strptr, strptr + 1); /* SAFE */
+ memmove(strptr, strptr + 1, strlen(strptr + 1) + 1);
strptr--;
} else {
/* Replace character */
@@ -1726,6 +1725,76 @@ AST_TEST_DEFINE(test_FIELDNUM)
return res;
}
+AST_TEST_DEFINE(test_REPLACE)
+{
+ int i, res = AST_TEST_PASS;
+ struct ast_channel *chan;
+ struct ast_str *str;
+ char expression[256];
+ struct {
+ const char *test_string;
+ const char *find_chars;
+ const char *replace_char;
+ const char *expected;
+ } test_args[] = {
+ {"abc,def", "\\,", "-", "abc-def"},
+ {"abc,abc", "bc", "a", "aaa,aaa"},
+ {"abc,def", "x", "?", "abc,def"},
+ {"abc,def", "\\,", "", "abcdef"}
+ };
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "func_REPLACE_test";
+ info->category = "/funcs/func_strings/";
+ info->summary = "Test REPLACE function";
+ info->description = "Verify REPLACE behavior";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(chan = ast_dummy_channel_alloc())) {
+ ast_test_status_update(test, "Unable to allocate dummy channel\n");
+ return AST_TEST_FAIL;
+ }
+
+ if (!(str = ast_str_create(16))) {
+ ast_test_status_update(test, "Unable to allocate dynamic string buffer\n");
+ ast_channel_release(chan);
+ return AST_TEST_FAIL;
+ }
+
+ for (i = 0; i < ARRAY_LEN(test_args); i++) {
+ struct ast_var_t *var = ast_var_assign("TEST_STRING", test_args[i].test_string);
+ if (!var) {
+ ast_test_status_update(test, "Out of memory\n");
+ res = AST_TEST_FAIL;
+ break;
+ }
+
+ AST_LIST_INSERT_HEAD(ast_channel_varshead(chan), var, entries);
+
+ snprintf(expression, sizeof(expression), "${REPLACE(%s,%s,%s)}", var->name, test_args[i].find_chars, test_args[i].replace_char);
+ ast_str_substitute_variables(&str, 0, chan, expression);
+
+ AST_LIST_REMOVE(ast_channel_varshead(chan), var, entries);
+ ast_var_delete(var);
+
+ if (strcasecmp(ast_str_buffer(str), test_args[i].expected)) {
+ ast_test_status_update(test, "Evaluation of '%s' returned '%s' instead of the expected value '%s'\n",
+ expression, ast_str_buffer(str), test_args[i].expected);
+ res = AST_TEST_FAIL;
+ break;
+ }
+ }
+
+ ast_free(str);
+ ast_channel_release(chan);
+
+ return res;
+}
+
AST_TEST_DEFINE(test_FILTER)
{
int i, res = AST_TEST_PASS;
@@ -1843,6 +1912,7 @@ static int unload_module(void)
int res = 0;
AST_TEST_UNREGISTER(test_FIELDNUM);
+ AST_TEST_UNREGISTER(test_REPLACE);
AST_TEST_UNREGISTER(test_FILTER);
AST_TEST_UNREGISTER(test_STRREPLACE);
res |= ast_custom_function_unregister(&fieldqty_function);
@@ -1879,6 +1949,7 @@ static int load_module(void)
int res = 0;
AST_TEST_REGISTER(test_FIELDNUM);
+ AST_TEST_REGISTER(test_REPLACE);
AST_TEST_REGISTER(test_FILTER);
AST_TEST_REGISTER(test_STRREPLACE);
res |= ast_custom_function_register(&fieldqty_function);