Index: include/asterisk/utils.h =================================================================== --- include/asterisk/utils.h (revision 231438) +++ include/asterisk/utils.h (working copy) @@ -250,10 +250,12 @@ /*! \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 +\note At this point, this function is encoding agnostic; it does not + check whether it is fed legal UTF-8. We escape control + characters and all characters above 0x7F. + If doreserved == 1 we will convert all characters except alnum + and mark (the unreserved characters, see RFC 2396, section 2.4 + and RFC 3261 25.1). 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. Index: main/utils.c =================================================================== --- main/utils.c (revision 231438) +++ main/utils.c (working copy) @@ -369,10 +369,12 @@ } /*! \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 +\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\x25\x7F) and all characters above 0x7F. + If doreserved == 1 we will convert all characters except alnum + and mark (the unreserved characters, see RFC 2396, section 2.4 + and RFC 3261 25.1). 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. @@ -382,7 +384,13 @@ */ char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved) { - char *reserved = ";/?:@&=+$,# "; /* Reserved chars */ + char *unreserved = +#if 0 /* see comparisons below */ + "01234567890" /* num */ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* alpha */ + "abcdefghijklmnopqrstuvwxyz" /* alpha */ +#endif + "-_.!~*'()"; /* mark */ const char *ptr = string; /* Start with the string */ char *out = NULL; @@ -390,9 +398,12 @@ ast_copy_string(outbuf, string, buflen); - /* If there's no characters to convert, just go through and don't do anything */ + /* If there are no characters to convert, just go through and don't do anything */ while (*ptr) { - if ((*ptr < 32 || (unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) { + if ((unsigned char)*ptr < 32 || (unsigned char)*ptr == '%' || (unsigned char)*ptr >= 0x7f || + (doreserved && !((*ptr >= '0' && *ptr <= '9') + (*ptr >= 'A' && *ptr <= 'Z') || (*ptr >= 'a' && *ptr <= 'z') + strchr(unreserved, *ptr) != NULL))) { /* Oops, we need to start working here */ if (!buf) { buf = outbuf;