From 31d42235239a1291a599b84cc352b7b5b53448b7 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Mon, 3 Jul 2006 22:08:47 +0000 Subject: Various performance improvements in PJSIP: (1) optimizing for common case to minimize stricmp() calls (header names, method, URI schemes), (2) added functionality in scanner to parse and unescape in-place, (3) etc.. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@583 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib-util/include/pjlib-util/scanner.h | 13 +++ pjlib-util/src/pjlib-util/scanner.c | 59 ++++++++++ pjlib-util/src/pjlib-util/scanner_cis_uint.c | 2 + pjlib/src/pj/hash.c | 11 ++ pjsip-apps/build/sample_debug.dsp | 5 +- pjsip/build/test_pjsip.dsp | 2 +- pjsip/include/pjsip/sip_config.h | 17 +++ pjsip/include/pjsip/sip_parser.h | 4 + pjsip/src/pjsip/sip_msg.c | 4 +- pjsip/src/pjsip/sip_parser.c | 161 ++++++++++++++++++++------- pjsip/src/pjsip/sip_tel_uri.c | 4 + pjsip/src/pjsip/sip_uri.c | 2 + pjsip/src/test-pjsip/msg_test.c | 3 +- 13 files changed, 242 insertions(+), 45 deletions(-) diff --git a/pjlib-util/include/pjlib-util/scanner.h b/pjlib-util/include/pjlib-util/scanner.h index eb9135fe..57cdced9 100644 --- a/pjlib-util/include/pjlib-util/scanner.h +++ b/pjlib-util/include/pjlib-util/scanner.h @@ -331,6 +331,19 @@ PJ_DECL(void) pj_scan_get( pj_scanner *scanner, const pj_cis_t *spec, pj_str_t *out); +/** + * Just like #pj_scan_get(), but additionally performs unescaping when + * escaped ('%') character is found. The input spec MUST NOT contain the + * specification for '%' characted. + * + * @param scanner The scanner. + * @param spec The spec to match input string. + * @param out String to store the result. + */ +PJ_DECL(void) pj_scan_get_unescape( pj_scanner *scanner, + const pj_cis_t *spec, pj_str_t *out); + + /** * Get characters between quotes. If current input doesn't match begin_quote, * syntax error will be thrown. Note that the resulting string will contain diff --git a/pjlib-util/src/pjlib-util/scanner.c b/pjlib-util/src/pjlib-util/scanner.c index 676fd026..cd2a54b2 100644 --- a/pjlib-util/src/pjlib-util/scanner.c +++ b/pjlib-util/src/pjlib-util/scanner.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include #include @@ -282,6 +283,64 @@ PJ_DEF(void) pj_scan_get( pj_scanner *scanner, } +PJ_DEF(void) pj_scan_get_unescape( pj_scanner *scanner, + const pj_cis_t *spec, pj_str_t *out) +{ + register char *s = scanner->curptr; + char *dst = s; + + pj_assert(pj_cis_match(spec,0)==0); + + /* Must not match character '%' */ + pj_assert(pj_cis_match(spec,'%')==0); + + /* EOF is detected implicitly */ + if (!pj_cis_match(spec, *s) && *s != '%') { + pj_scan_syntax_err(scanner); + return; + } + + out->ptr = s; + do { + if (*s == '%') { + if (s+3 <= scanner->end) { + /* This doesn't check if the hex digits are valid. + * If they dont' it will produce garbage characters, but + * no harm is done to the application (e.g. no illegal + * memory access. + */ + *dst = (pj_uint8_t) ((pj_hex_digit_to_val(*(s+1)) << 4) + + pj_hex_digit_to_val(*(s+2))); + ++dst; + s += 3; + } else { + *dst++ = *s++; + *dst++ = *s++; + break; + } + } + + if (pj_cis_match(spec, *s)) { + char *start = s; + do { + ++s; + } while (pj_cis_match(spec, *s)); + + if (dst != start) pj_memmove(dst, start, s-start); + dst += (s-start); + } + + } while (*s == '%'); + + scanner->curptr = s; + out->slen = (dst - out->ptr); + + if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) { + pj_scan_skip_whitespace(scanner); + } +} + + PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner, int begin_quote, int end_quote, pj_str_t *out) diff --git a/pjlib-util/src/pjlib-util/scanner_cis_uint.c b/pjlib-util/src/pjlib-util/scanner_cis_uint.c index 41599835..c12425d5 100644 --- a/pjlib-util/src/pjlib-util/scanner_cis_uint.c +++ b/pjlib-util/src/pjlib-util/scanner_cis_uint.c @@ -26,10 +26,12 @@ PJ_DEF(void) pj_cis_buf_init( pj_cis_buf_t *cis_buf) { /* Do nothing. */ + PJ_UNUSED_ARG(cis_buf); } PJ_DEF(pj_status_t) pj_cis_init(pj_cis_buf_t *cis_buf, pj_cis_t *cis) { + PJ_UNUSED_ARG(cis_buf); pj_bzero(cis->cis_buf, sizeof(cis->cis_buf)); return PJ_SUCCESS; } diff --git a/pjlib/src/pj/hash.c b/pjlib/src/pj/hash.c index 1f86317b..10ad9d97 100644 --- a/pjlib/src/pj/hash.c +++ b/pjlib/src/pj/hash.c @@ -75,10 +75,21 @@ PJ_DEF(pj_uint32_t) pj_hash_calc_tolower( pj_uint32_t hval, { long i; +#if defined(PJ_HASH_USE_OWN_TOLOWER) && PJ_HASH_USE_OWN_TOLOWER != 0 + for (i=0; islen; ++i) { + pj_uint8_t c = key->ptr[i]; + if (c & 64) + result[i] = (char)(c | 32); + else + result[i] = (char)c; + hval = hval * PJ_HASH_MULTIPLIER + result[i]; + } +#else for (i=0; islen; ++i) { result[i] = (char)pj_tolower(key->ptr[i]); hval = hval * PJ_HASH_MULTIPLIER + result[i]; } +#endif return hval; } diff --git a/pjsip-apps/build/sample_debug.dsp b/pjsip-apps/build/sample_debug.dsp index 1cf451c4..8b7ff9fe 100644 --- a/pjsip-apps/build/sample_debug.dsp +++ b/pjsip-apps/build/sample_debug.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "../../pjsip/include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c +# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../../pjsip/include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" @@ -51,7 +51,8 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /map /machine:I386 /out:"../bin/samples/sampledebug_vc6.exe" +# ADD LINK32 ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /map /debug /machine:I386 /out:"../bin/samples/sampledebug_vc6.exe" /fixed:no +# SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "sample_debug - Win32 Debug" diff --git a/pjsip/build/test_pjsip.dsp b/pjsip/build/test_pjsip.dsp index 418ee8a8..82f10ac3 100644 --- a/pjsip/build/test_pjsip.dsp +++ b/pjsip/build/test_pjsip.dsp @@ -51,7 +51,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib netapi32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /profile /map /debug /machine:I386 /out:"..\bin\test-pjsip-i386-win32-vc6-release.exe" +# ADD LINK32 dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib netapi32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /profile /map /debug /machine:I386 /out:"..\bin\test-pjsip-i386-win32-vc6-release.exe" /fixed:no !ELSEIF "$(CFG)" == "test_pjsip - Win32 Debug" diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h index 535f6697..2d635d62 100644 --- a/pjsip/include/pjsip/sip_config.h +++ b/pjsip/include/pjsip/sip_config.h @@ -130,6 +130,23 @@ #endif +/** + * If non-zero, SIP parser will unescape the escape characters ('%') + * in the original message, which means that it will modify the + * original message. Otherwise the parser will create a copy of + * the string and store the unescaped string to the new location. + * + * Unescaping in-place is faster, but less elegant (and it may + * break certain applications). So normally it's disabled, unless + * when benchmarking (to show off big performance). + * + * Default: 0 + */ +#ifndef PJSIP_UNESCAPE_IN_PLACE +# define PJSIP_UNESCAPE_IN_PLACE 0 +#endif + + /* Endpoint. */ #define PJSIP_MAX_TIMER_COUNT (2*PJSIP_MAX_TSX_COUNT + 2*PJSIP_MAX_DIALOG_COUNT) diff --git a/pjsip/include/pjsip/sip_parser.h b/pjsip/include/pjsip/sip_parser.h index b9e752f0..54dd52df 100644 --- a/pjsip/include/pjsip/sip_parser.h +++ b/pjsip/include/pjsip/sip_parser.h @@ -315,10 +315,14 @@ extern pj_cis_t pjsip_HEX_SPEC, /**< Hexadecimal digits. */ pjsip_PARAM_CHAR_SPEC, /**< For scanning pname (or pvalue when it's not quoted.) */ + pjsip_PARAM_CHAR_SPEC_ESC, /**< Variant without the escape ('%') char */ pjsip_HDR_CHAR_SPEC, /**< Chars in hname/havalue in URL. */ + pjsip_HDR_CHAR_SPEC_ESC, /**< Variant without the escape ('%') char */ pjsip_PROBE_USER_HOST_SPEC, /**< Hostname characters. */ pjsip_PASSWD_SPEC, /**< Password. */ + pjsip_PASSWD_SPEC_ESC, /**< Variant without the escape ('%') char */ pjsip_USER_SPEC, /**< User */ + pjsip_USER_SPEC_ESC, /**< Variant without the escape ('%') char */ pjsip_NOT_NEWLINE, /**< For eating up header, basicly any chars except newlines or zero. */ pjsip_NOT_COMMA_OR_NEWLINE, /**< Array elements. */ diff --git a/pjsip/src/pjsip/sip_msg.c b/pjsip/src/pjsip/sip_msg.c index 38603bc1..d6a33339 100644 --- a/pjsip/src/pjsip/sip_msg.c +++ b/pjsip/src/pjsip/sip_msg.c @@ -196,7 +196,9 @@ PJ_DEF(void) pjsip_method_init_np(pjsip_method *m, { int i; for (i=0; iptr, method_names[i]->ptr, str->slen)==0 || + pj_stricmp(str, method_names[i])==0) + { m->id = (pjsip_method_e)i; m->name = *method_names[i]; return; diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c index ab6144fd..a0ef3adc 100644 --- a/pjsip/src/pjsip/sip_parser.c +++ b/pjsip/src/pjsip/sip_parser.c @@ -115,10 +115,14 @@ pj_cis_t pjsip_HOST_SPEC, /* For scanning host part. */ pjsip_HEX_SPEC, /* Hexadecimal digits. */ pjsip_PARAM_CHAR_SPEC, /* For scanning pname (or pvalue when * it's not quoted.) */ + pjsip_PARAM_CHAR_SPEC_ESC, /* The variant without escaped char */ pjsip_HDR_CHAR_SPEC, /* Chars in hname or hvalue */ + pjsip_HDR_CHAR_SPEC_ESC, /* Variant without escaped char */ pjsip_PROBE_USER_HOST_SPEC, /* Hostname characters. */ pjsip_PASSWD_SPEC, /* Password. */ + pjsip_PASSWD_SPEC_ESC, /* Variant without escaped char */ pjsip_USER_SPEC, /* User */ + pjsip_USER_SPEC_ESC, /* Variant without escaped char */ pjsip_NOT_COMMA_OR_NEWLINE, /* Array separator. */ pjsip_NOT_NEWLINE, /* For eating up header.*/ pjsip_DISPLAY_SPEC; /* Used when searching for display name @@ -201,7 +205,26 @@ static unsigned long pj_strtoul_mindigit(const pj_str_t *str, } /* Case insensitive comparison */ -#define parser_stricmp(s1, s2) (pj_stricmp_alnum(&s1, &s2)) +#define parser_stricmp(s1, s2) (s1.slen!=s2.slen || pj_stricmp_alnum(&s1, &s2)) + + +/* Get a token and unescape */ +PJ_INLINE(void) parser_get_and_unescape(pj_scanner *scanner, pj_pool_t *pool, + const pj_cis_t *spec, + const pj_cis_t *unesc_spec, + pj_str_t *token) +{ +#if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0 + PJ_UNUSED_ARG(pool); + PJ_UNUSED_ARG(spec); + pj_scan_get_unescape(scanner, unesc_spec, token); +#else + PJ_UNUSED_ARG(unesc_spec); + pj_scan_get(scanner, spec, token); + *token = pj_str_unescape(pool, token); +#endif +} + /* Syntax error handler for parser. */ @@ -313,18 +336,34 @@ static pj_status_t init_parser() PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); pj_cis_add_str(&pjsip_PARAM_CHAR_SPEC, PARAM_CHAR); + status = pj_cis_dup(&pjsip_PARAM_CHAR_SPEC_ESC, &pjsip_PARAM_CHAR_SPEC); + PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); + pj_cis_del_str(&pjsip_PARAM_CHAR_SPEC_ESC, ESCAPED); + status = pj_cis_dup(&pjsip_HDR_CHAR_SPEC, &pjsip_ALNUM_SPEC); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); pj_cis_add_str(&pjsip_HDR_CHAR_SPEC, HDR_CHAR); + status = pj_cis_dup(&pjsip_HDR_CHAR_SPEC_ESC, &pjsip_HDR_CHAR_SPEC); + PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); + pj_cis_del_str(&pjsip_HDR_CHAR_SPEC_ESC, ESCAPED); + status = pj_cis_dup(&pjsip_USER_SPEC, &pjsip_ALNUM_SPEC); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); pj_cis_add_str( &pjsip_USER_SPEC, UNRESERVED ESCAPED USER_UNRESERVED ); + status = pj_cis_dup(&pjsip_USER_SPEC_ESC, &pjsip_USER_SPEC); + PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); + pj_cis_del_str( &pjsip_USER_SPEC_ESC, ESCAPED); + status = pj_cis_dup(&pjsip_PASSWD_SPEC, &pjsip_ALNUM_SPEC); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); pj_cis_add_str( &pjsip_PASSWD_SPEC, UNRESERVED ESCAPED PASS); + status = pj_cis_dup(&pjsip_PASSWD_SPEC_ESC, &pjsip_PASSWD_SPEC); + PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); + pj_cis_del_str( &pjsip_PASSWD_SPEC, ESCAPED); + status = pj_cis_init(&cis_buf, &pjsip_PROBE_USER_HOST_SPEC); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); pj_cis_add_str( &pjsip_PROBE_USER_HOST_SPEC, "@ \n>"); @@ -459,7 +498,7 @@ PJ_INLINE(int) compare_handler( const handler_rec *r1, */ /* Equal length and equal hash. compare the strings. */ - return pj_ansi_strcmp(r1->hname, name); + return pj_memcmp(r1->hname, name, name_len); } /* Register one handler for one header name. */ @@ -468,9 +507,9 @@ static pj_status_t int_register_parser( const char *name, { unsigned pos; handler_rec rec; - unsigned i; if (handler_count >= PJ_ARRAY_SIZE(handler)) { + pj_assert(!"Too many handlers!"); return PJ_ETOOMANY; } @@ -481,13 +520,12 @@ static pj_status_t int_register_parser( const char *name, pj_assert(!"Header name is too long!"); return PJ_ENAMETOOLONG; } - /* Name is copied in lowercase. */ - for (i=0; i PJSIP_MAX_HNAME_LEN) { + pj_assert(!"Header name is too long!"); + return PJ_ENAMETOOLONG; + } + + /* Register the normal Mixed-Case name */ status = int_register_parser(hname, fptr); if (status != PJ_SUCCESS) { return status; } + + /* Get the lower-case name */ + for (i=0; islen >= PJSIP_MAX_HNAME_LEN) { - /* Guaranteed not to be able to find handler. */ - return NULL; - } - - /* Calculate hash value while converting the header to lowercase. - * Don't assume that 'hname' is NULL terminated. - */ - hash = pj_hash_calc_tolower(0, hname_copy, hname); - hname_copy[hname->slen] = '\0'; - /* Binary search for the handler. */ comp = -1; first = &handler[0]; @@ -564,7 +616,7 @@ static pjsip_parse_hdr_func * find_handler(const pj_str_t *hname) unsigned half = n / 2; handler_rec *mid = first + half; - comp = compare_handler(mid, hname_copy, hname->slen, hash); + comp = compare_handler(mid, hname->ptr, hname->slen, hash); if (comp < 0) { first = ++mid; n -= half + 1; @@ -579,12 +631,43 @@ static pjsip_parse_hdr_func * find_handler(const pj_str_t *hname) return comp==0 ? first->handler : NULL; } + +/* Find handler to parse the header name. */ +static pjsip_parse_hdr_func* find_handler(const pj_str_t *hname) +{ + pj_uint32_t hash; + char hname_copy[PJSIP_MAX_HNAME_LEN]; + pj_str_t tmp; + pjsip_parse_hdr_func *handler; + + if (hname->slen >= PJSIP_MAX_HNAME_LEN) { + /* Guaranteed not to be able to find handler. */ + return NULL; + } + + /* First, common case, try to find handler with exact name */ + hash = pj_hash_calc(0, hname->ptr, hname->slen); + handler = find_handler_imp(hash, hname); + if (handler) + return handler; + + + /* If not found, try converting the header name to lowercase and + * search again. + */ + hash = pj_hash_calc_tolower(0, hname_copy, hname); + tmp.ptr = hname_copy; + tmp.slen = hname->slen; + return find_handler_imp(hash, &tmp); +} + + /* Find URI handler. */ static pjsip_parse_uri_func* find_uri_handler(const pj_str_t *scheme) { unsigned i; for (i=0; iptr = NULL; @@ -980,8 +1063,8 @@ void pjsip_parse_param_imp( pj_scanner *scanner, pj_pool_t *pool, pvalue->slen -= 2; } } else if(pj_cis_match(&pjsip_PARAM_CHAR_SPEC, *scanner->curptr)) { - pj_scan_get(scanner, &pjsip_PARAM_CHAR_SPEC, pvalue); - *pvalue = pj_str_unescape(pool, pvalue); + parser_get_and_unescape(scanner, pool, &pjsip_PARAM_CHAR_SPEC, + &pjsip_PARAM_CHAR_SPEC_ESC, pvalue); } } } @@ -1007,8 +1090,8 @@ static void int_parse_hparam( pj_scanner *scanner, pj_pool_t *pool, pj_scan_get_char(scanner); /* hname */ - pj_scan_get(scanner, &pjsip_HDR_CHAR_SPEC, hname); - *hname = pj_str_unescape(pool, hname); + parser_get_and_unescape(scanner, pool, &pjsip_HDR_CHAR_SPEC, + &pjsip_HDR_CHAR_SPEC_ESC, hname); /* Init hvalue */ hvalue->ptr = NULL; @@ -1020,8 +1103,8 @@ static void int_parse_hparam( pj_scanner *scanner, pj_pool_t *pool, if (!pj_scan_is_eof(scanner) && pj_cis_match(&pjsip_HDR_CHAR_SPEC, *scanner->curptr)) { - pj_scan_get(scanner, &pjsip_HDR_CHAR_SPEC, hvalue); - *hvalue = pj_str_unescape(pool, hvalue); + parser_get_and_unescape(scanner, pool, &pjsip_HDR_CHAR_SPEC, + &pjsip_HDR_CHAR_SPEC, hvalue); } } } @@ -1063,13 +1146,13 @@ static int int_is_next_user(pj_scanner *scanner) static void int_parse_user_pass( pj_scanner *scanner, pj_pool_t *pool, pj_str_t *user, pj_str_t *pass) { - pj_scan_get( scanner, &pjsip_USER_SPEC, user); - *user = pj_str_unescape(pool, user); + parser_get_and_unescape(scanner, pool, &pjsip_USER_SPEC, + &pjsip_USER_SPEC_ESC, user); if ( *scanner->curptr == ':') { pj_scan_get_char( scanner ); - pj_scan_get( scanner, &pjsip_PASSWD_SPEC, pass); - *pass = pj_str_unescape(pool, pass); + parser_get_and_unescape(scanner, pool, &pjsip_PASSWD_SPEC, + &pjsip_PASSWD_SPEC_ESC, pass); } else { pass->ptr = NULL; pass->slen = 0; @@ -1435,7 +1518,7 @@ static void int_parse_contact_param( pjsip_contact_hdr *hdr, int_parse_param( scanner, pool, &pname, &pvalue); if (!parser_stricmp(pname, pjsip_Q_STR) && pvalue.slen) { - char *dot_pos = memchr(pvalue.ptr, '.', pvalue.slen); + char *dot_pos = pj_memchr(pvalue.ptr, '.', pvalue.slen); if (!dot_pos) { hdr->q1000 = pj_strtoul(&pvalue); } else { diff --git a/pjsip/src/pjsip/sip_tel_uri.c b/pjsip/src/pjsip/sip_tel_uri.c index fd43bc52..34d28b15 100644 --- a/pjsip/src/pjsip/sip_tel_uri.c +++ b/pjsip/src/pjsip/sip_tel_uri.c @@ -373,8 +373,12 @@ static void* tel_uri_parse( pj_scanner *scanner, pj_pool_t *pool, uri = pjsip_tel_uri_create(pool); /* Get the phone number. */ +#if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0 + pj_scan_get_unescape(scanner, &pjsip_TEL_NUMBER_SPEC, &uri->number); +#else pj_scan_get(scanner, &pjsip_TEL_NUMBER_SPEC, &uri->number); uri->number = pj_str_unescape(pool, &uri->number); +#endif /* Get all parameters. */ if (parse_params && *scanner->curptr==';') { diff --git a/pjsip/src/pjsip/sip_uri.c b/pjsip/src/pjsip/sip_uri.c index 37fd3c4f..ddb1e68a 100644 --- a/pjsip/src/pjsip/sip_uri.c +++ b/pjsip/src/pjsip/sip_uri.c @@ -103,6 +103,8 @@ PJ_DEF(pj_ssize_t) pjsip_param_print_on( const pjsip_param *param_list, startbuf = buf; endbuf = buf + size; + PJ_UNUSED_ARG(pname_spec); + do { *buf++ = (char)sep; copy_advance_escape(buf, p->name, (*pname_spec)); diff --git a/pjsip/src/test-pjsip/msg_test.c b/pjsip/src/test-pjsip/msg_test.c index f93539fe..d0039047 100644 --- a/pjsip/src/test-pjsip/msg_test.c +++ b/pjsip/src/test-pjsip/msg_test.c @@ -50,7 +50,7 @@ struct test_msg { /* 'Normal' message with all headers. */ "INVITE sip:user@foo SIP/2.0\n" - "From: Hi I'm Joe ;tag=123457890123456\r" + "from: Hi I'm Joe ;tag=123457890123456\r" "To: Fellow User \r\n" "Call-ID: 12345678901234567890@bar\r\n" "Content-Length: 0\r\n" @@ -790,7 +790,6 @@ int msg_test(void) char desc[250]; pj_status_t status; - status = simple_test(); if (status != PJ_SUCCESS) return status; -- cgit v1.2.3