Changeset 583 for pjproject/trunk/pjsip/src/pjsip/sip_parser.c
- Timestamp:
- Jul 3, 2006 10:08:47 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_parser.c
r576 r583 116 116 pjsip_PARAM_CHAR_SPEC, /* For scanning pname (or pvalue when 117 117 * it's not quoted.) */ 118 pjsip_PARAM_CHAR_SPEC_ESC, /* The variant without escaped char */ 118 119 pjsip_HDR_CHAR_SPEC, /* Chars in hname or hvalue */ 120 pjsip_HDR_CHAR_SPEC_ESC, /* Variant without escaped char */ 119 121 pjsip_PROBE_USER_HOST_SPEC, /* Hostname characters. */ 120 122 pjsip_PASSWD_SPEC, /* Password. */ 123 pjsip_PASSWD_SPEC_ESC, /* Variant without escaped char */ 121 124 pjsip_USER_SPEC, /* User */ 125 pjsip_USER_SPEC_ESC, /* Variant without escaped char */ 122 126 pjsip_NOT_COMMA_OR_NEWLINE, /* Array separator. */ 123 127 pjsip_NOT_NEWLINE, /* For eating up header.*/ … … 202 206 203 207 /* Case insensitive comparison */ 204 #define parser_stricmp(s1, s2) (pj_stricmp_alnum(&s1, &s2)) 208 #define parser_stricmp(s1, s2) (s1.slen!=s2.slen || pj_stricmp_alnum(&s1, &s2)) 209 210 211 /* Get a token and unescape */ 212 PJ_INLINE(void) parser_get_and_unescape(pj_scanner *scanner, pj_pool_t *pool, 213 const pj_cis_t *spec, 214 const pj_cis_t *unesc_spec, 215 pj_str_t *token) 216 { 217 #if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0 218 PJ_UNUSED_ARG(pool); 219 PJ_UNUSED_ARG(spec); 220 pj_scan_get_unescape(scanner, unesc_spec, token); 221 #else 222 PJ_UNUSED_ARG(unesc_spec); 223 pj_scan_get(scanner, spec, token); 224 *token = pj_str_unescape(pool, token); 225 #endif 226 } 227 205 228 206 229 … … 314 337 pj_cis_add_str(&pjsip_PARAM_CHAR_SPEC, PARAM_CHAR); 315 338 339 status = pj_cis_dup(&pjsip_PARAM_CHAR_SPEC_ESC, &pjsip_PARAM_CHAR_SPEC); 340 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 341 pj_cis_del_str(&pjsip_PARAM_CHAR_SPEC_ESC, ESCAPED); 342 316 343 status = pj_cis_dup(&pjsip_HDR_CHAR_SPEC, &pjsip_ALNUM_SPEC); 317 344 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 318 345 pj_cis_add_str(&pjsip_HDR_CHAR_SPEC, HDR_CHAR); 319 346 347 status = pj_cis_dup(&pjsip_HDR_CHAR_SPEC_ESC, &pjsip_HDR_CHAR_SPEC); 348 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 349 pj_cis_del_str(&pjsip_HDR_CHAR_SPEC_ESC, ESCAPED); 350 320 351 status = pj_cis_dup(&pjsip_USER_SPEC, &pjsip_ALNUM_SPEC); 321 352 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 322 353 pj_cis_add_str( &pjsip_USER_SPEC, UNRESERVED ESCAPED USER_UNRESERVED ); 323 354 355 status = pj_cis_dup(&pjsip_USER_SPEC_ESC, &pjsip_USER_SPEC); 356 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 357 pj_cis_del_str( &pjsip_USER_SPEC_ESC, ESCAPED); 358 324 359 status = pj_cis_dup(&pjsip_PASSWD_SPEC, &pjsip_ALNUM_SPEC); 325 360 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 326 361 pj_cis_add_str( &pjsip_PASSWD_SPEC, UNRESERVED ESCAPED PASS); 362 363 status = pj_cis_dup(&pjsip_PASSWD_SPEC_ESC, &pjsip_PASSWD_SPEC); 364 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 365 pj_cis_del_str( &pjsip_PASSWD_SPEC, ESCAPED); 327 366 328 367 status = pj_cis_init(&cis_buf, &pjsip_PROBE_USER_HOST_SPEC); … … 460 499 461 500 /* Equal length and equal hash. compare the strings. */ 462 return pj_ ansi_strcmp(r1->hname, name);501 return pj_memcmp(r1->hname, name, name_len); 463 502 } 464 503 … … 469 508 unsigned pos; 470 509 handler_rec rec; 471 unsigned i;472 510 473 511 if (handler_count >= PJ_ARRAY_SIZE(handler)) { 512 pj_assert(!"Too many handlers!"); 474 513 return PJ_ETOOMANY; 475 514 } … … 482 521 return PJ_ENAMETOOLONG; 483 522 } 484 /* Name is copied in lowercase. */ 485 for (i=0; i<rec.hname_len; ++i) { 486 rec.hname[i] = (char)pj_tolower(name[i]); 487 } 488 rec.hname[i] = '\0'; 489 /* Hash value is calculated from the lowercase name. */ 490 rec.hname_hash = pj_hash_calc(0, rec.hname, PJ_HASH_KEY_STRING); 523 /* Copy name. */ 524 pj_memcpy(rec.hname, name, rec.hname_len); 525 rec.hname[rec.hname_len] = '\0'; 526 527 /* Calculate hash value. */ 528 rec.hname_hash = pj_hash_calc(0, rec.hname, rec.hname_len); 491 529 492 530 /* Get the pos to insert the new handler. */ … … 523 561 pjsip_parse_hdr_func *fptr) 524 562 { 563 unsigned i, len; 564 char hname_lcase[PJSIP_MAX_HNAME_LEN+1]; 525 565 pj_status_t status; 526 566 567 /* Check that name is not too long */ 568 len = pj_ansi_strlen(hname); 569 if (len > PJSIP_MAX_HNAME_LEN) { 570 pj_assert(!"Header name is too long!"); 571 return PJ_ENAMETOOLONG; 572 } 573 574 /* Register the normal Mixed-Case name */ 527 575 status = int_register_parser(hname, fptr); 528 576 if (status != PJ_SUCCESS) { 529 577 return status; 530 578 } 579 580 /* Get the lower-case name */ 581 for (i=0; i<len; ++i) { 582 hname_lcase[i] = (char)pj_tolower(hname[i]); 583 } 584 hname_lcase[len] = '\0'; 585 586 /* Register the lower-case version of the name */ 587 status = int_register_parser(hname_lcase, fptr); 588 if (status != PJ_SUCCESS) { 589 return status; 590 } 591 592 593 /* Register the shortname version of the name */ 531 594 if (hshortname) { 532 595 status = int_register_parser(hshortname, fptr); … … 537 600 } 538 601 602 539 603 /* Find handler to parse the header name. */ 540 static pjsip_parse_hdr_func * find_handler(const pj_str_t *hname) 604 static pjsip_parse_hdr_func * find_handler_imp(pj_uint32_t hash, 605 const pj_str_t *hname) 541 606 { 542 607 handler_rec *first; 543 char hname_copy[PJSIP_MAX_HNAME_LEN];544 pj_uint32_t hash;545 608 int comp; 546 609 unsigned n; 547 548 if (hname->slen >= PJSIP_MAX_HNAME_LEN) {549 /* Guaranteed not to be able to find handler. */550 return NULL;551 }552 553 /* Calculate hash value while converting the header to lowercase.554 * Don't assume that 'hname' is NULL terminated.555 */556 hash = pj_hash_calc_tolower(0, hname_copy, hname);557 hname_copy[hname->slen] = '\0';558 610 559 611 /* Binary search for the handler. */ … … 565 617 handler_rec *mid = first + half; 566 618 567 comp = compare_handler(mid, hname _copy, hname->slen, hash);619 comp = compare_handler(mid, hname->ptr, hname->slen, hash); 568 620 if (comp < 0) { 569 621 first = ++mid; … … 580 632 } 581 633 634 635 /* Find handler to parse the header name. */ 636 static pjsip_parse_hdr_func* find_handler(const pj_str_t *hname) 637 { 638 pj_uint32_t hash; 639 char hname_copy[PJSIP_MAX_HNAME_LEN]; 640 pj_str_t tmp; 641 pjsip_parse_hdr_func *handler; 642 643 if (hname->slen >= PJSIP_MAX_HNAME_LEN) { 644 /* Guaranteed not to be able to find handler. */ 645 return NULL; 646 } 647 648 /* First, common case, try to find handler with exact name */ 649 hash = pj_hash_calc(0, hname->ptr, hname->slen); 650 handler = find_handler_imp(hash, hname); 651 if (handler) 652 return handler; 653 654 655 /* If not found, try converting the header name to lowercase and 656 * search again. 657 */ 658 hash = pj_hash_calc_tolower(0, hname_copy, hname); 659 tmp.ptr = hname_copy; 660 tmp.slen = hname->slen; 661 return find_handler_imp(hash, &tmp); 662 } 663 664 582 665 /* Find URI handler. */ 583 666 static pjsip_parse_uri_func* find_uri_handler(const pj_str_t *scheme) … … 585 668 unsigned i; 586 669 for (i=0; i<uri_handler_count; ++i) { 587 if (p j_stricmp_alnum(&uri_handler[i].scheme, scheme)==0)670 if (parser_stricmp(uri_handler[i].scheme, (*scheme))==0) 588 671 return uri_handler[i].parse; 589 672 } … … 962 1045 { 963 1046 /* pname */ 964 p j_scan_get(scanner, &pjsip_PARAM_CHAR_SPEC, pname);965 *pname = pj_str_unescape(pool, pname);1047 parser_get_and_unescape(scanner, pool, &pjsip_PARAM_CHAR_SPEC, 1048 &pjsip_PARAM_CHAR_SPEC_ESC, pname); 966 1049 967 1050 /* init pvalue */ … … 981 1064 } 982 1065 } else if(pj_cis_match(&pjsip_PARAM_CHAR_SPEC, *scanner->curptr)) { 983 p j_scan_get(scanner, &pjsip_PARAM_CHAR_SPEC, pvalue);984 *pvalue = pj_str_unescape(pool, pvalue);1066 parser_get_and_unescape(scanner, pool, &pjsip_PARAM_CHAR_SPEC, 1067 &pjsip_PARAM_CHAR_SPEC_ESC, pvalue); 985 1068 } 986 1069 } … … 1008 1091 1009 1092 /* hname */ 1010 p j_scan_get(scanner, &pjsip_HDR_CHAR_SPEC, hname);1011 *hname = pj_str_unescape(pool, hname);1093 parser_get_and_unescape(scanner, pool, &pjsip_HDR_CHAR_SPEC, 1094 &pjsip_HDR_CHAR_SPEC_ESC, hname); 1012 1095 1013 1096 /* Init hvalue */ … … 1021 1104 pj_cis_match(&pjsip_HDR_CHAR_SPEC, *scanner->curptr)) 1022 1105 { 1023 p j_scan_get(scanner, &pjsip_HDR_CHAR_SPEC, hvalue);1024 *hvalue = pj_str_unescape(pool, hvalue);1106 parser_get_and_unescape(scanner, pool, &pjsip_HDR_CHAR_SPEC, 1107 &pjsip_HDR_CHAR_SPEC, hvalue); 1025 1108 } 1026 1109 } … … 1064 1147 pj_str_t *user, pj_str_t *pass) 1065 1148 { 1066 p j_scan_get( scanner, &pjsip_USER_SPEC, user);1067 *user = pj_str_unescape(pool, user);1149 parser_get_and_unescape(scanner, pool, &pjsip_USER_SPEC, 1150 &pjsip_USER_SPEC_ESC, user); 1068 1151 1069 1152 if ( *scanner->curptr == ':') { 1070 1153 pj_scan_get_char( scanner ); 1071 p j_scan_get( scanner, &pjsip_PASSWD_SPEC, pass);1072 *pass = pj_str_unescape(pool, pass);1154 parser_get_and_unescape(scanner, pool, &pjsip_PASSWD_SPEC, 1155 &pjsip_PASSWD_SPEC_ESC, pass); 1073 1156 } else { 1074 1157 pass->ptr = NULL; … … 1436 1519 int_parse_param( scanner, pool, &pname, &pvalue); 1437 1520 if (!parser_stricmp(pname, pjsip_Q_STR) && pvalue.slen) { 1438 char *dot_pos = memchr(pvalue.ptr, '.', pvalue.slen);1521 char *dot_pos = pj_memchr(pvalue.ptr, '.', pvalue.slen); 1439 1522 if (!dot_pos) { 1440 1523 hdr->q1000 = pj_strtoul(&pvalue);
Note: See TracChangeset
for help on using the changeset viewer.