diff options
author | Benny Prijono <bennylp@teluu.com> | 2005-11-22 23:51:50 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2005-11-22 23:51:50 +0000 |
commit | bf364b7c7deabe95dea0cf62180cdbf36c7c2031 (patch) | |
tree | 4e001db192608b4058476a8f686e25ab674d8676 /pjsip | |
parent | 2ddb744528ad991173650a2b6e3ff20796b3a748 (diff) |
More optimizations for msg parser etc.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@77 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/build/pjsip_core.dsp | 2 | ||||
-rw-r--r-- | pjsip/include/pjsip/print_util.h | 62 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_parser.h | 6 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_endpoint.c | 4 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_parser.c | 221 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_uri.c | 30 | ||||
-rw-r--r-- | pjsip/src/test-pjsip/msg.c | 16 | ||||
-rw-r--r-- | pjsip/src/test-pjsip/test.c | 4 |
8 files changed, 178 insertions, 167 deletions
diff --git a/pjsip/build/pjsip_core.dsp b/pjsip/build/pjsip_core.dsp index 11de7fd3..92a6353f 100644 --- a/pjsip/build/pjsip_core.dsp +++ b/pjsip/build/pjsip_core.dsp @@ -41,7 +41,7 @@ RSC=rc.exe # PROP Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /Zi /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
+# ADD CPP /nologo /MD /W4 /Zi /O2 /Oy /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
diff --git a/pjsip/include/pjsip/print_util.h b/pjsip/include/pjsip/print_util.h index b1362a72..c72d1ab2 100644 --- a/pjsip/include/pjsip/print_util.h +++ b/pjsip/include/pjsip/print_util.h @@ -19,53 +19,29 @@ #ifndef __PJSIP_PRINT_H__ #define __PJSIP_PRINT_H__ -/* Minimum space left in the buffer */ -#define MIN_SPACE 10 - #define copy_advance_check(buf,str) \ do { \ - if ((str).slen+MIN_SPACE >= (endbuf-buf)) return -1; \ + if ((str).slen >= (endbuf-buf)) return -1; \ pj_memcpy(buf, (str).ptr, (str).slen); \ buf += (str).slen; \ } while (0) -/* -static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, int len1, const pj_str_t *str2) -{ - if (str2->slen) { - int printed = len1+str2->slen; - if (printed+MIN_SPACE >= (endbuf-buf)) return NULL; - pj_memcpy(buf,str1,len1); - pj_memcpy(buf+len1, str2->ptr, str2->slen); - return buf + printed; - } else - return buf; -} -*/ - #define copy_advance_pair_check(buf,str1,len1,str2) \ do { \ if (str2.slen) { \ printed = len1+str2.slen; \ - if (printed+MIN_SPACE >= (endbuf-buf)) return -1; \ + if (printed >= (endbuf-buf)) return -1; \ pj_memcpy(buf,str1,len1); \ pj_memcpy(buf+len1, str2.ptr, str2.slen); \ buf += printed; \ } \ } while (0) -/* -#define copy_advance_pair(buf,str1,len1,str2) \ - do { \ - buf = imp_copy_advance_pair(buf, endbuf, str1, len1, &str2); \ - if (buf == NULL) return -1; \ - } while (0) -*/ #define copy_advance_pair_quote_check(buf,str1,len1,str2,quotebegin,quoteend) \ do { \ if (str2.slen) { \ printed = len1+str2.slen+2; \ - if (printed+MIN_SPACE >= (endbuf-buf)) return -1; \ + if (printed >= (endbuf-buf)) return -1; \ pj_memcpy(buf,str1,len1); \ *(buf+len1)=quotebegin; \ pj_memcpy(buf+len1+1, str2.ptr, str2.slen); \ @@ -76,16 +52,13 @@ static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, in #define copy_advance_pair_escape(buf,str1,len1,str2,unres) \ do { \ - if (str2.slen) { \ - pj_ssize_t esc_len; \ - if (len1+str2.slen+MIN_SPACE >= (endbuf-buf)) return -1; \ - pj_memcpy(buf,str1,len1); \ - buf += len1; \ - esc_len=pj_strncpy2_escape(buf, &str2, (endbuf-buf), &unres); \ - if (esc_len < 0) return -1; \ - buf += esc_len; \ - if (endbuf-buf < MIN_SPACE) return -1; \ - } \ + if (str2.slen) { \ + if (len1+str2.slen >= (endbuf-buf)) return -1; \ + pj_memcpy(buf,str1,len1); \ + printed=pj_strncpy2_escape(buf,&str2,(endbuf-buf-len1),&unres);\ + if (printed < 0) return -1; \ + buf += (printed+len1); \ + } \ } while (0) @@ -97,11 +70,10 @@ static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, in #define copy_advance_escape(buf,str,unres) \ do { \ - pj_ssize_t len = \ + printed = \ pj_strncpy2_escape(buf, &(str), (endbuf-buf), &(unres)); \ - if (len < 0) return -1; \ - buf += len; \ - if (endbuf-buf < MIN_SPACE) return -1; \ + if (printed < 0) return -1; \ + buf += printed; \ } while (0) #define copy_advance_pair_no_check(buf,str1,len1,str2) \ @@ -117,10 +89,10 @@ static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, in #define copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend) \ do { \ - if (str2.slen && *str2.ptr!=quotebegin) \ - copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \ - else \ - copy_advance_pair(buf,str1,len1,str2); \ + if (str2.slen && *str2.ptr!=quotebegin) \ + copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \ + else \ + copy_advance_pair(buf,str1,len1,str2); \ } while (0) /* diff --git a/pjsip/include/pjsip/sip_parser.h b/pjsip/include/pjsip/sip_parser.h index 389e6342..d6e46e5f 100644 --- a/pjsip/include/pjsip/sip_parser.h +++ b/pjsip/include/pjsip/sip_parser.h @@ -307,8 +307,10 @@ extern pj_cis_t pjsip_PROBE_USER_HOST_SPEC, /**< Hostname characters. */ pjsip_PASSWD_SPEC, /**< Password. */ pjsip_USER_SPEC, /**< User */ - pjsip_NEWLINE_OR_EOF_SPEC, /**< For eating up header.*/ - pjsip_DISPLAY_SCAN_SPEC; /**< Used when searching for display name. */ + pjsip_NOT_NEWLINE, /**< For eating up header, basicly any chars + except newlines or zero. */ + pjsip_NOT_COMMA_OR_NEWLINE, /**< Array elements. */ + pjsip_DISPLAY_SPEC; /**< Used when searching for display name. */ /* * Various string constants. diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c index 53311f36..79cd68a5 100644 --- a/pjsip/src/pjsip/sip_endpoint.c +++ b/pjsip/src/pjsip/sip_endpoint.c @@ -104,6 +104,7 @@ struct pjsip_endpoint static void endpt_transport_callback(pjsip_endpoint*, pj_status_t, pjsip_rx_data*); +void init_sip_parser(void); /* * This is the global handler for memory allocation failure, for pools that @@ -373,6 +374,9 @@ PJ_DEF(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf, endpt->pool = pool; endpt->pf = pf; + /* Init parser. */ + init_sip_parser(); + /* Get name. */ if (name != NULL) { pj_str_t temp; diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c index 49b735b9..6a9828c4 100644 --- a/pjsip/src/pjsip/sip_parser.c +++ b/pjsip/src/pjsip/sip_parser.c @@ -65,7 +65,6 @@ static handler_rec handler[127]; static unsigned handler_count; static int parser_is_initialized; - /* * Global vars (also extern). */ @@ -101,9 +100,9 @@ pj_cis_t pjsip_HOST_SPEC, /* For scanning host part. */ pjsip_PROBE_USER_HOST_SPEC, /* Hostname characters. */ pjsip_PASSWD_SPEC, /* Password. */ pjsip_USER_SPEC, /* User */ - pjsip_ARRAY_ELEMENTS, /* Array separator. */ - pjsip_NEWLINE_OR_EOF_SPEC, /* For eating up header.*/ - pjsip_DISPLAY_SCAN_SPEC; /* Used when searching for display name + pjsip_NOT_COMMA_OR_NEWLINE, /* Array separator. */ + pjsip_NOT_NEWLINE, /* For eating up header.*/ + pjsip_DISPLAY_SPEC; /* Used when searching for display name * in URL. */ @@ -258,14 +257,15 @@ static pj_status_t init_parser() pj_cis_add_alpha( &pjsip_ALNUM_SPEC ); pj_cis_add_num( &pjsip_ALNUM_SPEC ); - status = pj_cis_init(&cis_buf, &pjsip_NEWLINE_OR_EOF_SPEC); + status = pj_cis_init(&cis_buf, &pjsip_NOT_NEWLINE); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); - pj_cis_add_str(&pjsip_NEWLINE_OR_EOF_SPEC, "\r\n"); - //pj_cs_set(pjsip_NEWLINE_OR_EOF_SPEC, 0); + pj_cis_add_str(&pjsip_NOT_NEWLINE, "\r\n"); + pj_cis_invert(&pjsip_NOT_NEWLINE); - status = pj_cis_init(&cis_buf, &pjsip_ARRAY_ELEMENTS); + status = pj_cis_init(&cis_buf, &pjsip_NOT_COMMA_OR_NEWLINE); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); - pj_cis_add_str( &pjsip_ARRAY_ELEMENTS, ",\r\n"); + pj_cis_add_str( &pjsip_NOT_COMMA_OR_NEWLINE, ",\r\n"); + pj_cis_invert(&pjsip_NOT_COMMA_OR_NEWLINE); status = pj_cis_dup(&pjsip_TOKEN_SPEC, &pjsip_ALNUM_SPEC); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); @@ -300,9 +300,10 @@ static pj_status_t init_parser() pj_cis_add_str( &pjsip_PROBE_USER_HOST_SPEC, "@ \n>"); pj_cis_invert( &pjsip_PROBE_USER_HOST_SPEC ); - status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SCAN_SPEC); + status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SPEC); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); - pj_cis_add_str( &pjsip_DISPLAY_SCAN_SPEC, ":\r\n<"); + pj_cis_add_str( &pjsip_DISPLAY_SPEC, ":\r\n<"); + pj_cis_invert(&pjsip_DISPLAY_SPEC); status = pjsip_register_hdr_parser( "Accept", NULL, &parse_hdr_accept); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); @@ -374,7 +375,7 @@ static pj_status_t init_parser() return status; } -static void init_sip_parser(void) +void init_sip_parser(void) { if (!parser_is_initialized) { /* Prevent race cond. */ @@ -392,23 +393,27 @@ static void init_sip_parser(void) * - <0 if handler is 'less' than the header name. * - >0 if handler is 'greater' than header name. */ -static int compare_handler( const handler_rec *r1, +PJ_INLINE(int) compare_handler( const handler_rec *r1, const char *name, pj_size_t name_len, pj_uint32_t hash ) { - /* Compare length. */ - if (r1->hname_len < name_len) - return -1; - if (r1->hname_len > name_len) - return 1; + PJ_UNUSED_ARG(name_len); - /* Length is equal, compare hashed value. */ + /* Compare hashed value. */ if (r1->hname_hash < hash) return -1; if (r1->hname_hash > hash) return 1; + /* Compare length. */ + /* + if (r1->hname_len < name_len) + return -1; + if (r1->hname_len > name_len) + return 1; + */ + /* Equal length and equal hash. compare the strings. */ return pj_native_strcmp(r1->hname, name); } @@ -609,19 +614,20 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size, /* Find the end of header area by finding an empty line. */ - if ((pos = pj_native_strstr(buf, "\n\r\n")) == NULL) { + pos = pj_native_strstr(buf, "\n\r\n"); + if (pos == NULL) { return PJSIP_EPARTIALMSG; } - + hdr_end = pos+1; body_start = pos+3; /* Find "Content-Length" header the hard way. */ line = pj_native_strchr(buf, '\n'); - while (line && line < hdr_end-14) { + while (line && line < hdr_end) { ++line; if ( ((*line=='C' || *line=='c') && - pj_native_strncasecmp(line, "Content-Length", 14) == 0) || + strnicmp_alnum(line, "Content-Length", 14) == 0) || ((*line=='l' || *line=='L') && (*(line+1)==' ' || *(line+1)=='\t' || *(line+1)==':'))) { @@ -744,22 +750,20 @@ static int generic_print_body (pjsip_msg_body *msg_body, static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx, pjsip_parser_err_report *err_list) { - int ch; pjsip_msg *msg; + pj_str_t hname; pjsip_ctype_hdr *ctype_hdr = NULL; pj_scanner *scanner = ctx->scanner; pj_pool_t *pool = ctx->pool; PJ_USE_EXCEPTION; /* Skip leading newlines. */ - ch = *scanner->curptr; - while (ch=='\r' || ch=='\n') { - pj_scan_get_char(scanner); - ch = *scanner->curptr; + while (*scanner->curptr=='\r' || *scanner->curptr=='\n') { + pj_scan_get_newline(scanner); } /* Parse request or status line */ - if (pj_scan_stricmp( scanner, PJSIP_VERSION, 7) == 0) { + if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) == 0) { msg = pjsip_msg_create(pool, PJSIP_RESPONSE_MSG); int_parse_status_line( scanner, &msg->line.status ); } else { @@ -768,22 +772,23 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx, } /* Parse headers. */ - do { - pj_str_t hname; - pjsip_parse_hdr_func * handler; - pjsip_hdr *hdr = NULL; - - /* Get hname. */ - pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname); - ch = pj_scan_get_char( scanner ); - if (ch != ':') { - PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); - } +parse_headers: - /* Find handler. */ - handler = find_handler(&hname); - - PJ_TRY { + PJ_TRY + { + do { + pjsip_parse_hdr_func * handler; + pjsip_hdr *hdr = NULL; + + /* Get hname. */ + pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname); + if (pj_scan_get_char( scanner ) != ':') { + PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); + } + + /* Find handler. */ + handler = find_handler(&hname); + /* Call the handler if found. * If no handler is found, then treat the header as generic * hname/hvalue pair. @@ -795,46 +800,15 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx, hdr->type = PJSIP_H_OTHER; hdr->name = hdr->sname = hname; } - + /* Check if we've just parsed a Content-Type header. - * We will check for a message body if we've got Content-Type header. + * We will check for a message body if we've got Content-Type + * header. */ if (hdr->type == PJSIP_H_CONTENT_TYPE) { ctype_hdr = (pjsip_ctype_hdr*)hdr; } - - } - PJ_CATCH_ANY { - /* Exception was thrown during parsing. - * Skip until newline, and parse next header. - */ - pj_str_t token; - hdr = NULL; - - //PJ_LOG(4,("sipparser", - // "Syntax error in line %d col %d (hname=%.*s)", - // scanner->line, scanner->col, hname.slen, hname.ptr)); - - if (err_list) { - pjsip_parser_err_report *err_info; - err_info = pj_pool_alloc(pool, sizeof(*err_info)); - err_info->except_code = PJ_GET_EXCEPTION(); - err_info->line = scanner->line; - err_info->col = scanner->col; - err_info->hname = hname; - - pj_list_insert_before(err_list, err_info); - } - - if (!pj_scan_is_eof(scanner)) { - pj_scan_get_until(scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &token); - parse_hdr_end(scanner); - } - } - PJ_END; - - if (hdr) { /* Single parse of header line can produce multiple headers. * For example, if one Contact: header contains Contact list * separated by comma, then these Contacts will be split into @@ -842,11 +816,44 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx, * So here we must insert list instead of just insert one header. */ pj_list_insert_nodes_before(&msg->hdr, hdr); + + /* Parse until EOF or an empty line is found. */ + } while (!pj_scan_is_eof(scanner) && + *scanner->curptr != '\r' && *scanner->curptr != '\n'); + + } + PJ_CATCH_ANY + { + /* Exception was thrown during parsing. + * Skip until newline, and parse next header. + */ + pj_str_t token; + + if (err_list) { + pjsip_parser_err_report *err_info; + + err_info = pj_pool_alloc(pool, sizeof(*err_info)); + err_info->except_code = PJ_GET_EXCEPTION(); + err_info->line = scanner->line; + err_info->col = pj_scan_get_col(scanner); + err_info->hname = hname; + + pj_list_insert_before(err_list, err_info); + } + + if (!pj_scan_is_eof(scanner)) { + pj_scan_get(scanner, &pjsip_NOT_NEWLINE, &token); + parse_hdr_end(scanner); + } + + if (!pj_scan_is_eof(scanner) && + *scanner->curptr != '\r' && *scanner->curptr != '\n'); + { + goto parse_headers; } + } + PJ_END; - /* Parse until EOF or an empty line is found. */ - } while (!pj_scan_is_eof(scanner) && - *scanner->curptr != '\r' && *scanner->curptr != '\n'); /* If empty line is found, eat it. */ if (!pj_scan_is_eof(scanner)) { @@ -858,9 +865,10 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx, /* If we have Content-Type header, treat the rest of the message as body.*/ if (ctype_hdr && scanner->curptr!=scanner->end) { pjsip_msg_body *body = pj_pool_alloc(pool, sizeof(pjsip_msg_body)); - pj_strdup(pool, &body->content_type.type, &ctype_hdr->media.type); - pj_strdup(pool, &body->content_type.subtype, &ctype_hdr->media.subtype); - pj_strdup(pool, &body->content_type.param, &ctype_hdr->media.param); + body->content_type.type = ctype_hdr->media.type; + body->content_type.subtype = ctype_hdr->media.subtype; + body->content_type.param = ctype_hdr->media.param; + body->data = scanner->curptr; body->len = scanner->end - scanner->curptr; body->print_body = &generic_print_body; @@ -1001,16 +1009,12 @@ static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *po uri = (pjsip_uri*)int_parse_name_addr( scanner, pool ); is_name_addr = 1; } else { - pj_scan_state backtrack; pj_str_t scheme; - int colon; + int next_ch; - pj_scan_save_state( scanner, &backtrack); - pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &scheme); - colon = pj_scan_get_char( scanner ); - pj_scan_restore_state( scanner, &backtrack); + next_ch = pj_scan_peek( scanner, &pjsip_DISPLAY_SPEC, &scheme); - if (colon==':' && + if (next_ch==':' && (parser_stricmp(scheme, pjsip_SIP_STR)==0 || parser_stricmp(scheme, pjsip_SIPS_STR)==0)) { @@ -1018,7 +1022,7 @@ static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *po int_parse_sip_url( scanner, pool, (opt & PJSIP_PARSE_URI_IN_FROM_TO_HDR)== 0); - } else if (colon==':' && parser_stricmp( scheme, pjsip_TEL_STR)==0) { + } else if (next_ch==':') { /* Not supported. */ PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); @@ -1189,7 +1193,7 @@ static pjsip_name_addr *int_parse_name_addr( pj_scanner *scanner, * We're only interested in display name, because SIP URL * will be parser later. */ - next = pj_scan_peek_until(scanner, &pjsip_DISPLAY_SCAN_SPEC, &dummy); + next = pj_scan_peek(scanner, &pjsip_DISPLAY_SPEC, &dummy); if (next == '<') { /* Ok, this is what we're looking for, a display name. */ pj_scan_get_until_ch( scanner, '<', &name_addr->display); @@ -1205,8 +1209,10 @@ static pjsip_name_addr *int_parse_name_addr( pj_scanner *scanner, if (has_bracket) pj_scan_get_char(scanner); name_addr->uri = int_parse_uri( scanner, pool, PJ_TRUE ); - if (has_bracket) - pj_scan_get_char(scanner); + if (has_bracket) { + if (pj_scan_get_char(scanner) != '>') + PJ_THROW( PJSIP_SYN_ERR_EXCEPTION); + } return name_addr; } @@ -1222,7 +1228,7 @@ static void int_parse_req_line( pj_scanner *scanner, pj_pool_t *pool, pjsip_method_init_np( &req_line->method, &token); req_line->uri = int_parse_uri(scanner, pool, PJ_TRUE); - if (pj_scan_stricmp( scanner, PJSIP_VERSION, 7) != 0) + if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) != 0) PJ_THROW( PJSIP_SYN_ERR_EXCEPTION); pj_scan_advance_n (scanner, 7, 1); pj_scan_get_newline( scanner ); @@ -1234,14 +1240,13 @@ static void int_parse_status_line( pj_scanner *scanner, { pj_str_t token; - if (pj_scan_stricmp(scanner, PJSIP_VERSION, 7) != 0) + if (pj_scan_stricmp_alnum(scanner, PJSIP_VERSION, 7) != 0) PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); pj_scan_advance_n( scanner, 7, 1); pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &token); status_line->code = pj_strtoul(&token); - pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, - &status_line->reason); + pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &status_line->reason); pj_scan_get_newline( scanner ); } @@ -1267,13 +1272,13 @@ void pjsip_parse_end_hdr_imp( pj_scanner *scanner ) static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr, pj_scanner *scanner) { - pj_scan_get_until( scanner, &pjsip_ARRAY_ELEMENTS, &hdr->values[0]); + pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE, &hdr->values[0]); hdr->count++; while (*scanner->curptr == ',') { pj_scan_get_char(scanner); - pj_scan_get_until( scanner, &pjsip_ARRAY_ELEMENTS, - &hdr->values[hdr->count]); + pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE, + &hdr->values[hdr->count]); hdr->count++; } parse_hdr_end(scanner); @@ -1283,7 +1288,11 @@ static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr, static void parse_generic_string_hdr( pjsip_generic_string_hdr *hdr, pj_scanner *scanner ) { - pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->hvalue); + if (pj_cis_match(&pjsip_NOT_NEWLINE, *scanner->curptr)) + pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &hdr->hvalue); + else + hdr->hvalue.slen = 0; + parse_hdr_end(scanner); } @@ -1292,7 +1301,7 @@ static void parse_generic_int_hdr( pjsip_generic_int_hdr *hdr, pj_scanner *scanner ) { pj_str_t tmp; - pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &tmp); + pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &tmp); hdr->ivalue = pj_strtoul(&tmp); parse_hdr_end(scanner); } @@ -1318,7 +1327,7 @@ static pjsip_hdr* parse_hdr_allow(pjsip_parse_ctx *ctx) static pjsip_hdr* parse_hdr_call_id(pjsip_parse_ctx *ctx) { pjsip_cid_hdr *hdr = pjsip_cid_hdr_create(ctx->pool); - pj_scan_get_until( ctx->scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->id); + pj_scan_get( ctx->scanner, &pjsip_NOT_NEWLINE, &hdr->id); parse_hdr_end(ctx->scanner); if (ctx->rdata) @@ -1700,7 +1709,7 @@ static pjsip_hdr* parse_hdr_via( pjsip_parse_ctx *ctx ) else pj_list_insert_before(first, hdr); - if (pj_scan_stricmp( scanner, PJSIP_VERSION "/", 8) != 0) + if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION "/", 8) != 0) PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); pj_scan_advance_n( scanner, 8, 1); diff --git a/pjsip/src/pjsip/sip_uri.c b/pjsip/src/pjsip/sip_uri.c index a4464254..6c4efb53 100644 --- a/pjsip/src/pjsip/sip_uri.c +++ b/pjsip/src/pjsip/sip_uri.c @@ -89,11 +89,19 @@ PJ_DEF(pj_ssize_t) pjsip_param_print_on( const pjsip_param *param_list, char *buf, pj_size_t size, int sep) { - const pjsip_param *p = param_list->next; - char *startbuf = buf; - char *endbuf = buf + size; + const pjsip_param *p; + char *startbuf; + char *endbuf; + int printed; - while (p != param_list) { + p = param_list->next; + if (p == param_list) + return 0; + + startbuf = buf; + endbuf = buf + size; + + do { *buf++ = (char)sep; copy_advance_escape(buf, p->name, pjsip_PARAM_CHAR_SPEC); if (p->value.slen) { @@ -101,7 +109,8 @@ PJ_DEF(pj_ssize_t) pjsip_param_print_on( const pjsip_param *param_list, copy_advance_escape(buf, p->value, pjsip_PARAM_CHAR_SPEC); } p = p->next; - } + } while (p != param_list); + return buf-startbuf; } @@ -248,6 +257,9 @@ static int pjsip_url_print( pjsip_uri_context_e context, */ //PJ_TODO(SHOULD_DISALLOW_URI_PORT_IN_FROM_TO_HEADER) if (url->port && context != PJSIP_URI_IN_FROMTO_HDR) { + if (endbuf - buf < 10) + return -1; + *buf++ = ':'; printed = pj_utoa(url->port, buf); buf += printed; @@ -270,8 +282,10 @@ static int pjsip_url_print( pjsip_uri_context_e context, /* TTL param is not allowed in From, To, Route, and Record-Route header. */ if (url->ttl_param >= 0 && context != PJSIP_URI_IN_FROMTO_HDR && - context != PJSIP_URI_IN_ROUTING_HDR && (endbuf-buf) > 15) + context != PJSIP_URI_IN_ROUTING_HDR) { + if (endbuf - buf < 15) + return -1; pj_memcpy(buf, ";ttl=", 5); printed = pj_utoa(url->ttl_param, buf+5); buf += printed + 5; @@ -288,6 +302,8 @@ static int pjsip_url_print( pjsip_uri_context_e context, context != PJSIP_URI_IN_CONTACT_HDR) { pj_str_t lr = { ";lr", 3 }; + if (endbuf - buf < 3) + return -1; copy_advance_check(buf, lr); } @@ -300,6 +316,8 @@ static int pjsip_url_print( pjsip_uri_context_e context, /* Header param. */ param = url->header_param.next; while (param != &url->header_param) { + if (endbuf - buf < param->name.slen+2) + return -1; *buf++ = hparam_char; copy_advance_escape(buf, param->name, pjsip_HDR_CHAR_SPEC); if (param->value.slen) { diff --git a/pjsip/src/test-pjsip/msg.c b/pjsip/src/test-pjsip/msg.c index bfa253bd..1f6affdd 100644 --- a/pjsip/src/test-pjsip/msg.c +++ b/pjsip/src/test-pjsip/msg.c @@ -34,7 +34,7 @@ static pjsip_msg *create_msg1(pj_pool_t *pool); #define FLAG_PARSE_ONLY 4 #define FLAG_PRINT_ONLY 8 -static int flag = FLAG_PARSE_ONLY; +static int flag = 0; struct test_msg { @@ -105,6 +105,7 @@ static pj_timestamp detect_time, parse_time, print_time; static pj_status_t test_entry( pj_pool_t *pool, struct test_msg *entry ) { pjsip_msg *parsed_msg, *ref_msg; + static pjsip_msg *print_msg; pj_status_t status = PJ_SUCCESS; int len; pj_str_t str1, str2; @@ -114,15 +115,18 @@ static pj_status_t test_entry( pj_pool_t *pool, struct test_msg *entry ) pj_size_t msg_size; char msgbuf1[PJSIP_MAX_PKT_LEN]; char msgbuf2[PJSIP_MAX_PKT_LEN]; - enum { BUFLEN = 512 }; entry->len = pj_native_strlen(entry->msg); if (flag & FLAG_PARSE_ONLY) goto parse_msg; - if (flag & FLAG_PRINT_ONLY) + + if (flag & FLAG_PRINT_ONLY) { + if (print_msg == NULL) + print_msg = entry->creator(pool); goto print_msg; + } /* Detect message. */ detect_len = detect_len + entry->len; @@ -144,7 +148,7 @@ static pj_status_t test_entry( pj_pool_t *pool, struct test_msg *entry ) pj_sub_timestamp(&t2, &t1); pj_add_timestamp(&detect_time, &t2); - if (flag & FLAG_PARSE_ONLY) + if (flag & FLAG_DETECT_ONLY) return PJ_SUCCESS; /* Parse message. */ @@ -302,7 +306,9 @@ parse_msg: print_msg: print_len = print_len + entry->len; pj_get_timestamp(&t1); - len = pjsip_msg_print(parsed_msg, msgbuf1, PJSIP_MAX_PKT_LEN); + if (flag && FLAG_PRINT_ONLY) + ref_msg = print_msg; + len = pjsip_msg_print(ref_msg, msgbuf1, PJSIP_MAX_PKT_LEN); if (len < 1) { status = -150; goto on_return; diff --git a/pjsip/src/test-pjsip/test.c b/pjsip/src/test-pjsip/test.c index d598dd5d..b940ffa1 100644 --- a/pjsip/src/test-pjsip/test.c +++ b/pjsip/src/test-pjsip/test.c @@ -81,8 +81,8 @@ int test_main(void) PJ_LOG(3,("","")); - //DO_TEST(uri_test()); - DO_TEST(msg_test()); + DO_TEST(uri_test()); + //DO_TEST(msg_test()); on_return: |