summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-11-04 13:17:31 +0000
committerBenny Prijono <bennylp@teluu.com>2009-11-04 13:17:31 +0000
commit5bba86aff1c5236d9f106e3e13fbfa4954556898 (patch)
tree006da74263fa71bcc0959b39c0a93b8147c6eef9 /pjsip
parentffb29852a54771b54218e24595b123f1f5b96e22 (diff)
Fixed ticket #940: Multiple header rows with the same name may not be completely processed by PJSIP modules
- the parser now collect and aggregate all Supported/Require header fields into single header git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2985 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsip/sip_transport.h9
-rw-r--r--pjsip/src/pjsip/sip_parser.c50
2 files changed, 47 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 )
{