Ignore:
Timestamp:
Mar 23, 2009 1:14:26 PM (15 years ago)
Author:
bennylp
Message:

Ticket #748: backported changes from ticket #747

Location:
pjproject/branches/1.0
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/1.0

  • pjproject/branches/1.0/pjsip/src/pjsip/sip_parser.c

    r2394 r2538  
    5454 */ 
    5555#define GENERIC_URI_CHARS   "#?;:@&=+-_.!~*'()%$,/" "%" 
    56  
    57 #define PJSIP_VERSION           "SIP/2.0" 
    5856 
    5957#define UNREACHED(expr) 
     
    328326    pj_cis_del_str(&pconst.pjsip_TOKEN_SPEC_ESC, "%"); 
    329327 
     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 
    330336    status = pj_cis_dup(&pconst.pjsip_HOST_SPEC, &pconst.pjsip_ALNUM_SPEC); 
    331337    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 
     
    773779    const char *line; 
    774780    int content_length = -1; 
     781    pj_str_t cur_msg; 
     782    const pj_str_t end_hdr = { "\n\r\n", 3}; 
    775783 
    776784    *msg_size = size; 
     
    782790 
    783791 
    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); 
    786798    if (pos == NULL) { 
    787799        return PJSIP_EPARTIALMSG; 
     
    792804 
    793805    /* Find "Content-Length" header the hard way. */ 
    794     line = pj_ansi_strchr(buf, '\n'); 
     806    line = pj_strchr(&cur_msg, '\n'); 
    795807    while (line && line < hdr_end) { 
    796808        ++line; 
     
    843855 
    844856        /* 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'); 
    846860    } 
    847861 
     
    894908} 
    895909 
     910/* SIP version */ 
     911static 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 
     925static 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 
    896940/* Internal function to parse SIP message */ 
    897941static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx, 
     
    927971 
    928972        /* Parse request or status line */ 
    929         if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) == 0) { 
     973        if (is_next_sip_version(scanner)) { 
    930974            msg = pjsip_msg_create(pool, PJSIP_RESPONSE_MSG); 
    931975            int_parse_status_line( scanner, &msg->line.status ); 
     
    11261170 
    11271171 
    1128 /* Parse parameter (";" pname ["=" pvalue]) in header. */ 
     1172/* Parse parameter (";" pname ["=" pvalue]) in SIP header. */ 
    11291173static void int_parse_param( pj_scanner *scanner, pj_pool_t *pool, 
    11301174                             pj_str_t *pname, pj_str_t *pvalue, 
     
    15141558 
    15151559    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); 
    15191561    pj_scan_get_newline( scanner ); 
    15201562} 
     
    15261568    pj_str_t token; 
    15271569 
    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); 
    15321571    pj_scan_get( scanner, &pconst.pjsip_DIGIT_SPEC, &token); 
    15331572    status_line->code = pj_strtoul(&token); 
     
    16191658/* Parse generic string header. */ 
    16201659static 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 
    16241670        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    } 
    16271686 
    16281687    parse_hdr_end(scanner); 
     
    19351994 
    19361995        //Parse with PARAM_CHAR instead, to allow IPv6 
     1996        //No, back to using int_parse_param() for the "`" character! 
    19371997        //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. 
    19392005        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); 
    19442010 
    19452011        if (!parser_stricmp(pname, pconst.pjsip_BRANCH_STR) && pvalue.slen) { 
     
    20762142            pj_list_insert_before(first, hdr); 
    20772143 
    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); 
    20822147 
    20832148        pj_scan_get( scanner, &pconst.pjsip_TOKEN_SPEC, &hdr->transport); 
     
    21202185 
    21212186    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); 
    21232188    return (pjsip_hdr*)hdr; 
    21242189 
Note: See TracChangeset for help on using the changeset viewer.