Changeset 77 for pjproject/trunk/pjsip/src/pjsip/sip_parser.c
- Timestamp:
- Nov 22, 2005 11:51:50 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_parser.c
r76 r77 66 66 static int parser_is_initialized; 67 67 68 69 68 /* 70 69 * Global vars (also extern). … … 102 101 pjsip_PASSWD_SPEC, /* Password. */ 103 102 pjsip_USER_SPEC, /* User */ 104 pjsip_ ARRAY_ELEMENTS,/* Array separator. */105 pjsip_N EWLINE_OR_EOF_SPEC,/* For eating up header.*/106 pjsip_DISPLAY_S CAN_SPEC;/* Used when searching for display name103 pjsip_NOT_COMMA_OR_NEWLINE, /* Array separator. */ 104 pjsip_NOT_NEWLINE, /* For eating up header.*/ 105 pjsip_DISPLAY_SPEC; /* Used when searching for display name 107 106 * in URL. */ 108 107 … … 259 258 pj_cis_add_num( &pjsip_ALNUM_SPEC ); 260 259 261 status = pj_cis_init(&cis_buf, &pjsip_NEWLINE_OR_EOF_SPEC); 262 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 263 pj_cis_add_str(&pjsip_NEWLINE_OR_EOF_SPEC, "\r\n"); 264 //pj_cs_set(pjsip_NEWLINE_OR_EOF_SPEC, 0); 265 266 status = pj_cis_init(&cis_buf, &pjsip_ARRAY_ELEMENTS); 267 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 268 pj_cis_add_str( &pjsip_ARRAY_ELEMENTS, ",\r\n"); 260 status = pj_cis_init(&cis_buf, &pjsip_NOT_NEWLINE); 261 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 262 pj_cis_add_str(&pjsip_NOT_NEWLINE, "\r\n"); 263 pj_cis_invert(&pjsip_NOT_NEWLINE); 264 265 status = pj_cis_init(&cis_buf, &pjsip_NOT_COMMA_OR_NEWLINE); 266 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 267 pj_cis_add_str( &pjsip_NOT_COMMA_OR_NEWLINE, ",\r\n"); 268 pj_cis_invert(&pjsip_NOT_COMMA_OR_NEWLINE); 269 269 270 270 status = pj_cis_dup(&pjsip_TOKEN_SPEC, &pjsip_ALNUM_SPEC); … … 301 301 pj_cis_invert( &pjsip_PROBE_USER_HOST_SPEC ); 302 302 303 status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SCAN_SPEC); 304 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 305 pj_cis_add_str( &pjsip_DISPLAY_SCAN_SPEC, ":\r\n<"); 303 status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SPEC); 304 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 305 pj_cis_add_str( &pjsip_DISPLAY_SPEC, ":\r\n<"); 306 pj_cis_invert(&pjsip_DISPLAY_SPEC); 306 307 307 308 status = pjsip_register_hdr_parser( "Accept", NULL, &parse_hdr_accept); … … 375 376 } 376 377 377 staticvoid init_sip_parser(void)378 void init_sip_parser(void) 378 379 { 379 380 if (!parser_is_initialized) { … … 393 394 * - >0 if handler is 'greater' than header name. 394 395 */ 395 static intcompare_handler( const handler_rec *r1,396 PJ_INLINE(int) compare_handler( const handler_rec *r1, 396 397 const char *name, 397 398 pj_size_t name_len, 398 399 pj_uint32_t hash ) 399 400 { 401 PJ_UNUSED_ARG(name_len); 402 403 /* Compare hashed value. */ 404 if (r1->hname_hash < hash) 405 return -1; 406 if (r1->hname_hash > hash) 407 return 1; 408 400 409 /* Compare length. */ 410 /* 401 411 if (r1->hname_len < name_len) 402 412 return -1; 403 413 if (r1->hname_len > name_len) 404 414 return 1; 405 406 /* Length is equal, compare hashed value. */ 407 if (r1->hname_hash < hash) 408 return -1; 409 if (r1->hname_hash > hash) 410 return 1; 415 */ 411 416 412 417 /* Equal length and equal hash. compare the strings. */ … … 610 615 611 616 /* Find the end of header area by finding an empty line. */ 612 if ((pos = pj_native_strstr(buf, "\n\r\n")) == NULL) { 617 pos = pj_native_strstr(buf, "\n\r\n"); 618 if (pos == NULL) { 613 619 return PJSIP_EPARTIALMSG; 614 620 } 615 621 616 622 hdr_end = pos+1; 617 623 body_start = pos+3; … … 619 625 /* Find "Content-Length" header the hard way. */ 620 626 line = pj_native_strchr(buf, '\n'); 621 while (line && line < hdr_end -14) {627 while (line && line < hdr_end) { 622 628 ++line; 623 629 if ( ((*line=='C' || *line=='c') && 624 pj_native_strncasecmp(line, "Content-Length", 14) == 0) ||630 strnicmp_alnum(line, "Content-Length", 14) == 0) || 625 631 ((*line=='l' || *line=='L') && 626 632 (*(line+1)==' ' || *(line+1)=='\t' || *(line+1)==':'))) … … 745 751 pjsip_parser_err_report *err_list) 746 752 { 747 int ch;748 753 pjsip_msg *msg; 754 pj_str_t hname; 749 755 pjsip_ctype_hdr *ctype_hdr = NULL; 750 756 pj_scanner *scanner = ctx->scanner; … … 753 759 754 760 /* Skip leading newlines. */ 755 ch = *scanner->curptr; 756 while (ch=='\r' || ch=='\n') { 757 pj_scan_get_char(scanner); 758 ch = *scanner->curptr; 761 while (*scanner->curptr=='\r' || *scanner->curptr=='\n') { 762 pj_scan_get_newline(scanner); 759 763 } 760 764 761 765 /* Parse request or status line */ 762 if (pj_scan_stricmp ( scanner, PJSIP_VERSION, 7) == 0) {766 if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) == 0) { 763 767 msg = pjsip_msg_create(pool, PJSIP_RESPONSE_MSG); 764 768 int_parse_status_line( scanner, &msg->line.status ); … … 769 773 770 774 /* Parse headers. */ 771 do { 772 pj_str_t hname; 773 pjsip_parse_hdr_func * handler; 774 pjsip_hdr *hdr = NULL; 775 776 /* Get hname. */ 777 pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname); 778 ch = pj_scan_get_char( scanner ); 779 if (ch != ':') { 780 PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 781 } 782 783 /* Find handler. */ 784 handler = find_handler(&hname); 785 786 PJ_TRY { 775 parse_headers: 776 777 PJ_TRY 778 { 779 do { 780 pjsip_parse_hdr_func * handler; 781 pjsip_hdr *hdr = NULL; 782 783 /* Get hname. */ 784 pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname); 785 if (pj_scan_get_char( scanner ) != ':') { 786 PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 787 } 788 789 /* Find handler. */ 790 handler = find_handler(&hname); 791 787 792 /* Call the handler if found. 788 793 * If no handler is found, then treat the header as generic … … 796 801 hdr->name = hdr->sname = hname; 797 802 } 798 803 799 804 /* Check if we've just parsed a Content-Type header. 800 * We will check for a message body if we've got Content-Type header. 805 * We will check for a message body if we've got Content-Type 806 * header. 801 807 */ 802 808 if (hdr->type == PJSIP_H_CONTENT_TYPE) { 803 809 ctype_hdr = (pjsip_ctype_hdr*)hdr; 804 810 } 805 806 }807 PJ_CATCH_ANY {808 /* Exception was thrown during parsing.809 * Skip until newline, and parse next header.810 */811 pj_str_t token;812 hdr = NULL;813 814 //PJ_LOG(4,("sipparser",815 // "Syntax error in line %d col %d (hname=%.*s)",816 // scanner->line, scanner->col, hname.slen, hname.ptr));817 818 if (err_list) {819 pjsip_parser_err_report *err_info;820 811 821 err_info = pj_pool_alloc(pool, sizeof(*err_info));822 err_info->except_code = PJ_GET_EXCEPTION();823 err_info->line = scanner->line;824 err_info->col = scanner->col;825 err_info->hname = hname;826 827 pj_list_insert_before(err_list, err_info);828 }829 830 if (!pj_scan_is_eof(scanner)) {831 pj_scan_get_until(scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &token);832 parse_hdr_end(scanner);833 }834 }835 PJ_END;836 837 if (hdr) {838 812 /* Single parse of header line can produce multiple headers. 839 813 * For example, if one Contact: header contains Contact list … … 843 817 */ 844 818 pj_list_insert_nodes_before(&msg->hdr, hdr); 845 } 846 847 /* Parse until EOF or an empty line is found. */ 848 } while (!pj_scan_is_eof(scanner) && 849 *scanner->curptr != '\r' && *scanner->curptr != '\n'); 819 820 /* Parse until EOF or an empty line is found. */ 821 } while (!pj_scan_is_eof(scanner) && 822 *scanner->curptr != '\r' && *scanner->curptr != '\n'); 823 824 } 825 PJ_CATCH_ANY 826 { 827 /* Exception was thrown during parsing. 828 * Skip until newline, and parse next header. 829 */ 830 pj_str_t token; 831 832 if (err_list) { 833 pjsip_parser_err_report *err_info; 834 835 err_info = pj_pool_alloc(pool, sizeof(*err_info)); 836 err_info->except_code = PJ_GET_EXCEPTION(); 837 err_info->line = scanner->line; 838 err_info->col = pj_scan_get_col(scanner); 839 err_info->hname = hname; 840 841 pj_list_insert_before(err_list, err_info); 842 } 843 844 if (!pj_scan_is_eof(scanner)) { 845 pj_scan_get(scanner, &pjsip_NOT_NEWLINE, &token); 846 parse_hdr_end(scanner); 847 } 848 849 if (!pj_scan_is_eof(scanner) && 850 *scanner->curptr != '\r' && *scanner->curptr != '\n'); 851 { 852 goto parse_headers; 853 } 854 } 855 PJ_END; 856 850 857 851 858 /* If empty line is found, eat it. */ … … 859 866 if (ctype_hdr && scanner->curptr!=scanner->end) { 860 867 pjsip_msg_body *body = pj_pool_alloc(pool, sizeof(pjsip_msg_body)); 861 pj_strdup(pool, &body->content_type.type, &ctype_hdr->media.type); 862 pj_strdup(pool, &body->content_type.subtype, &ctype_hdr->media.subtype); 863 pj_strdup(pool, &body->content_type.param, &ctype_hdr->media.param); 868 body->content_type.type = ctype_hdr->media.type; 869 body->content_type.subtype = ctype_hdr->media.subtype; 870 body->content_type.param = ctype_hdr->media.param; 871 864 872 body->data = scanner->curptr; 865 873 body->len = scanner->end - scanner->curptr; … … 1002 1010 is_name_addr = 1; 1003 1011 } else { 1004 pj_scan_state backtrack;1005 1012 pj_str_t scheme; 1006 int colon; 1007 1008 pj_scan_save_state( scanner, &backtrack); 1009 pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &scheme); 1010 colon = pj_scan_get_char( scanner ); 1011 pj_scan_restore_state( scanner, &backtrack); 1012 1013 if (colon==':' && 1013 int next_ch; 1014 1015 next_ch = pj_scan_peek( scanner, &pjsip_DISPLAY_SPEC, &scheme); 1016 1017 if (next_ch==':' && 1014 1018 (parser_stricmp(scheme, pjsip_SIP_STR)==0 || 1015 1019 parser_stricmp(scheme, pjsip_SIPS_STR)==0)) … … 1019 1023 (opt & PJSIP_PARSE_URI_IN_FROM_TO_HDR)== 0); 1020 1024 1021 } else if ( colon==':' && parser_stricmp( scheme, pjsip_TEL_STR)==0) {1025 } else if (next_ch==':') { 1022 1026 1023 1027 /* Not supported. */ … … 1190 1194 * will be parser later. 1191 1195 */ 1192 next = pj_scan_peek _until(scanner, &pjsip_DISPLAY_SCAN_SPEC, &dummy);1196 next = pj_scan_peek(scanner, &pjsip_DISPLAY_SPEC, &dummy); 1193 1197 if (next == '<') { 1194 1198 /* Ok, this is what we're looking for, a display name. */ … … 1206 1210 pj_scan_get_char(scanner); 1207 1211 name_addr->uri = int_parse_uri( scanner, pool, PJ_TRUE ); 1208 if (has_bracket) 1209 pj_scan_get_char(scanner); 1212 if (has_bracket) { 1213 if (pj_scan_get_char(scanner) != '>') 1214 PJ_THROW( PJSIP_SYN_ERR_EXCEPTION); 1215 } 1210 1216 1211 1217 return name_addr; … … 1223 1229 1224 1230 req_line->uri = int_parse_uri(scanner, pool, PJ_TRUE); 1225 if (pj_scan_stricmp ( scanner, PJSIP_VERSION, 7) != 0)1231 if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) != 0) 1226 1232 PJ_THROW( PJSIP_SYN_ERR_EXCEPTION); 1227 1233 pj_scan_advance_n (scanner, 7, 1); … … 1235 1241 pj_str_t token; 1236 1242 1237 if (pj_scan_stricmp (scanner, PJSIP_VERSION, 7) != 0)1243 if (pj_scan_stricmp_alnum(scanner, PJSIP_VERSION, 7) != 0) 1238 1244 PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 1239 1245 pj_scan_advance_n( scanner, 7, 1); … … 1241 1247 pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &token); 1242 1248 status_line->code = pj_strtoul(&token); 1243 pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, 1244 &status_line->reason); 1249 pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &status_line->reason); 1245 1250 pj_scan_get_newline( scanner ); 1246 1251 } … … 1268 1273 pj_scanner *scanner) 1269 1274 { 1270 pj_scan_get _until( scanner, &pjsip_ARRAY_ELEMENTS, &hdr->values[0]);1275 pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE, &hdr->values[0]); 1271 1276 hdr->count++; 1272 1277 1273 1278 while (*scanner->curptr == ',') { 1274 1279 pj_scan_get_char(scanner); 1275 pj_scan_get _until( scanner, &pjsip_ARRAY_ELEMENTS,1276 1280 pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE, 1281 &hdr->values[hdr->count]); 1277 1282 hdr->count++; 1278 1283 } … … 1284 1289 pj_scanner *scanner ) 1285 1290 { 1286 pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->hvalue); 1291 if (pj_cis_match(&pjsip_NOT_NEWLINE, *scanner->curptr)) 1292 pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &hdr->hvalue); 1293 else 1294 hdr->hvalue.slen = 0; 1295 1287 1296 parse_hdr_end(scanner); 1288 1297 } … … 1293 1302 { 1294 1303 pj_str_t tmp; 1295 pj_scan_get _until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &tmp);1304 pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &tmp); 1296 1305 hdr->ivalue = pj_strtoul(&tmp); 1297 1306 parse_hdr_end(scanner); … … 1319 1328 { 1320 1329 pjsip_cid_hdr *hdr = pjsip_cid_hdr_create(ctx->pool); 1321 pj_scan_get _until( ctx->scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->id);1330 pj_scan_get( ctx->scanner, &pjsip_NOT_NEWLINE, &hdr->id); 1322 1331 parse_hdr_end(ctx->scanner); 1323 1332 … … 1701 1710 pj_list_insert_before(first, hdr); 1702 1711 1703 if (pj_scan_stricmp ( scanner, PJSIP_VERSION "/", 8) != 0)1712 if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION "/", 8) != 0) 1704 1713 PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 1705 1714
Note: See TracChangeset
for help on using the changeset viewer.