[Asterisk-code-review] main/pbx_variables.c: Better parsing of variable name and value ... (asterisk[16])
Leandro Dardini
asteriskteam at digium.com
Tue Jan 19 14:37:15 CST 2021
Leandro Dardini has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/15331 )
Change subject: main/pbx_variables.c: Better parsing of variable name and value separator for Set command main/utils.c: Added a subroutine to return name and value from Set command argument
......................................................................
main/pbx_variables.c: Better parsing of variable name and value
separator for Set command
main/utils.c: Added a subroutine to return name and value from
Set command argument
The variable name and value of a Set command are separated by a
=, but the = character may appear in the variable name portion as
a parameter for a function, like any ODBC_* func_odbc.conf
function, so better handling of quotes, parenthesis, and brackets
was needed.
ASTERISK-29239 #close
Change-Id: I7cd3bc6118033530ad00ae4b6bdad97b6b349b6f
---
M include/asterisk/utils.h
M main/pbx_variables.c
M main/utils.c
3 files changed, 69 insertions(+), 9 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/31/15331/1
diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h
index 0ee11ee..54da45d 100644
--- a/include/asterisk/utils.h
+++ b/include/asterisk/utils.h
@@ -928,6 +928,12 @@
*/
int ast_check_ipv6(void);
+/*!
+ *\brief Parse a name = value assignment pair.
+ *\return Returns -1 if there is no valid assignment in the string.
+ */
+int ast_parse_name_value(const char *input, char **name, char **value);
+
enum ast_fd_flag_operation {
AST_FD_FLAG_SET,
AST_FD_FLAG_CLEAR,
diff --git a/main/pbx_variables.c b/main/pbx_variables.c
index 91b5bbb..22d14b2 100644
--- a/main/pbx_variables.c
+++ b/main/pbx_variables.c
@@ -1128,23 +1128,22 @@
int pbx_builtin_setvar(struct ast_channel *chan, const char *data)
{
- char *name, *value, *mydata;
+ char *name = NULL;
+ char *value = NULL;
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Set requires one variable name/value pair.\n");
return 0;
}
- mydata = ast_strdupa(data);
- name = strsep(&mydata, "=");
- value = mydata;
- if (!value) {
- ast_log(LOG_WARNING, "Set requires an '=' to be a valid assignment.\n");
- return 0;
- }
+ /* We don't know how much of "data" is the name and how much is the value so we'll use the worst case */
+ name = ast_alloca(strlen(data) + 1);
+ value = ast_alloca(strlen(data) + 1);
+
+ ast_parse_name_value(data,&name,&value);
if (strchr(name, ' ')) {
- ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", name, mydata);
+ ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", name, value);
}
pbx_builtin_setvar_helper(chan, name, value);
diff --git a/main/utils.c b/main/utils.c
index 827ee2e..aa44cd5 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -2372,6 +2372,61 @@
return 0;
}
+/*!
+ *\brief Parse a name = value assignment pair.
+ *\return Returns -1 if there is no valid assignment in the string.
+ */
+int ast_parse_name_value(const char *input, char **name, char **value)
+{
+ char *mydata = NULL;
+ char *scan = NULL;
+ int paren = 0;
+ int quote = 0;
+ int bracket = 0;
+ int ret = 0;
+
+ if (ast_strlen_zero(input)) {
+ ast_log(LOG_ERROR, "Input must be not NULL");
+ ret = -1;
+ }
+
+ mydata = ast_strdupa(input);
+
+ scan = mydata;
+
+ for (; *scan; scan++) {
+ if (*scan == '(') {
+ paren++;
+ } else if (*scan == ')') {
+ if (paren) {
+ paren--;
+ }
+ } else if (*scan == '[') {
+ bracket++;
+ } else if (*scan == ']') {
+ if (bracket) {
+ bracket--;
+ }
+ } else if (*scan == '"') {
+ quote = quote ? 0 : 1;
+ } else if (*scan == '\\') {
+ scan++;
+ } else if ((*scan == '=') && !paren && !quote && !bracket) {
+ *scan++ = '\0';
+ strcpy(*value, scan);
+ strcpy(*name, mydata);
+ break;
+ }
+ }
+
+ if (!*value) {
+ ast_log(LOG_WARNING, "Set requires an '=' to be a valid assignment.\n");
+ ret = -1;
+ }
+
+ return ret;
+}
+
int ast_get_tid(void)
{
int ret = -1;
--
To view, visit https://gerrit.asterisk.org/c/asterisk/+/15331
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: 16
Gerrit-Change-Id: I7cd3bc6118033530ad00ae4b6bdad97b6b349b6f
Gerrit-Change-Number: 15331
Gerrit-PatchSet: 1
Gerrit-Owner: Leandro Dardini <ldardini at gmail.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20210119/f3b566cf/attachment.html>
More information about the asterisk-code-review
mailing list