Changeset 2538 for pjproject/branches/1.0/pjsip/src/pjsip/sip_parser.c
- Timestamp:
- Mar 23, 2009 1:14:26 PM (15 years ago)
- Location:
- pjproject/branches/1.0
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/1.0
- Property svn:mergeinfo changed
/pjproject/trunk merged: 2505,2522
- Property svn:mergeinfo changed
-
pjproject/branches/1.0/pjsip/src/pjsip/sip_parser.c
r2394 r2538 54 54 */ 55 55 #define GENERIC_URI_CHARS "#?;:@&=+-_.!~*'()%$,/" "%" 56 57 #define PJSIP_VERSION "SIP/2.0"58 56 59 57 #define UNREACHED(expr) … … 328 326 pj_cis_del_str(&pconst.pjsip_TOKEN_SPEC_ESC, "%"); 329 327 328 status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC, &pconst.pjsip_TOKEN_SPEC); 329 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 330 pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, ":"); 331 332 status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC_ESC); 333 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 334 pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, ":"); 335 330 336 status = pj_cis_dup(&pconst.pjsip_HOST_SPEC, &pconst.pjsip_ALNUM_SPEC); 331 337 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); … … 773 779 const char *line; 774 780 int content_length = -1; 781 pj_str_t cur_msg; 782 const pj_str_t end_hdr = { "\n\r\n", 3}; 775 783 776 784 *msg_size = size; … … 782 790 783 791 784 /* Find the end of header area by finding an empty line. */ 785 pos = pj_ansi_strstr(buf, "\n\r\n"); 792 /* Find the end of header area by finding an empty line. 793 * Don't use plain strstr() since we want to be able to handle 794 * NULL character in the message 795 */ 796 cur_msg.ptr = (char*)buf; cur_msg.slen = size; 797 pos = pj_strstr(&cur_msg, &end_hdr); 786 798 if (pos == NULL) { 787 799 return PJSIP_EPARTIALMSG; … … 792 804 793 805 /* Find "Content-Length" header the hard way. */ 794 line = pj_ ansi_strchr(buf, '\n');806 line = pj_strchr(&cur_msg, '\n'); 795 807 while (line && line < hdr_end) { 796 808 ++line; … … 843 855 844 856 /* Go to next line. */ 845 line = pj_ansi_strchr(line, '\n'); 857 cur_msg.slen -= (line - cur_msg.ptr); 858 cur_msg.ptr = (char*)line; 859 line = pj_strchr(&cur_msg, '\n'); 846 860 } 847 861 … … 894 908 } 895 909 910 /* SIP version */ 911 static void parse_sip_version(pj_scanner *scanner) 912 { 913 pj_str_t SIP = { "SIP", 3 }; 914 pj_str_t V2 = { "2.0", 3 }; 915 pj_str_t sip, version; 916 917 pj_scan_get( scanner, &pconst.pjsip_ALPHA_SPEC, &sip); 918 if (pj_scan_get_char(scanner) != '/') 919 on_syntax_error(scanner); 920 pj_scan_get_n( scanner, 3, &version); 921 if (pj_stricmp(&sip, &SIP) || pj_stricmp(&version, &V2)) 922 on_syntax_error(scanner); 923 } 924 925 static pj_bool_t is_next_sip_version(pj_scanner *scanner) 926 { 927 pj_str_t SIP = { "SIP", 3 }; 928 pj_str_t sip; 929 int c; 930 931 c = pj_scan_peek(scanner, &pconst.pjsip_ALPHA_SPEC, &sip); 932 /* return TRUE if it is "SIP" followed by "/" or space. 933 * we include space since the "/" may be separated by space, 934 * although this would mean it would return TRUE if it is a 935 * request and the method is "SIP"! 936 */ 937 return c && (c=='/' || c==' ' || c=='\t') && pj_stricmp(&sip, &SIP)==0; 938 } 939 896 940 /* Internal function to parse SIP message */ 897 941 static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx, … … 927 971 928 972 /* Parse request or status line */ 929 if ( pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) == 0) {973 if (is_next_sip_version(scanner)) { 930 974 msg = pjsip_msg_create(pool, PJSIP_RESPONSE_MSG); 931 975 int_parse_status_line( scanner, &msg->line.status ); … … 1126 1170 1127 1171 1128 /* Parse parameter (";" pname ["=" pvalue]) in header. */1172 /* Parse parameter (";" pname ["=" pvalue]) in SIP header. */ 1129 1173 static void int_parse_param( pj_scanner *scanner, pj_pool_t *pool, 1130 1174 pj_str_t *pname, pj_str_t *pvalue, … … 1514 1558 1515 1559 req_line->uri = int_parse_uri(scanner, pool, PJ_TRUE); 1516 if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) != 0) 1517 PJ_THROW( PJSIP_SYN_ERR_EXCEPTION); 1518 pj_scan_advance_n (scanner, 7, 1); 1560 parse_sip_version(scanner); 1519 1561 pj_scan_get_newline( scanner ); 1520 1562 } … … 1526 1568 pj_str_t token; 1527 1569 1528 if (pj_scan_stricmp_alnum(scanner, PJSIP_VERSION, 7) != 0) 1529 PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 1530 pj_scan_advance_n( scanner, 7, 1); 1531 1570 parse_sip_version(scanner); 1532 1571 pj_scan_get( scanner, &pconst.pjsip_DIGIT_SPEC, &token); 1533 1572 status_line->code = pj_strtoul(&token); … … 1619 1658 /* Parse generic string header. */ 1620 1659 static void parse_generic_string_hdr( pjsip_generic_string_hdr *hdr, 1621 pj_scanner *scanner ) 1622 { 1623 if (pj_cis_match(&pconst.pjsip_NOT_NEWLINE, *scanner->curptr)) 1660 pjsip_parse_ctx *ctx) 1661 { 1662 pj_scanner *scanner = ctx->scanner; 1663 1664 hdr->hvalue.slen = 0; 1665 1666 /* header may be mangled hence the loop */ 1667 while (pj_cis_match(&pconst.pjsip_NOT_NEWLINE, *scanner->curptr)) { 1668 pj_str_t next, tmp; 1669 1624 1670 pj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &hdr->hvalue); 1625 else 1626 hdr->hvalue.slen = 0; 1671 if (pj_scan_is_eof(scanner) || IS_NEWLINE(*scanner->curptr)) 1672 break; 1673 /* mangled, get next fraction */ 1674 pj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &next); 1675 /* concatenate */ 1676 tmp.ptr = (char*)pj_pool_alloc(ctx->pool, 1677 hdr->hvalue.slen + next.slen + 2); 1678 tmp.slen = 0; 1679 pj_strcpy(&tmp, &hdr->hvalue); 1680 pj_strcat2(&tmp, " "); 1681 pj_strcat(&tmp, &next); 1682 tmp.ptr[tmp.slen] = '\0'; 1683 1684 hdr->hvalue = tmp; 1685 } 1627 1686 1628 1687 parse_hdr_end(scanner); … … 1935 1994 1936 1995 //Parse with PARAM_CHAR instead, to allow IPv6 1996 //No, back to using int_parse_param() for the "`" character! 1937 1997 //int_parse_param( scanner, pool, &pname, &pvalue, 0); 1938 /* Get ';' character */ 1998 //parse_param_imp(scanner, pool, &pname, &pvalue, 1999 // &pconst.pjsip_TOKEN_SPEC, 2000 // &pconst.pjsip_TOKEN_SPEC_ESC, 0); 2001 //int_parse_param(scanner, pool, &pname, &pvalue, 0); 2002 // This should be the correct one: 2003 // added special spec for Via parameter, basically token plus 2004 // ":" to allow IPv6 address in the received param. 1939 2005 pj_scan_get_char(scanner); 1940 1941 parse_param_imp(scanner, pool, &pname, &pvalue,1942 &pconst.pjsip_ PARAM_CHAR_SPEC,1943 &pconst.pjsip_PARAM_CHAR_SPEC_ESC,0);2006 parse_param_imp(scanner, pool, &pname, &pvalue, 2007 &pconst.pjsip_VIA_PARAM_SPEC, 2008 &pconst.pjsip_VIA_PARAM_SPEC_ESC, 2009 0); 1944 2010 1945 2011 if (!parser_stricmp(pname, pconst.pjsip_BRANCH_STR) && pvalue.slen) { … … 2076 2142 pj_list_insert_before(first, hdr); 2077 2143 2078 if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION "/", 8) != 0) 2079 PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 2080 2081 pj_scan_advance_n( scanner, 8, 1); 2144 parse_sip_version(scanner); 2145 if (pj_scan_get_char(scanner) != '/') 2146 on_syntax_error(scanner); 2082 2147 2083 2148 pj_scan_get( scanner, &pconst.pjsip_TOKEN_SPEC, &hdr->transport); … … 2120 2185 2121 2186 hdr = pjsip_generic_string_hdr_create(ctx->pool, NULL, NULL); 2122 parse_generic_string_hdr(hdr, ctx ->scanner);2187 parse_generic_string_hdr(hdr, ctx); 2123 2188 return (pjsip_hdr*)hdr; 2124 2189
Note: See TracChangeset
for help on using the changeset viewer.