summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2012-06-08 21:08:17 +0000
committerRichard Mudgett <rmudgett@digium.com>2012-06-08 21:08:17 +0000
commit745484e1b3dbf758e602aa642474822c4f1eaccb (patch)
tree5ef2f990af200c21029dd7acb4b189855c52945f
parent8b2412db289b43202ef33053fb4efc4481d99bd4 (diff)
Fix error paths in action_hangup() for AMI Hangup action.
* Check allocation function return values for failure. Crashing is bad. * Tweak ast_regex_string_to_regex_pattern() parameters for proper ast_str usage. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@368714 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--include/asterisk/strings.h26
-rw-r--r--main/manager.c50
-rw-r--r--main/utils.c6
3 files changed, 44 insertions, 38 deletions
diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h
index e3ff4c4fe..7a7772294 100644
--- a/include/asterisk/strings.h
+++ b/include/asterisk/strings.h
@@ -253,19 +253,19 @@ int ast_build_string(char **buffer, size_t *space, const char *fmt, ...) __attri
int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap) __attribute__((format(printf, 3, 0)));
/*!
- \brief Given a string regex_string in the form of "/regex/", convert it into the form of "regex"
-
- This function will trim one leading / and one trailing / from a given input string
- ast_str regex_pattern must be preallocated before calling this function
-
- \return 0 on success, non-zero on failure.
- \return 1 if we only stripped a leading /
- \return 2 if we only stripped a trailing /
- \return 3 if we did not strip any / characters
- \param regex_string the string containing /regex/
- \param regex_pattern the destination ast_str which will contain "regex" after execution
-*/
-int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str *regex_pattern);
+ * \brief Given a string regex_string in the form of "/regex/", convert it into the form of "regex"
+ *
+ * This function will trim one leading / and one trailing / from a given input string
+ * ast_str regex_pattern must be preallocated before calling this function
+ *
+ * \return 0 on success, non-zero on failure.
+ * \return 1 if we only stripped a leading /
+ * \return 2 if we only stripped a trailing /
+ * \return 3 if we did not strip any / characters
+ * \param regex_string the string containing /regex/
+ * \param regex_pattern the destination ast_str which will contain "regex" after execution
+ */
+int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str **regex_pattern);
/*!
* \brief Make sure something is true.
diff --git a/main/manager.c b/main/manager.c
index 4bf859e2e..588d880e0 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -3199,7 +3199,7 @@ static int action_hangup(struct mansession *s, const struct message *m)
const char *id = astman_get_header(m, "ActionID");
const char *name_or_regex = astman_get_header(m, "Channel");
const char *cause = astman_get_header(m, "Cause");
- char idText[256] = "";
+ char idText[256];
regex_t regexbuf;
struct ast_channel_iterator *iter = NULL;
struct ast_str *regex_string;
@@ -3212,6 +3212,8 @@ static int action_hangup(struct mansession *s, const struct message *m)
if (!ast_strlen_zero(id)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
+ } else {
+ idText[0] = '\0';
}
if (!ast_strlen_zero(cause)) {
@@ -3252,9 +3254,13 @@ static int action_hangup(struct mansession *s, const struct message *m)
/* find and hangup any channels matching regex */
regex_string = ast_str_create(strlen(name_or_regex));
+ if (!regex_string) {
+ astman_send_error(s, m, "Memory Allocation Failure");
+ return 0;
+ }
/* Make "/regex/" into "regex" */
- if (ast_regex_string_to_regex_pattern(name_or_regex, regex_string) != 0) {
+ if (ast_regex_string_to_regex_pattern(name_or_regex, &regex_string) != 0) {
astman_send_error(s, m, "Regex format invalid, Channel param should be /regex/");
ast_free(regex_string);
return 0;
@@ -3269,31 +3275,31 @@ static int action_hangup(struct mansession *s, const struct message *m)
astman_send_listack(s, m, "Channels hung up will follow", "start");
- for (iter = ast_channel_iterator_all_new(); iter && (c = ast_channel_iterator_next(iter)); ) {
- if (regexec(&regexbuf, ast_channel_name(c), 0, NULL, 0)) {
- ast_channel_unref(c);
- continue;
- }
-
- ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
- (s->session->managerid ? "HTTP " : ""),
- s->session->username,
- ast_inet_ntoa(s->session->sin.sin_addr),
- ast_channel_name(c));
+ iter = ast_channel_iterator_all_new();
+ if (iter) {
+ for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
+ if (regexec(&regexbuf, ast_channel_name(c), 0, NULL, 0)) {
+ continue;
+ }
- ast_channel_softhangup_withcause_locked(c, causecode);
- channels_matched++;
+ ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
+ (s->session->managerid ? "HTTP " : ""),
+ s->session->username,
+ ast_inet_ntoa(s->session->sin.sin_addr),
+ ast_channel_name(c));
- astman_append(s,
- "Event: ChannelHungup\r\n"
- "Channel: %s\r\n"
- "%s"
- "\r\n", ast_channel_name(c), idText);
+ ast_channel_softhangup_withcause_locked(c, causecode);
+ channels_matched++;
- ast_channel_unref(c);
+ astman_append(s,
+ "Event: ChannelHungup\r\n"
+ "Channel: %s\r\n"
+ "%s"
+ "\r\n", ast_channel_name(c), idText);
+ }
+ ast_channel_iterator_destroy(iter);
}
- ast_channel_iterator_destroy(iter);
regfree(&regexbuf);
ast_free(regex_string);
diff --git a/main/utils.c b/main/utils.c
index 9bdf74f19..21842ee94 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -1362,20 +1362,20 @@ int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
return result;
}
-int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str *regex_pattern)
+int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str **regex_pattern)
{
int regex_len = strlen(regex_string);
int ret = 3;
/* Chop off the leading / if there is one */
if ((regex_len >= 1) && (regex_string[0] == '/')) {
- ast_str_set(&regex_pattern, 0, "%s", regex_string + 1);
+ ast_str_set(regex_pattern, 0, "%s", regex_string + 1);
ret -= 2;
}
/* Chop off the ending / if there is one */
if ((regex_len > 1) && (regex_string[regex_len - 1] == '/')) {
- ast_str_truncate(regex_pattern, -1);
+ ast_str_truncate(*regex_pattern, -1);
ret -= 1;
}