diff options
author | dvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-01-26 16:30:08 +0000 |
---|---|---|
committer | dvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-01-26 16:30:08 +0000 |
commit | 1bc7ad599c3fb70a6d23f7334e2550dfd007c051 (patch) | |
tree | b4f37193aa43a729fdd7ab30df84eaffd4fbbf3b /main | |
parent | 7f9286a9d201a270f3c6410d58dfda2757af1d2b (diff) |
RFC compliant uri and display-name encode/decode
1. URI Encoding
This patch changes ast_uri_encode()'s behavior when doreserved is enabled.
Previously when doreserved was enabled only a small set of reserved
characters were encoded. This set was comprised primarily of the reserved
characters defined in RFC3261 section 25.1, but contained other characters as
well. Rather than only escaping the reserved set, doreserved now escapes
all characters not within the unreserved set as defined by RFC 3261 and
RFC 2396. Also, the 'doreserved' variable has been renamed to 'do_special_char'
in attempts to avoid confusion.
When doreserve is not enabled, the previous logic of only encoding the
characters <= 0X1F and > 0X7f remains, except for the '%' character, which
must always be encoded as it signifies a HEX escaped character during the decode
process.
2. URI Decoding: Break up URI before decode.
In chan_sip.c ast_uri_decode is called on the entire URI instead of it's
individual parts after it is parsed. This is not good as ast_uri_decode
can introduce special characters back into the URI which can mess up parsing.
This patch resolves this by not decoding a URI until parsing is completely
done. There are many instances where we check to see if pedantic checking
is enabled before we decode a URI. In these cases a new macro,
SIP_PEDANTIC_DECODE, is used on the individual parsed segments of the URI
rather than constantly putting if (pedantic) { decode() } checks everywhere
in the code. In the areas where ast_uri_decode is not dependent upon
pedantic checking this macro is not used, but decoding is still moved to
each individual part of the URI. The only behavior that should change from
this patch is the time at which decoding occurs.
Since I had to look over every place URI parsing occurs to create this
patch, I found several places where we use duplicate code for parsing.
To consolidate the code, those areas have updated to use the parse_uri()
function where possible.
3. SIP display-name decoding according to RFC3261 section 25.
To properly decode the display-name portion of a FROM header, chan_sip's
get_calleridname() function required a complete re-write. More information
about this change can be found in the comments at the beginning of this function.
4. Unit Tests.
Unit tests for ast_uri_encode, ast_uri_decode, and get_calleridname() have been
written. This involved the addition of the test_utils.c file for testing the
utils api.
(closes issue #16299)
Reported by: wdoekes
Patches:
astsvn-16299-get_calleridname.diff uploaded by wdoekes (license 717)
get_calleridname_rewrite.diff uploaded by dvossel (license 671)
Tested by: wdoekes, dvossel, Nick_Lewis
Review: https://reviewboard.asterisk.org/r/469/
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@243200 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r-- | main/test.c | 3 | ||||
-rw-r--r-- | main/utils.c | 45 |
2 files changed, 24 insertions, 24 deletions
diff --git a/main/test.c b/main/test.c index e0ccbe33b..754f77001 100644 --- a/main/test.c +++ b/main/test.c @@ -833,9 +833,6 @@ int ast_test_init() #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; diff --git a/main/utils.c b/main/utils.c index 86dcb0428..fcf3a4f75 100644 --- a/main/utils.c +++ b/main/utils.c @@ -368,41 +368,44 @@ static void base64_init(void) 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) +/*! \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) { - char *reserved = ";/?:@&=+$,# "; /* Reserved chars */ - - const char *ptr = string; /* Start with the string */ + 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) |