[asterisk-commits] mmichelson: branch group/CCSS r243220 - in /team/group/CCSS: ./ channels/ inc...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jan 26 11:21:53 CST 2010
Author: mmichelson
Date: Tue Jan 26 11:21:47 2010
New Revision: 243220
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=243220
Log:
Resolve conflict in chan_sip and reset automerge.
Added:
team/group/CCSS/tests/test_utils.c
- copied unchanged from r243200, trunk/tests/test_utils.c
Modified:
team/group/CCSS/ (props changed)
team/group/CCSS/channels/chan_sip.c
team/group/CCSS/include/asterisk/utils.h
team/group/CCSS/main/test.c
team/group/CCSS/main/utils.c
Propchange: team/group/CCSS/
------------------------------------------------------------------------------
automerge = *
Propchange: team/group/CCSS/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jan 26 11:21:47 2010
@@ -1,1 +1,1 @@
-/trunk:1-243164
+/trunk:1-243215
Modified: team/group/CCSS/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/channels/chan_sip.c?view=diff&rev=243220&r1=243219&r2=243220
==============================================================================
--- team/group/CCSS/channels/chan_sip.c (original)
+++ team/group/CCSS/channels/chan_sip.c Tue Jan 26 11:21:47 2010
@@ -240,6 +240,7 @@
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
+#include "asterisk/test.h"
/*
Uncomment the define below, if you are having refcount related memory leaks.
With this uncommented, this module will generate a file, /tmp/refs, which contains
@@ -1225,6 +1226,12 @@
static struct sip_settings sip_cfg; /*!< SIP configuration data.
\note in the future we could have multiple of these (per domain, per device group etc) */
+/*!< use this macro when ast_uri_decode is dependent on pedantic checking to be on. */
+#define SIP_PEDANTIC_DECODE(str) \
+ if (sip_cfg.pedanticsipchecking && !ast_strlen_zero(str)) { \
+ ast_uri_decode(str); \
+ } \
+
static int global_match_auth_username; /*!< Match auth username if available instead of From: Default off. */
static int global_relaxdtmf; /*!< Relax DTMF */
@@ -3222,7 +3229,7 @@
static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req);
static int set_address_from_contact(struct sip_pvt *pvt);
static void check_via(struct sip_pvt *p, struct sip_request *req);
-static char *get_calleridname(const char *input, char *output, size_t outputsize);
+static const char *get_calleridname(const char *input, char *output, size_t outputsize);
static int get_rpid(struct sip_pvt *p, struct sip_request *oreq);
static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason);
static int get_destination(struct sip_pvt *p, struct sip_request *oreq, int *cc_recall_core_id);
@@ -14813,47 +14820,33 @@
enum check_auth_result res = AUTH_NOT_FOUND;
struct sip_peer *peer;
char tmp[256];
- char *name, *c;
- char *domain;
+ char *name = NULL, *c, *domain = NULL;
char *uri2 = ast_strdupa(uri);
terminate_uri(uri2);
ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
- if (sip_cfg.pedanticsipchecking)
- ast_uri_decode(tmp);
c = get_in_brackets(tmp);
c = remove_uri_parameters(c);
- if (!strncasecmp(c, "sip:", 4)) {
- name = c + 4;
- } else if (!strncasecmp(c, "sips:", 5)) {
- name = c + 5;
- } else {
- name = c;
+ if (parse_uri(c, "sip:,sips:", &name, NULL, &domain, NULL, NULL, NULL)) {
ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
- }
+ return -1;
+ }
+
+ SIP_PEDANTIC_DECODE(name);
+ SIP_PEDANTIC_DECODE(domain);
/*! \todo XXX here too we interpret a missing @domain as a name-only
* URI, whereas the RFC says this is a domain-only uri.
*/
- /* Strip off the domain name */
- if ((c = strchr(name, '@'))) {
- *c++ = '\0';
- domain = c;
- if ((c = strchr(domain, ':'))) /* Remove :port */
- *c = '\0';
- if (!AST_LIST_EMPTY(&domain_list)) {
- if (!check_sip_domain(domain, NULL, 0)) {
- transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
- return AUTH_UNKNOWN_DOMAIN;
- }
- }
- }
- c = strchr(name, ';'); /* Remove any Username parameters */
- if (c)
- *c = '\0';
+ if (!ast_strlen_zero(domain) && !AST_LIST_EMPTY(&domain_list)) {
+ if (!check_sip_domain(domain, NULL, 0)) {
+ transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
+ return AUTH_UNKNOWN_DOMAIN;
+ }
+ }
ast_string_field_set(p, exten, name);
build_contact(p);
@@ -15330,10 +15323,9 @@
*/
static int get_destination(struct sip_pvt *p, struct sip_request *oreq, int *cc_recall_core_id)
{
- char tmp[256] = "", *uri, *a;
+ char tmp[256] = "", *uri, *domain;
char tmpf[256] = "", *from = NULL;
struct sip_request *req;
- char *colon;
char *decoded_uri;
req = oreq;
@@ -15344,19 +15336,17 @@
if (req->rlPart2)
ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp));
- if (sip_cfg.pedanticsipchecking)
- ast_uri_decode(tmp);
-
- uri = ast_strdupa(get_in_brackets(tmp));
-
- if (!strncasecmp(uri, "sip:", 4)) {
- uri += 4;
- } else if (!strncasecmp(uri, "sips:", 5)) {
- uri += 5;
- } else {
- ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri);
+ uri = get_in_brackets(tmp);
+
+ if (parse_uri(uri, "sip:,sips:", &uri, NULL, &domain, NULL, NULL, NULL)) {
+ ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri);
return -1;
}
+
+ SIP_PEDANTIC_DECODE(domain);
+ SIP_PEDANTIC_DECODE(uri);
+
+ ast_string_field_set(p, domain, domain);
/* Now find the From: caller ID and name */
/* XXX Why is this done in get_destination? Isn't it already done?
@@ -15364,46 +15354,17 @@
*/
ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
if (!ast_strlen_zero(tmpf)) {
- if (sip_cfg.pedanticsipchecking)
- ast_uri_decode(tmpf);
from = get_in_brackets(tmpf);
- }
-
- if (!ast_strlen_zero(from)) {
- if (!strncasecmp(from, "sip:", 4)) {
- from += 4;
- } else if (!strncasecmp(from, "sips:", 5)) {
- from += 5;
- } else {
- ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from);
+ if (parse_uri(from, "sip:,sips:", &from, NULL, &domain, NULL, NULL, NULL)) {
+ ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from);
return -1;
}
- if ((a = strchr(from, '@')))
- *a++ = '\0';
- else
- a = from; /* just a domain */
- from = strsep(&from, ";"); /* Remove userinfo options */
- a = strsep(&a, ";"); /* Remove URI options */
- ast_string_field_set(p, fromdomain, a);
- }
-
- /* Skip any options and find the domain */
-
- /* Get the target domain */
- if ((a = strchr(uri, '@'))) {
- *a++ = '\0';
- } else { /* No username part */
- a = uri;
- uri = "s"; /* Set extension to "s" */
- }
- colon = strchr(a, ':'); /* Remove :port */
- if (colon)
- *colon = '\0';
-
- uri = strsep(&uri, ";"); /* Remove userinfo options */
- a = strsep(&a, ";"); /* Remove URI options */
-
- ast_string_field_set(p, domain, a);
+
+ SIP_PEDANTIC_DECODE(from);
+ SIP_PEDANTIC_DECODE(domain);
+
+ ast_string_field_set(p, fromdomain, domain);
+ }
if (!AST_LIST_EMPTY(&domain_list)) {
char domain_context[AST_MAX_EXTENSION];
@@ -15592,9 +15553,6 @@
}
h_refer_to = ast_strdupa(p_refer_to);
refer_to = get_in_brackets(h_refer_to);
- if (sip_cfg.pedanticsipchecking)
- ast_uri_decode(refer_to);
-
if (!strncasecmp(refer_to, "sip:", 4)) {
refer_to += 4; /* Skip sip: */
} else if (!strncasecmp(refer_to, "sips:", 5)) {
@@ -15619,8 +15577,6 @@
if (!ast_strlen_zero(p_referred_by)) {
char *lessthan;
h_referred_by = ast_strdupa(p_referred_by);
- if (sip_cfg.pedanticsipchecking)
- ast_uri_decode(h_referred_by);
/* Store referrer's caller ID name */
ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
@@ -15629,6 +15585,7 @@
}
referred_by_uri = get_in_brackets(h_referred_by);
+
if (!strncasecmp(referred_by_uri, "sip:", 4)) {
referred_by_uri += 4; /* Skip sip: */
} else if (!strncasecmp(referred_by_uri, "sips:", 5)) {
@@ -15646,7 +15603,6 @@
/* This is an attended transfer */
referdata->attendedtransfer = 1;
ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
- ast_uri_decode(referdata->replaces_callid);
if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ {
*ptr++ = '\0';
}
@@ -15664,6 +15620,7 @@
*to = '\0';
if ((to = strchr(ptr, ';')))
*to = '\0';
+ ast_uri_decode(ptr);
ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
}
@@ -15673,6 +15630,7 @@
*to = '\0';
if ((to = strchr(ptr, ';')))
*to = '\0';
+ ast_uri_decode(ptr);
ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
}
@@ -15693,19 +15651,26 @@
if ((ptr = strchr(domain, ':'))) /* Remove :port */
*ptr = '\0';
+ SIP_PEDANTIC_DECODE(domain);
+ SIP_PEDANTIC_DECODE(urioption);
+
/* Save the domain for the dial plan */
ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
- if (urioption)
+ if (urioption) {
ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
+ }
}
if ((ptr = strchr(refer_to, ';'))) /* Remove options */
*ptr = '\0';
+
+ SIP_PEDANTIC_DECODE(refer_to);
ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
if (referred_by_uri) {
if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */
*ptr = '\0';
+ SIP_PEDANTIC_DECODE(referred_by_uri);
ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
} else {
referdata->referred_by[0] = '\0';
@@ -15757,26 +15722,18 @@
ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
c = get_in_brackets(tmp);
- if (sip_cfg.pedanticsipchecking)
- ast_uri_decode(c);
-
- if (!strncasecmp(c, "sip:", 4)) {
- c += 4;
- } else if (!strncasecmp(c, "sips:", 5)) {
- c += 5;
- } else {
+ if (parse_uri(c, "sip:,sips:", &c, NULL, &a, NULL, NULL, NULL)) {
ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c);
return -1;
}
-
- if ((a = strchr(c, ';'))) /* Remove arguments */
- *a = '\0';
- if ((a = strchr(c, '@'))) { /* Separate Domain */
- *a++ = '\0';
+ SIP_PEDANTIC_DECODE(c);
+ SIP_PEDANTIC_DECODE(a);
+
+ if (!ast_strlen_zero(a)) {
ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
}
-
+
if (sip_debug_test_pvt(p))
ast_verbose("Looking for %s in %s\n", c, p->context);
@@ -15903,48 +15860,185 @@
}
}
-/*! \brief Get caller id name from SIP headers */
-static char *get_calleridname(const char *input, char *output, size_t outputsize)
-{
- const char *end = strchr(input, '<'); /* first_bracket */
- const char *tmp = strchr(input, '"'); /* first quote */
- int bytes = 0;
- int maxbytes = outputsize - 1;
-
- if (!end || end == input) /* we require a part in brackets */
- return NULL;
-
- end--; /* move just before "<" */
-
- if (tmp && tmp <= end) {
- /* The quote (tmp) precedes the bracket (end+1).
- * Find the matching quote and return the content.
- */
- end = strchr(tmp+1, '"');
- if (!end)
- return NULL;
- bytes = (int) (end - tmp);
- /* protect the output buffer */
- if (bytes > maxbytes)
- bytes = maxbytes;
- ast_copy_string(output, tmp + 1, bytes);
- } else {
- /* No quoted string, or it is inside brackets. */
- /* clear the empty characters in the begining*/
- input = ast_skip_blanks(input);
- /* clear the empty characters in the end */
- while(*end && *end < 33 && end > input)
- end--;
- if (end >= input) {
- bytes = (int) (end - input) + 2;
- /* protect the output buffer */
- if (bytes > maxbytes)
- bytes = maxbytes;
- ast_copy_string(output, input, bytes);
- } else
- return NULL;
- }
- return output;
+/*! \brief Get caller id name from SIP headers, copy into output buffer
+ *
+ * \retval input string pointer placed after display-name field if possible
+ */
+static const char *get_calleridname(const char *input, char *output, size_t outputsize)
+{
+ /* From RFC3261:
+ *
+ * From = ( "From" / "f" ) HCOLON from-spec
+ * from-spec = ( name-addr / addr-spec ) *( SEMI from-param )
+ * name-addr = [ display-name ] LAQUOT addr-spec RAQUOT
+ * display-name = *(token LWS)/ quoted-string
+ * token = 1*(alphanum / "-" / "." / "!" / "%" / "*"
+ * / "_" / "+" / "`" / "'" / "~" )
+ * quoted-string = SWS DQUOTE *(qdtext / quoted-pair ) DQUOTE
+ * qdtext = LWS / %x21 / %x23-5B / %x5D-7E
+ * / UTF8-NONASCII
+ * quoted-pair = "\" (%x00-09 / %x0B-0C / %x0E-7F)
+ *
+ * HCOLON = *WSP ":" SWS
+ * SWS = [LWS]
+ * LWS = *[*WSP CRLF] 1*WSP
+ * WSP = (SP / HTAB)
+ *
+ * Deviations from it:
+ * - following CRLF's in LWS is not done (here at least)
+ * - ascii NUL is never legal as it terminates the C-string
+ * - utf8-nonascii is not checked for validity
+ */
+ char *orig_output = output;
+ const char *orig_input = input;
+
+ /* clear any empty characters in the beginning */
+ input = ast_skip_blanks(input);
+
+ /* no data at all or no storage room? */
+ if (!input || *input == '<' || !outputsize || !output) {
+ return orig_input;
+ }
+
+ /* make sure the output buffer is initilized */
+ *orig_output = '\0';
+
+ /* make room for '\0' at the end of the output buffer */
+ outputsize--;
+
+ /* quoted-string rules */
+ if (input[0] == '"') {
+ input++; /* skip the first " */
+
+ for (;((outputsize > 0) && *input); input++) {
+ if (*input == '"') { /* end of quoted-string */
+ break;
+ } else if (*input == 0x5c) { /* quoted-pair = "\" (%x00-09 / %x0B-0C / %x0E-7F) */
+ input++;
+ if (!*input || (unsigned char)*input > 0x7f || *input == 0xa || *input == 0xd) {
+ continue; /* not a valid quoted-pair, so skip it */
+ }
+ } else if (((*input != 0x9) && ((unsigned char) *input < 0x20)) ||
+ (*input == 0x7f)) {
+ continue; /* skip this invalid character. */
+ }
+
+ *output++ = *input;
+ outputsize--;
+ }
+
+ /* if this is successful, input should be at the ending quote */
+ if (!input || *input != '"') {
+ ast_log(LOG_WARNING, "No ending quote for display-name was found\n");
+ *orig_output = '\0';
+ return orig_input;
+ }
+
+ /* make sure input is past the last quote */
+ input++;
+
+ /* terminate outbuf */
+ *output = '\0';
+ } else { /* either an addr-spec or tokenLWS-combo */
+ for (;((outputsize > 0) && *input); input++) {
+ /* token or WSP (without LWS) */
+ if ((*input >= '0' && *input <= '9') || (*input >= 'A' && *input <= 'Z')
+ || (*input >= 'a' && *input <= 'z') || *input == '-' || *input == '.'
+ || *input == '!' || *input == '%' || *input == '*' || *input == '_'
+ || *input == '+' || *input == '`' || *input == '\'' || *input == '~'
+ || *input == 0x9 || *input == ' ') {
+ *output++ = *input;
+ outputsize -= 1;
+ } else if (*input == '<') { /* end of tokenLWS-combo */
+ /* we could assert that the previous char is LWS, but we don't care */
+ break;
+ } else if (*input == ':') {
+ /* This invalid character which indicates this is addr-spec rather than display-name. */
+ *orig_output = '\0';
+ return orig_input;
+ } else { /* else, invalid character we can skip. */
+ continue; /* skip this character */
+ }
+ }
+
+ /* set NULL while trimming trailing whitespace */
+ do {
+ *output-- = '\0';
+ } while (*output == 0x9 || *output == ' '); /* we won't go past orig_output as first was a non-space */
+ }
+
+ return input;
+}
+
+AST_TEST_DEFINE(get_calleridname_test)
+{
+ int res = AST_TEST_PASS;
+ const char *in1 = "\" quoted-text internal \\\" quote \"<stuff>";
+ const char *in2 = " token text with no quotes <stuff>";
+ const char *overflow1 = " \"quoted-text overflow 1234567890123456789012345678901234567890\" <stuff>";
+ const char *noendquote = " \"quoted-text no end <stuff>";
+ const char *addrspec = " \"sip:blah at blah <stuff>";
+ const char *after_dname;
+ char dname[40];
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "sip_get_calleridname_test";
+ info->category = "channels/chan_sip/";
+ info->summary = "decodes callerid name from sip header";
+ info->description = "Decodes display-name field of sip header. Checks for valid output and expected failure cases.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ /* quoted-text with backslash escaped quote */
+ after_dname = get_calleridname(in1, dname, sizeof(dname));
+ ast_test_status_update(&args->status_update, "display-name1: %s\nafter: %s\n", dname, after_dname);
+ if (strcmp(dname, " quoted-text internal \" quote ")) {
+ ast_test_status_update(&args->status_update, "display-name1 test failed\n");
+ ast_str_append(&args->ast_test_error_str, 0, "quoted-text with internal backslash decode failed. \n");
+ res = AST_TEST_FAIL;
+ }
+
+ /* token text */
+ after_dname = get_calleridname(in2, dname, sizeof(dname));
+ ast_test_status_update(&args->status_update, "display-name2: %s\nafter: %s\n", dname, after_dname);
+ if (strcmp(dname, "token text with no quotes")) {
+ ast_test_status_update(&args->status_update, "display-name2 test failed\n");
+ ast_str_append(&args->ast_test_error_str, 0, "token text with decode failed. \n");
+ res = AST_TEST_FAIL;
+ }
+
+ /* quoted-text buffer overflow */
+ after_dname = get_calleridname(overflow1, dname, sizeof(dname));
+ ast_test_status_update(&args->status_update, "overflow display-name1: %s\nafter: %s\n", dname, after_dname);
+ if (*dname != '\0' && after_dname != overflow1) {
+ ast_test_status_update(&args->status_update, "overflow display-name1 test failed\n");
+ ast_str_append(&args->ast_test_error_str, 0, "quoted-text buffer overflow check failed. \n");
+ res = AST_TEST_FAIL;
+ }
+
+ /* quoted-text buffer with no terminating end quote */
+ after_dname = get_calleridname(noendquote, dname, sizeof(dname));
+ ast_test_status_update(&args->status_update, "noendquote display-name1: %s\nafter: %s\n", dname, after_dname);
+ if (*dname != '\0' && after_dname != noendquote) {
+ ast_test_status_update(&args->status_update, "no end quote for quoted-text display-name failed\n");
+ ast_str_append(&args->ast_test_error_str, 0, "quoted-text buffer check no terminating end quote failed. \n");
+ res = AST_TEST_FAIL;
+ }
+
+ /* addr-spec rather than display-name. */
+ after_dname = get_calleridname(addrspec, dname, sizeof(dname));
+ ast_test_status_update(&args->status_update, "noendquote display-name1: %s\nafter: %s\n", dname, after_dname);
+ if (*dname != '\0' && after_dname != addrspec) {
+ ast_test_status_update(&args->status_update, "detection of addr-spec failed\n");
+ ast_str_append(&args->ast_test_error_str, 0, "detection of addr-spec failed. \n");
+ res = AST_TEST_FAIL;
+ }
+
+
+ return res;
}
@@ -16121,26 +16215,29 @@
int sipmethod, const char *uri, enum xmittype reliable,
struct sockaddr_in *sin, struct sip_peer **authpeer)
{
- char from[256];
+ char from[256] = { 0, };
char *dummy; /* dummy return value for parse_uri */
char *domain; /* dummy return value for parse_uri */
char *of;
- enum check_auth_result res;
+ enum check_auth_result res = AUTH_DONT_KNOW;
char calleridname[50];
char *uri2 = ast_strdupa(uri);
terminate_uri(uri2); /* trim extra stuff */
ast_copy_string(from, get_header(req, "From"), sizeof(from));
- if (sip_cfg.pedanticsipchecking)
- ast_uri_decode(from);
/* XXX here tries to map the username for invite things */
memset(calleridname, 0, sizeof(calleridname));
- get_calleridname(from, calleridname, sizeof(calleridname));
+
+ /* strip the display-name portion off the beginning of the FROM header. */
+ if (!(of = (char *) get_calleridname(from, calleridname, sizeof(calleridname)))) {
+ ast_log(LOG_ERROR, "FROM header can not be parsed \n");
+ return res;
+ }
+
if (calleridname[0])
ast_string_field_set(p, cid_name, calleridname);
- of = get_in_brackets(from);
if (ast_strlen_zero(p->exten)) {
char *t = uri2;
if (!strncasecmp(t, "sip:", 4))
@@ -16151,9 +16248,13 @@
t = strchr(p->exten, '@');
if (t)
*t = '\0';
+
if (ast_strlen_zero(p->our_contact))
build_contact(p);
}
+
+ of = get_in_brackets(of);
+
/* save the URI part of the From header */
ast_string_field_set(p, from, of);
@@ -16161,6 +16262,9 @@
if (parse_uri(of, "sip:,sips:", &of, &dummy, &domain, &dummy, &dummy, NULL)) {
ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
}
+
+ SIP_PEDANTIC_DECODE(of);
+ SIP_PEDANTIC_DECODE(domain);
if (ast_strlen_zero(of)) {
/* XXX note: the original code considered a missing @host
@@ -22267,7 +22371,6 @@
ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
/* Create a buffer we can manipulate */
replace_id = ast_strdupa(p_replaces);
- ast_uri_decode(replace_id);
if (!p->refer && !sip_refer_allocate(p)) {
transmit_response_reliable(p, "500 Server Internal Error", req);
@@ -22298,6 +22401,10 @@
fromtag = strsep(&fromtag, "&"); /* trim what ? */
}
}
+
+ ast_uri_decode(fromtag);
+ ast_uri_decode(totag);
+ ast_uri_decode(replace_id);
if (sipdebug)
ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n",
@@ -28925,6 +29032,18 @@
AST_CLI_DEFINE(sip_show_tcp, "List TCP Connections")
};
+/*! \brief SIP test registration */
+static void sip_register_tests(void)
+{
+ AST_TEST_REGISTER(get_calleridname_test);
+}
+
+/*! \brief SIP test registration */
+static void sip_unregister_tests(void)
+{
+ AST_TEST_UNREGISTER(get_calleridname_test);
+}
+
/*! \brief PBX load module - initialization */
static int load_module(void)
{
@@ -29034,6 +29153,9 @@
"lastms", RQ_INTEGER4, 11,
SENTINEL);
+
+ sip_register_tests();
+
return AST_MODULE_LOAD_SUCCESS;
}
@@ -29160,6 +29282,8 @@
ast_cc_monitor_unregister(&sip_cc_monitor_callbacks);
ast_cc_agent_unregister(&sip_cc_agent_callbacks);
+ sip_unregister_tests();
+
return 0;
}
Modified: team/group/CCSS/include/asterisk/utils.h
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/include/asterisk/utils.h?view=diff&rev=243220&r1=243219&r2=243220
==============================================================================
--- team/group/CCSS/include/asterisk/utils.h (original)
+++ team/group/CCSS/include/asterisk/utils.h Tue Jan 26 11:21:47 2010
@@ -248,22 +248,25 @@
*/
int ast_base64decode(unsigned char *dst, const char *src, int max);
-/*! \brief Turn text string to URI-encoded %XX version
-
-\note At this point, we're converting from ISO-8859-x (8-bit), not UTF8
- as in the SIP protocol spec
- If doreserved == 1 we will convert reserved characters also.
- RFC 2396, section 2.4
- outbuf needs to have more memory allocated than the instring
- to have room for the expansion. Every char that is converted
- is replaced by three ASCII characters.
- \param string String to be converted
- \param outbuf Resulting encoded string
- \param buflen Size of output buffer
- \param doreserved Convert reserved characters
-*/
-
-char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved);
+/*! \brief Turn text string to URI-encoded %XX version
+ *
+ * \note
+ * At this point, this function is encoding agnostic; it does not
+ * check whether it is fed legal UTF-8. We escape control
+ * characters (\x00-\x1F\x7F), '%', and all characters above 0x7F.
+ * If do_special_char == 1 we will convert all characters except alnum
+ * and the mark set.
+ * Outbuf needs to have more memory allocated than the instring
+ * to have room for the expansion. Every char that is converted
+ * is replaced by three ASCII characters.
+ *
+ * \param string String to be converted
+ * \param outbuf Resulting encoded string
+ * \param buflen Size of output buffer
+ * \param do_special_char Convert all non alphanum characters execept
+ * those in the mark set as defined by rfc 3261 section 25.1
+ */
+char *ast_uri_encode(const char *string, char *outbuf, int buflen, int do_special_char);
/*! \brief Decode URI, URN, URL (overwrite string)
\param s String to be decoded
@@ -755,4 +758,8 @@
*/
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
+/*!
+ * \brief Registers util api unit tests
+ */
+void ast_utils_register_tests(void);
#endif /* _ASTERISK_UTILS_H */
Modified: team/group/CCSS/main/test.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/test.c?view=diff&rev=243220&r1=243219&r2=243220
==============================================================================
--- team/group/CCSS/main/test.c (original)
+++ team/group/CCSS/main/test.c Tue Jan 26 11:21:47 2010
@@ -833,9 +833,6 @@
#ifdef TEST_FRAMEWORK
/* Register cli commands */
ast_cli_register_multiple(test_cli, ARRAY_LEN(test_cli));
-
- /* in the future this function could be used to register functions not
- * defined within a module */
#endif
return 0;
Modified: team/group/CCSS/main/utils.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/utils.c?view=diff&rev=243220&r1=243219&r2=243220
==============================================================================
--- team/group/CCSS/main/utils.c (original)
+++ team/group/CCSS/main/utils.c Tue Jan 26 11:21:47 2010
@@ -368,41 +368,44 @@
b2a[(int)'/'] = 63;
}
-/*! \brief ast_uri_encode: Turn text string to URI-encoded %XX version
-\note At this point, we're converting from ISO-8859-x (8-bit), not UTF8
- as in the SIP protocol spec
- If doreserved == 1 we will convert reserved characters also.
- RFC 2396, section 2.4
- outbuf needs to have more memory allocated than the instring
- to have room for the expansion. Every char that is converted
- is replaced by three ASCII characters.
-
- Note: The doreserved option is needed for replaces header in
- SIP transfers.
-*/
-char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved)
-{
- char *reserved = ";/?:@&=+$,# "; /* Reserved chars */
-
- const char *ptr = string; /* Start with the string */
+/*! \brief Turn text string to URI-encoded %XX version
+ *
+ * \note
+ * At this point, this function is encoding agnostic; it does not
+ * check whether it is fed legal UTF-8. We escape control
+ * characters (\x00-\x1F\x7F), '%', and all characters above 0x7F.
+ * If do_special_char == 1 we will convert all characters except alnum
+ * and mark.
+ * Outbuf needs to have more memory allocated than the instring
+ * to have room for the expansion. Every char that is converted
+ * is replaced by three ASCII characters.
+ */
+char *ast_uri_encode(const char *string, char *outbuf, int buflen, int do_special_char)
+{
+ const char *ptr = string; /* Start with the string */
char *out = NULL;
char *buf = NULL;
-
+ const char *mark = "-_.!~*'()"; /* no encode set, RFC 2396 section 2.3, RFC 3261 sec 25 */
ast_copy_string(outbuf, string, buflen);
- /* If there's no characters to convert, just go through and don't do anything */
while (*ptr) {
- if ((*ptr < 32) || (doreserved && strchr(reserved, *ptr))) {
+ if ((const signed char) *ptr < 32 || *ptr == 0x7f || *ptr == '%' ||
+ (do_special_char &&
+ !(*ptr >= '0' && *ptr <= '9') && /* num */
+ !(*ptr >= 'A' && *ptr <= 'Z') && /* ALPHA */
+ !(*ptr >= 'a' && *ptr <= 'z') && /* alpha */
+ !strchr(mark, *ptr))) { /* mark set */
+
/* Oops, we need to start working here */
if (!buf) {
buf = outbuf;
out = buf + (ptr - string) ; /* Set output ptr */
}
- out += sprintf(out, "%%%02x", (unsigned char) *ptr);
+ out += sprintf(out, "%%%02X", (unsigned char) *ptr);
} else if (buf) {
*out = *ptr; /* Continue copying the string */
out++;
- }
+ }
ptr++;
}
if (buf)
More information about the asterisk-commits
mailing list