diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 2692cdf4d3..f54d1d1d2b 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -1107,6 +1107,13 @@ static inline int switch_needs_url_encode(const char *s) SWITCH_DECLARE(char *) switch_url_encode_opt(const char *url, char *buf, size_t len, switch_bool_t double_encode); SWITCH_DECLARE(char *) switch_url_encode(const char *url, char *buf, size_t len); SWITCH_DECLARE(char *) switch_url_decode(char *s); + +SWITCH_DECLARE(char *) switch_core_url_encode_opt(switch_memory_pool_t *pool, const char *url, switch_bool_t double_encode); +SWITCH_DECLARE(char *) switch_core_url_encode(switch_memory_pool_t *pool, const char *url); +SWITCH_DECLARE(char *) switch_core_session_url_encode_opt(switch_core_session_t *session, const char *url, switch_bool_t double_encode); +SWITCH_DECLARE(char *) switch_core_session_url_encode(switch_core_session_t *session, const char *url); + + SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, const char *from, const char *headers, diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 7bc26b94e7..12dd673d29 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -860,6 +860,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) if (!tech_pvt->from_str) { const char *sipip; const char *format; + char *use_cid_num = switch_core_session_url_encode(tech_pvt->session, cid_num); sipip = tech_pvt->profile->sipip; @@ -873,7 +874,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) format = strchr(sipip, ':') ? "\"%s\" " : "\"%s\" "; - tech_pvt->from_str = switch_core_session_sprintf(tech_pvt->session, format, cid_name, cid_num, !zstr(cid_num) ? "@" : "", sipip); + tech_pvt->from_str = switch_core_session_sprintf(tech_pvt->session, format, cid_name, use_cid_num, !zstr(cid_num) ? "@" : "", sipip); } if (from_var) { diff --git a/src/switch_utils.c b/src/switch_utils.c index 5c47974f1b..6d0e0a5e91 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -3228,6 +3228,58 @@ SWITCH_DECLARE(int) switch_socket_waitfor(switch_pollfd_t *poll, int ms) return nsds; } +SWITCH_DECLARE(char *) switch_core_session_url_encode(switch_core_session_t *session, const char *url) +{ + return switch_core_url_encode_opt(switch_core_session_get_pool(session), url, SWITCH_FALSE); +} + +SWITCH_DECLARE(char *) switch_core_session_url_encode_opt(switch_core_session_t *session, const char *url, switch_bool_t double_encode) +{ + return switch_core_url_encode_opt(switch_core_session_get_pool(session), url, double_encode); +} + +SWITCH_DECLARE(char *) switch_core_url_encode(switch_memory_pool_t *pool, const char *url) +{ + return switch_core_url_encode_opt(pool, url, SWITCH_FALSE); +} + +SWITCH_DECLARE(char *) switch_core_url_encode_opt(switch_memory_pool_t *pool, const char *url, switch_bool_t double_encode) +{ + const char hex[] = "0123456789ABCDEF"; + switch_size_t len = 0; + switch_size_t slen = 0; + const char *p, *e = end_of_p(url); + + if (!url) return NULL; + if (!pool) return NULL; + + for (p = url; *p; p++) { + int ok = 0; + + len++; + slen++; + + if (!double_encode && *p == '%' && e-p > 1) { + if (strchr(hex, *(p+1)) && strchr(hex, *(p+2))) { + ok = 1; + } + } + + if (!ok && (*p < ' ' || *p > '~' || strchr(SWITCH_URL_UNSAFE, *p))) { + len += 2; + } + } + + slen++; + len++; /* NULL Terminatior */ + + if (slen == len) { + return switch_core_strdup(pool, url); + } else { + return switch_url_encode_opt(url, switch_core_alloc(pool, sizeof(char) * len), len, double_encode); + } +} + SWITCH_DECLARE(char *) switch_url_encode_opt(const char *url, char *buf, size_t len, switch_bool_t double_encode) { const char *p, *e = end_of_p(url);