diff options
-rw-r--r-- | pjsip/include/pjsip/sip_transport.h | 9 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_parser.c | 50 | ||||
-rw-r--r-- | tests/pjsua/scripts-sipp/uac-inv-multiple-require.xml | 91 |
3 files changed, 138 insertions, 12 deletions
diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h index 0e461638..b971762f 100644 --- a/pjsip/include/pjsip/sip_transport.h +++ b/pjsip/include/pjsip/sip_transport.h @@ -385,9 +385,16 @@ struct pjsip_rx_data /** Content-length header. */ pjsip_clen_hdr *clen; - /** The first Require header. */ + /** "Require" header containing aggregates of all Require + * headers found in the message, or NULL. + */ pjsip_require_hdr *require; + /** "Supported" header containing aggregates of all Supported + * headers found in the message, or NULL. + */ + pjsip_supported_hdr *supported; + /** The list of error generated by the parser when parsing this message. */ diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c index a5a8e033..5f004ca1 100644 --- a/pjsip/src/pjsip/sip_parser.c +++ b/pjsip/src/pjsip/sip_parser.c @@ -1007,11 +1007,17 @@ parse_headers: if (handler) { hdr = (*handler)(ctx); + /* Note: + * hdr MAY BE NULL, if parsing does not yield a new header + * instance, e.g. the values have been added to existing + * header. See http://trac.pjsip.org/repos/ticket/940 + */ + /* Check if we've just parsed a Content-Type header. * We will check for a message body if we've got Content-Type * header. */ - if (hdr->type == PJSIP_H_CONTENT_TYPE) { + if (hdr && hdr->type == PJSIP_H_CONTENT_TYPE) { ctype_hdr = (pjsip_ctype_hdr*)hdr; } @@ -1027,7 +1033,8 @@ parse_headers: * different Contact headers. * So here we must insert list instead of just insert one header. */ - pj_list_insert_nodes_before(&msg->hdr, hdr); + if (hdr) + pj_list_insert_nodes_before(&msg->hdr, hdr); /* Parse until EOF or an empty line is found. */ } while (!pj_scan_is_eof(scanner) && !IS_NEWLINE(*scanner->curptr)); @@ -1639,7 +1646,14 @@ static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr, goto end; } - pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE, &hdr->values[0]); + if (hdr->count >= PJ_ARRAY_SIZE(hdr->values)) { + /* Too many elements */ + on_syntax_error(scanner); + return; + } + + pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE, + &hdr->values[hdr->count]); hdr->count++; while (*scanner->curptr == ',') { @@ -1917,13 +1931,19 @@ static pjsip_hdr* parse_hdr_from( pjsip_parse_ctx *ctx ) /* Parse Require: header. */ static pjsip_hdr* parse_hdr_require( pjsip_parse_ctx *ctx ) { - pjsip_require_hdr *hdr = pjsip_require_hdr_create(ctx->pool); - parse_generic_array_hdr(hdr, ctx->scanner); + pjsip_require_hdr *hdr; + pj_bool_t new_hdr = (ctx->rdata->msg_info.require == NULL); + + if (ctx->rdata && ctx->rdata->msg_info.require) { + hdr = ctx->rdata->msg_info.require; + } else { + hdr = pjsip_require_hdr_create(ctx->pool); + ctx->rdata->msg_info.require = hdr; + } - if (ctx->rdata && ctx->rdata->msg_info.require == NULL) - ctx->rdata->msg_info.require = hdr; + parse_generic_array_hdr(hdr, ctx->scanner); - return (pjsip_hdr*)hdr; + return new_hdr ? (pjsip_hdr*)hdr : NULL; } /* Parse Retry-After: header. */ @@ -1960,12 +1980,20 @@ static pjsip_hdr* parse_hdr_retry_after(pjsip_parse_ctx *ctx) /* Parse Supported: header. */ static pjsip_hdr* parse_hdr_supported(pjsip_parse_ctx *ctx) { - pjsip_supported_hdr *hdr = pjsip_supported_hdr_create(ctx->pool); + pjsip_supported_hdr *hdr; + pj_bool_t new_hdr = (ctx->rdata->msg_info.supported == NULL); + + if (ctx->rdata && ctx->rdata->msg_info.supported) { + hdr = ctx->rdata->msg_info.supported; + } else { + hdr = pjsip_supported_hdr_create(ctx->pool); + ctx->rdata->msg_info.supported = hdr; + } + parse_generic_array_hdr(hdr, ctx->scanner); - return (pjsip_hdr*)hdr; + return new_hdr ? (pjsip_hdr*)hdr : NULL; } - /* Parse To: header. */ static pjsip_hdr* parse_hdr_to( pjsip_parse_ctx *ctx ) { diff --git a/tests/pjsua/scripts-sipp/uac-inv-multiple-require.xml b/tests/pjsua/scripts-sipp/uac-inv-multiple-require.xml new file mode 100644 index 00000000..b0790f6e --- /dev/null +++ b/tests/pjsua/scripts-sipp/uac-inv-multiple-require.xml @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+
+<scenario name="Multiple Require header fields">
+ <!-- UAC with bad ACK causes assertion with pjsip 1.4 -->
+ <send retrans="500">
+ <![CDATA[
+
+ INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+ From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
+ To: sut <sip:[service]@[remote_ip]:[remote_port]>
+ Call-ID: [call_id]
+ CSeq: 1 INVITE
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Require: timer
+ Require: toto
+ Subject: Performance Test
+ Content-Type: application/sdp
+ Content-Length: [len]
+
+ v=0
+ o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+ s=-
+ c=IN IP[media_ip_type] [media_ip]
+ t=0 0
+ m=audio [media_port] RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+
+ ]]>
+ </send>
+
+ <recv response="100"
+ optional="true">
+ </recv>
+
+ <recv response="180" optional="true">
+ </recv>
+
+ <recv response="200" rtd="true">
+ </recv>
+
+ <send>
+ <![CDATA[
+
+ ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+ From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
+ To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
+ Call-ID: [call_id]
+ CSeq: 1 ACK
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Subject: Performance Test
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <pause/>
+
+ <send retrans="500">
+ <![CDATA[
+
+ BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=z9hG4bK-1
+ From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
+ To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
+ Call-ID: [call_id]
+ CSeq: 2 BYE
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Subject: Performance Test
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <recv response="200" crlf="true">
+ </recv>
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
|