From ca2d2c9b66db52b740b445cb8c55cabff98846b0 Mon Sep 17 00:00:00 2001 From: Aron Podrigal Date: Mon, 15 Dec 2014 14:23:33 -0500 Subject: [PATCH 1/6] FS-5945 - cond api escape special charactars --- .../applications/mod_commands/mod_commands.c | 272 ++++++++++-------- 1 file changed, 153 insertions(+), 119 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 6fc06ea07e..de90df3b5c 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1893,13 +1893,13 @@ typedef enum { SWITCH_STANDARD_API(cond_function) { int argc; - char *mydata = NULL, *argv[3]; + char *mydata = NULL, *argv[2]; char *expr; char *a, *b; double a_f = 0.0, b_f = 0.0; o_t o = O_NONE; int is_true = 0; - char *p; + char *p = NULL; if (!cmd) { goto error; @@ -1908,114 +1908,150 @@ SWITCH_STANDARD_API(cond_function) mydata = strdup(cmd); switch_assert(mydata); - if ((p = strchr(mydata, '?'))) { - *p = ':'; - } else { - goto error; - } - - argc = switch_separate_string(mydata, ':', argv, (sizeof(argv) / sizeof(argv[0]))); - - if (! (argc >= 2 && argc <= 3)) { - goto error; - } - - a = argv[0]; - while(*a == ' ' || *a == '\t') a++; + a = mydata; if (*a == '\'') { - if ((expr = switch_find_end_paren(a, '\'', '\''))) { - a++; - *expr++ = '\0'; - } else { - goto error; + for (expr = ++a; expr && *expr; expr++) { + if (*expr == '\\') { + if (expr + 1 && (*(expr + 1) == '\\' || *(expr + 1) == '\'')) { + expr++; + } + } else if (*expr == '\'') { + break; + } + } + if (!expr) { + stream->write_function(stream, "-ERR while looking for closing quote near %s \n", a); + goto end; + } + *expr++ = '\0'; + + if (expr && *expr != ' ' && *expr != '\t') { + stream->write_function(stream, "-ERR, Syntax error near %s \n", expr); + goto end; } } else { if ((expr = strchr(a, ' '))) { *expr++ = '\0'; } else { - expr = a; + stream->write_function(stream, "-ERR, Syntax error near %s \n", a); + goto end; } } - if (strspn(a, "!<>=")) { - expr = a; + while (expr && (*expr == ' ' || *expr == '\t')) expr++; + + while (expr && *expr) { + switch (*expr) { + case '!': + case '<': + case '>': + case '=': + goto operator; + default: + expr++; + break; + } } - if (expr == a) { - a = ""; - } +operator: - while (*expr == ' ') expr++; - - while(expr && *expr) { - switch(*expr) { + switch (*expr) { case '!': - case '<': - case '>': - case '=': - goto done; - default: - expr++; + *expr++ = '\0'; + if (*expr == '=') { + o = O_NE; + *expr++ = '\0'; + } break; - } + + case '>': + *expr++ = '\0'; + if (*expr == '=') { + o = O_GE; + *expr++ = '\0'; + } else { + o = O_GT; + } + break; + + case '<': + *expr++ = '\0'; + if (*expr == '=') { + o = O_LE; + *expr++ = '\0'; + } else { + o = O_LT; + } + break; + + case '=': + *expr++ = '\0'; + if (*expr == '=') { + o = O_EQ; + *expr++ = '\0'; + } + break; + + default: + stream->write_function(stream, "-ERR, Syntax error near %s invalid conditional operator.\n", expr); + goto end; } - done: - - switch(*expr) { - case '!': - *expr++ = '\0'; - if (*expr == '=') { - o = O_NE; - *expr++ = '\0'; - } - break; - - case '>': - *expr++ = '\0'; - if (*expr == '=') { - o = O_GE; - *expr++ = '\0'; - } else { - o = O_GT; - } - break; - - case '<': - *expr++ = '\0'; - if (*expr == '=') { - o = O_LE; - *expr++ = '\0'; - } else { - o = O_LT; - } - break; - - case '=': - *expr++ = '\0'; - if (*expr == '=') { - o = O_EQ; - *expr++ = '\0'; - } - break; - - default: - goto error; - } - - if (o) { char *s_a = NULL, *s_b = NULL; int a_is_num, b_is_num; expr++; + while (expr && (*expr == ' ' || *expr == '\t')) expr++; + b = expr; + if (b && *b == '\'') { + for (expr = ++b; expr && *expr; expr++) { + if (*expr == '\\') { + if (expr + 1 && (*(expr + 1) == '\\' || *(expr + 1) == '\'')) { + expr++; + } + } else if (*expr == '\'') { + break; + } + } + if (!expr) { + stream->write_function(stream, "-ERR while looking for closing quote near < %s >!\n", b); + goto end; + } + *expr++ = '\0'; - s_a = switch_strip_spaces(a, SWITCH_TRUE); - s_b = switch_strip_spaces(b, SWITCH_TRUE); + if (expr && *expr != ' ' && *expr != '\t') { + stream->write_function(stream, "-ERR, Syntax error near %s \n", expr); + goto end; + } + } else { + if ((expr = strchr(b, ' '))) { + *expr++ = '\0'; + } else { + stream->write_function(stream, "-ERR, Syntax error near %s \n", b); + goto end; + } + } + if ((p = strchr(expr, '?'))) { + expr = ++p; + while (expr && (*expr == ' ' || *expr == '\t')) expr++; + } else { + stream->write_function(stream, "-ERR, Syntax error near %s , no expression found.\n", expr); + goto end; + } + + argc = switch_separate_string(expr, ':', argv, (sizeof (argv) / sizeof (argv[0]))); + if (!(argc >= 2 && argc <= 3)) { + stream->write_function(stream, "-ERR, Syntax error near %s , Invalid expression.\n", expr); + goto end; + } + + s_a = a; + s_b = b; a_is_num = switch_is_number(s_a); b_is_num = switch_is_number(s_b); @@ -2023,49 +2059,47 @@ SWITCH_STANDARD_API(cond_function) b_f = b_is_num ? atof(s_b) : (float) strlen(s_b); switch (o) { - case O_EQ: - if (!a_is_num && !b_is_num) { - is_true = !strcmp(s_a, s_b); - } else { - is_true = a_f == b_f; - } - break; - case O_NE: - if (!a_is_num && !b_is_num) { - is_true = strcmp(s_a, s_b); - } else { - is_true = a_f != b_f; - } - break; - case O_GT: - is_true = a_f > b_f; - break; - case O_GE: - is_true = a_f >= b_f; - break; - case O_LT: - is_true = a_f < b_f; - break; - case O_LE: - is_true = a_f <= b_f; - break; - default: - break; + case O_EQ: + if (!a_is_num && !b_is_num) { + is_true = !strcmp(s_a, s_b); + } else { + is_true = a_f == b_f; + } + break; + case O_NE: + if (!a_is_num && !b_is_num) { + is_true = strcmp(s_a, s_b); + } else { + is_true = a_f != b_f; + } + break; + case O_GT: + is_true = a_f > b_f; + break; + case O_GE: + is_true = a_f >= b_f; + break; + case O_LT: + is_true = a_f < b_f; + break; + case O_LE: + is_true = a_f <= b_f; + break; + default: + break; } - switch_safe_free(s_a); - switch_safe_free(s_b); - if ((argc == 2 && !is_true)) { + if ((argc == 1 && !is_true)) { stream->write_function(stream, ""); } else { - stream->write_function(stream, "%s", is_true ? argv[1] : argv[2]); + stream->write_function(stream, "%s", is_true ? argv[0] : argv[1]); } - goto ok; + goto end; } - error: +error: stream->write_function(stream, "-ERR"); - ok: +end: switch_safe_free(mydata); return SWITCH_STATUS_SUCCESS; From 625c95a5b18a4f81a780825545525d687943cced Mon Sep 17 00:00:00 2001 From: Aron Podrigal Date: Wed, 24 Dec 2014 21:22:23 -0500 Subject: [PATCH 2/6] FS-5945 - cond api improved --- .../applications/mod_commands/mod_commands.c | 74 ++++++++++--------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index de90df3b5c..b485a71a78 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1893,13 +1893,13 @@ typedef enum { SWITCH_STANDARD_API(cond_function) { int argc; - char *mydata = NULL, *argv[2]; + char *mydata = NULL, *argv[3]; char *expr; char *a, *b; double a_f = 0.0, b_f = 0.0; + int a_is_quoted = 0, b_is_quoted = 0; o_t o = O_NONE; int is_true = 0; - char *p = NULL; if (!cmd) { goto error; @@ -1911,37 +1911,38 @@ SWITCH_STANDARD_API(cond_function) a = mydata; if (*a == '\'') { - for (expr = ++a; expr && *expr; expr++) { + a_is_quoted = 1; + for (expr = ++a; *expr; expr++) { if (*expr == '\\') { - if (expr + 1 && (*(expr + 1) == '\\' || *(expr + 1) == '\'')) { + if (*(expr + 1) == '\\' || *(expr + 1) == '\'') { expr++; } } else if (*expr == '\'') { break; } } - if (!expr) { - stream->write_function(stream, "-ERR while looking for closing quote near %s \n", a); + if (!*expr) { + stream->write_function(stream, "-ERR while looking for closing quote near < %s > \n", a); goto end; } *expr++ = '\0'; - if (expr && *expr != ' ' && *expr != '\t') { - stream->write_function(stream, "-ERR, Syntax error near %s \n", expr); + if (!switch_isspace(*expr)) { + stream->write_function(stream, "-ERR, Syntax error near < %s > \n", expr); goto end; } } else { if ((expr = strchr(a, ' '))) { *expr++ = '\0'; } else { - stream->write_function(stream, "-ERR, Syntax error near %s \n", a); + stream->write_function(stream, "-ERR, Syntax error near < %s > \n", a); goto end; } } - while (expr && (*expr == ' ' || *expr == '\t')) expr++; + while (switch_isspace(*expr)) expr++; - while (expr && *expr) { + while (*expr) { switch (*expr) { case '!': case '<': @@ -2003,57 +2004,58 @@ operator: int a_is_num, b_is_num; expr++; - while (expr && (*expr == ' ' || *expr == '\t')) expr++; + while (switch_isspace(*expr)) expr++; b = expr; - if (b && *b == '\'') { - for (expr = ++b; expr && *expr; expr++) { - if (*expr == '\\') { - if (expr + 1 && (*(expr + 1) == '\\' || *(expr + 1) == '\'')) { - expr++; + if (*b == '\'') { + b_is_quoted = 1; + for (expr = ++b; *expr; expr++) { + if (*expr == '\\') { + if (*(expr + 1) == '\\' || *(expr + 1) == '\'') { + expr++; + } + } else if (*expr == '\'') { + break; } - } else if (*expr == '\'') { - break; } - } - if (!expr) { + if (!*expr) { stream->write_function(stream, "-ERR while looking for closing quote near < %s >!\n", b); goto end; } *expr++ = '\0'; - if (expr && *expr != ' ' && *expr != '\t') { - stream->write_function(stream, "-ERR, Syntax error near %s \n", expr); + if (!switch_isspace(*expr)) { + stream->write_function(stream, "-ERR, Syntax error near < %s > \n", expr); goto end; } - } else { if ((expr = strchr(b, ' '))) { *expr++ = '\0'; } else { - stream->write_function(stream, "-ERR, Syntax error near %s \n", b); + stream->write_function(stream, "-ERR, Syntax error near < %s > \n", b); goto end; } } - if ((p = strchr(expr, '?'))) { - expr = ++p; - while (expr && (*expr == ' ' || *expr == '\t')) expr++; - } else { - stream->write_function(stream, "-ERR, Syntax error near %s , no expression found.\n", expr); + while (switch_isspace(*expr)) expr++; + + if (*expr != '?') { + stream->write_function(stream, "-ERR, Syntax error near < %s > no expression found.\n", expr); goto end; } - argc = switch_separate_string(expr, ':', argv, (sizeof (argv) / sizeof (argv[0]))); + *expr = ':'; + + argc = switch_separate_string(expr, ':', argv, (sizeof(argv) / sizeof(argv[0]))); if (!(argc >= 2 && argc <= 3)) { - stream->write_function(stream, "-ERR, Syntax error near %s , Invalid expression.\n", expr); + stream->write_function(stream, "-ERR, Syntax error near < %s > , Invalid expression.\n", ++expr); goto end; } s_a = a; s_b = b; - a_is_num = switch_is_number(s_a); - b_is_num = switch_is_number(s_b); + a_is_num = (switch_is_number(s_a) && !a_is_quoted); + b_is_num = (switch_is_number(s_b) && !b_is_quoted); a_f = a_is_num ? atof(s_a) : (float) strlen(s_a); b_f = b_is_num ? atof(s_b) : (float) strlen(s_b); @@ -2089,10 +2091,10 @@ operator: break; } - if ((argc == 1 && !is_true)) { + if ((argc == 2 && !is_true)) { stream->write_function(stream, ""); } else { - stream->write_function(stream, "%s", is_true ? argv[0] : argv[1]); + stream->write_function(stream, "%s", is_true ? argv[1] : argv[2]); } goto end; } From 3e11bf0d223c0e9b27a7e7b2fb09759f3501ba4a Mon Sep 17 00:00:00 2001 From: Aron Podrigal Date: Thu, 25 Dec 2014 10:34:37 -0500 Subject: [PATCH 3/6] cond api return -ERR on all syntax errors --- .../applications/mod_commands/mod_commands.c | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index b485a71a78..51f8f72714 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1922,21 +1922,18 @@ SWITCH_STANDARD_API(cond_function) } } if (!*expr) { - stream->write_function(stream, "-ERR while looking for closing quote near < %s > \n", a); - goto end; + goto error; } *expr++ = '\0'; if (!switch_isspace(*expr)) { - stream->write_function(stream, "-ERR, Syntax error near < %s > \n", expr); - goto end; + goto error; } } else { if ((expr = strchr(a, ' '))) { *expr++ = '\0'; } else { - stream->write_function(stream, "-ERR, Syntax error near < %s > \n", a); - goto end; + goto error; } } @@ -1950,7 +1947,7 @@ SWITCH_STANDARD_API(cond_function) case '=': goto operator; default: - expr++; + goto error; break; } } @@ -1995,8 +1992,7 @@ operator: break; default: - stream->write_function(stream, "-ERR, Syntax error near %s invalid conditional operator.\n", expr); - goto end; + goto error; } if (o) { @@ -2019,37 +2015,32 @@ operator: } } if (!*expr) { - stream->write_function(stream, "-ERR while looking for closing quote near < %s >!\n", b); - goto end; + goto error; } *expr++ = '\0'; if (!switch_isspace(*expr)) { - stream->write_function(stream, "-ERR, Syntax error near < %s > \n", expr); - goto end; + goto error; } } else { if ((expr = strchr(b, ' '))) { *expr++ = '\0'; } else { - stream->write_function(stream, "-ERR, Syntax error near < %s > \n", b); - goto end; + goto error; } } while (switch_isspace(*expr)) expr++; if (*expr != '?') { - stream->write_function(stream, "-ERR, Syntax error near < %s > no expression found.\n", expr); - goto end; + goto error; } *expr = ':'; argc = switch_separate_string(expr, ':', argv, (sizeof(argv) / sizeof(argv[0]))); if (!(argc >= 2 && argc <= 3)) { - stream->write_function(stream, "-ERR, Syntax error near < %s > , Invalid expression.\n", ++expr); - goto end; + goto error; } s_a = a; From ff2729c370ba427f710825afa941d77270916610 Mon Sep 17 00:00:00 2001 From: Aron Podrigal Date: Sat, 27 Dec 2014 23:10:34 -0500 Subject: [PATCH 4/6] cleanup --- .../applications/mod_commands/mod_commands.c | 145 +++++++++--------- 1 file changed, 71 insertions(+), 74 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 51f8f72714..88800ab5e4 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1922,9 +1922,9 @@ SWITCH_STANDARD_API(cond_function) } } if (!*expr) { - goto error; - } - *expr++ = '\0'; + goto error; + } + *expr++ = '\0'; if (!switch_isspace(*expr)) { goto error; @@ -1934,65 +1934,62 @@ SWITCH_STANDARD_API(cond_function) *expr++ = '\0'; } else { goto error; - } + } } while (switch_isspace(*expr)) expr++; - while (*expr) { - switch (*expr) { - case '!': - case '<': - case '>': - case '=': - goto operator; - default: - goto error; - break; - } - } + switch (*expr) { + case '!': + case '<': + case '>': + case '=': + goto operator; + default: + goto error; + } operator: switch (*expr) { - case '!': + case '!': + *expr++ = '\0'; + if (*expr == '=') { + o = O_NE; *expr++ = '\0'; - if (*expr == '=') { - o = O_NE; - *expr++ = '\0'; - } - break; + } + break; - case '>': + case '>': + *expr++ = '\0'; + if (*expr == '=') { + o = O_GE; *expr++ = '\0'; - if (*expr == '=') { - o = O_GE; - *expr++ = '\0'; - } else { - o = O_GT; - } - break; + } else { + o = O_GT; + } + break; - case '<': + case '<': + *expr++ = '\0'; + if (*expr == '=') { + o = O_LE; *expr++ = '\0'; - if (*expr == '=') { - o = O_LE; - *expr++ = '\0'; - } else { - o = O_LT; - } - break; + } else { + o = O_LT; + } + break; - case '=': + case '=': + *expr++ = '\0'; + if (*expr == '=') { + o = O_EQ; *expr++ = '\0'; - if (*expr == '=') { - o = O_EQ; - *expr++ = '\0'; - } - break; + } + break; - default: - goto error; + default: + goto error; } if (o) { @@ -2052,34 +2049,34 @@ operator: b_f = b_is_num ? atof(s_b) : (float) strlen(s_b); switch (o) { - case O_EQ: - if (!a_is_num && !b_is_num) { - is_true = !strcmp(s_a, s_b); - } else { - is_true = a_f == b_f; - } - break; - case O_NE: - if (!a_is_num && !b_is_num) { - is_true = strcmp(s_a, s_b); - } else { - is_true = a_f != b_f; - } - break; - case O_GT: - is_true = a_f > b_f; - break; - case O_GE: - is_true = a_f >= b_f; - break; - case O_LT: - is_true = a_f < b_f; - break; - case O_LE: - is_true = a_f <= b_f; - break; - default: - break; + case O_EQ: + if (!a_is_num && !b_is_num) { + is_true = !strcmp(s_a, s_b); + } else { + is_true = a_f == b_f; + } + break; + case O_NE: + if (!a_is_num && !b_is_num) { + is_true = strcmp(s_a, s_b); + } else { + is_true = a_f != b_f; + } + break; + case O_GT: + is_true = a_f > b_f; + break; + case O_GE: + is_true = a_f >= b_f; + break; + case O_LT: + is_true = a_f < b_f; + break; + case O_LE: + is_true = a_f <= b_f; + break; + default: + break; } if ((argc == 2 && !is_true)) { From 6be85bbef53d2a1789744ecc73feae161a1d1f85 Mon Sep 17 00:00:00 2001 From: Aron Podrigal Date: Sat, 27 Dec 2014 23:44:03 -0500 Subject: [PATCH 5/6] fixed indentation --- .../applications/mod_commands/mod_commands.c | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 88800ab5e4..bc761a3911 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1922,9 +1922,9 @@ SWITCH_STANDARD_API(cond_function) } } if (!*expr) { - goto error; - } - *expr++ = '\0'; + goto error; + } + *expr++ = '\0'; if (!switch_isspace(*expr)) { goto error; @@ -1934,20 +1934,20 @@ SWITCH_STANDARD_API(cond_function) *expr++ = '\0'; } else { goto error; - } + } } while (switch_isspace(*expr)) expr++; - switch (*expr) { - case '!': - case '<': - case '>': - case '=': - goto operator; - default: - goto error; - } + switch (*expr) { + case '!': + case '<': + case '>': + case '=': + goto operator; + default: + goto error; + } operator: From 2cad5a6940bb76458e909a56c5e5e35e622467ed Mon Sep 17 00:00:00 2001 From: Aron Podrigal Date: Mon, 29 Dec 2014 13:24:21 -0500 Subject: [PATCH 6/6] more whitespace cleanup --- src/mod/applications/mod_commands/mod_commands.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index bc761a3911..f904a085c4 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1939,7 +1939,7 @@ SWITCH_STANDARD_API(cond_function) while (switch_isspace(*expr)) expr++; - switch (*expr) { + switch(*expr) { case '!': case '<': case '>': @@ -1949,7 +1949,7 @@ SWITCH_STANDARD_API(cond_function) goto error; } -operator: + operator: switch (*expr) { case '!': @@ -2087,9 +2087,9 @@ operator: goto end; } -error: + error: stream->write_function(stream, "-ERR"); -end: + end: switch_safe_free(mydata); return SWITCH_STATUS_SUCCESS;