From e1ed386bb979651f76198bd63a2a8a845f8beeb5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 1 Jul 2013 12:16:47 -0500 Subject: [PATCH 1/3] FS-5565 --resolve --- src/switch_rtp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 821c375384..177fbffcc5 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -681,10 +681,14 @@ static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice) ice->next_run = now + RTP_STUN_FREQ; - if (ice == &rtp_session->rtcp_ice) { + if (ice == &rtp_session->rtcp_ice && rtp_session->rtcp_sock_output) { sock_output = rtp_session->rtcp_sock_output; } + if (!sock_output) { + return SWITCH_STATUS_FALSE; + } + switch_assert(rtp_session != NULL); switch_assert(ice->ice_user != NULL); From 8bcff4ca4d3643518f98d01f52772cf71661699f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 1 Jul 2013 14:31:43 -0500 Subject: [PATCH 2/3] fix input event checker pre-empting return value from dtmf checker when both are present --- src/switch_ivr.c | 15 ++++++++++++--- src/switch_ivr_play_say.c | 21 +++++++++++++++++---- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index a99070d241..ba4ad8bead 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -275,7 +275,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, switch_event_t *event = NULL; if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + if (ostatus != SWITCH_STATUS_SUCCESS) { + status = ostatus; + } switch_event_destroy(&event); } } @@ -1092,7 +1095,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session, if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { if (args && args->input_callback) { - if ((status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) { + switch_status_t ostatus; + + if ((ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) { + status = ostatus; break; } } else { @@ -1210,7 +1216,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s } if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + if (ostatus != SWITCH_STATUS_SUCCESS) { + status = ostatus; + } switch_event_destroy(&event); } diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index fe62b911a0..1f2f076a06 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -687,9 +687,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if (args->input_callback) { switch_event_t *event = NULL; + switch_status_t ostatus; if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + if ((ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) { + status = ostatus; + } + switch_event_destroy(&event); } } @@ -941,7 +945,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi switch_event_t *event; if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + if (ostatus != SWITCH_STATUS_SUCCESS) { + status = ostatus; + } switch_event_destroy(&event); } } @@ -1433,7 +1440,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_event_t *event; if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + if (ostatus != SWITCH_STATUS_SUCCESS) { + status = ostatus; + } switch_event_destroy(&event); } } @@ -2278,7 +2288,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session if (args->input_callback) { if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); + if (ostatus != SWITCH_STATUS_SUCCESS) { + status = ostatus; + } switch_event_destroy(&event); } } From c2c8fba14a0352dfeecf31a0f818d83f83a93a85 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Mon, 1 Jul 2013 17:03:00 -0500 Subject: [PATCH 3/3] --resolve FS-5566 When you use $12345 in regex substitutions, it isn't obvious whenever you mean $1-concatenated-2345 or $12-concatenated-345 or any other variation. In all other languages, in order to solve this ambiguity, a braces {} are allowed to be used to separate variable name (or a reference) from surrounding text, like ${1}2345 or ${12}345. Use the same for freeswitch too. While at it, fix a buffer overflow as well: the index[] variable which is used to copy the "variable" name is 10 chars long, but it is used in the code without bounds checking, so a reference which is >9 chars long ($1234567890) will overflow the buffer, crashing freeswitch. And another overflow is in the way how size of the "substituted" variable is handled. First, in the outer loop, we compare the wrong variable with the size of `substituted' buffer (amount of bytes we took from the source instead of amount of bytes we used in `substituted'). And second, when actual regex match is being substitured, amount of room in `substituted' variable is not checked at all. Patch contributed by Michael Tokarev --- src/switch_regex.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/switch_regex.c b/src/switch_regex.c index 0a3479582e..2a98638134 100644 --- a/src/switch_regex.c +++ b/src/switch_regex.c @@ -132,20 +132,37 @@ SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_c const char *replace = NULL; switch_size_t x, y = 0, z = 0; int num = 0; + int brace; - for (x = 0; x < (len - 1) && x < strlen(data);) { + for (x = 0; y < (len - 1) && x < strlen(data);) { if (data[x] == '$') { x++; + brace = data[x] == '{'; + if (brace) { + x++; + } + if (!(data[x] > 47 && data[x] < 58)) { + x -= brace; substituted[y++] = data[x - 1]; continue; } - while (data[x] > 47 && data[x] < 58) { + while (data[x] > 47 && data[x] < 58 && z < sizeof(index) - 1) { index[z++] = data[x]; x++; } + if (brace) { + if (data[x] != '}') { + x -= z - 1; + substituted[y++] = data[x - 1]; + continue; + } + else { + x++; + } + } index[z++] = '\0'; z = 0; num = atoi(index); @@ -156,7 +173,7 @@ SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_c if (pcre_get_substring(field_data, ovector, match_count, num, &replace) > 0) { switch_size_t r; - for (r = 0; r < strlen(replace); r++) { + for (r = 0; r < strlen(replace) && y < (len - 1); r++) { substituted[y++] = replace[r]; } pcre_free_substring(replace);