summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-07-17 10:04:12 +0000
committerBenny Prijono <bennylp@teluu.com>2006-07-17 10:04:12 +0000
commit7e998fa0ffc4fdfeb742ccd907a4b443ef79293d (patch)
tree1eacf47d6c8b6cf98d30da9be717bba73ae128d2
parent6244290e262fa290196b1ef2f1cec16fd193382e (diff)
Fixed bugs with the parsing (re: allowable chars): (1) Parameters in URI and header should have different spec. URI should use paramchar spec while header should use token spec (thanks Jeroen van Bemmel) (2) The same rule applies when escaping the parameters during printing process (3) While we're on it, also fixed the tel-URI parser to automatically unescape the parameter values.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@606 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/include/pjsip/sip_parser.h10
-rw-r--r--pjsip/src/pjsip-simple/evsub_msg.c8
-rw-r--r--pjsip/src/pjsip/sip_auth_msg.c8
-rw-r--r--pjsip/src/pjsip/sip_msg.c16
-rw-r--r--pjsip/src/pjsip/sip_parser.c60
-rw-r--r--pjsip/src/pjsip/sip_tel_uri.c21
6 files changed, 94 insertions, 29 deletions
diff --git a/pjsip/include/pjsip/sip_parser.h b/pjsip/include/pjsip/sip_parser.h
index 54dd52df..fe788395 100644
--- a/pjsip/include/pjsip/sip_parser.h
+++ b/pjsip/include/pjsip/sip_parser.h
@@ -314,7 +314,7 @@ extern pj_cis_t
pjsip_TOKEN_SPEC, /**< Token. */
pjsip_HEX_SPEC, /**< Hexadecimal digits. */
pjsip_PARAM_CHAR_SPEC, /**< For scanning pname (or pvalue when it's
- not quoted.) */
+ not quoted.) in URI */
pjsip_PARAM_CHAR_SPEC_ESC, /**< Variant without the escape ('%') char */
pjsip_HDR_CHAR_SPEC, /**< Chars in hname/havalue in URL. */
pjsip_HDR_CHAR_SPEC_ESC, /**< Variant without the escape ('%') char */
@@ -356,11 +356,17 @@ enum
PJSIP_PARSE_REMOVE_QUOTE = 1,
};
+/* Parse parameter in header (matching the character as token) */
void pjsip_parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,
pj_str_t *pname, pj_str_t *pvalue,
unsigned opt);
+/* Parse parameter in URL (matching the character as paramchar) */
+void pjsip_parse_uri_param_imp( pj_scanner *scanner, pj_pool_t *pool,
+ pj_str_t *pname, pj_str_t *pvalue,
+ unsigned opt);
void pjsip_concat_param_imp( pj_str_t *param, pj_pool_t *pool,
- const pj_str_t *pname, const pj_str_t *pvalue, int sepchar);
+ const pj_str_t *pname, const pj_str_t *pvalue,
+ int sepchar);
void pjsip_parse_end_hdr_imp ( pj_scanner *scanner );
PJ_END_DECL
diff --git a/pjsip/src/pjsip-simple/evsub_msg.c b/pjsip/src/pjsip-simple/evsub_msg.c
index 7fd44d32..cf73527c 100644
--- a/pjsip/src/pjsip-simple/evsub_msg.c
+++ b/pjsip/src/pjsip-simple/evsub_msg.c
@@ -70,8 +70,8 @@ static int pjsip_event_hdr_print( pjsip_event_hdr *hdr,
copy_advance_pair(p, ";id=", 4, hdr->id_param);
printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,
- &pjsip_PARAM_CHAR_SPEC,
- &pjsip_PARAM_CHAR_SPEC, ';');
+ &pjsip_TOKEN_SPEC,
+ &pjsip_TOKEN_SPEC, ';');
if (printed < 0)
return printed;
@@ -180,8 +180,8 @@ static int pjsip_sub_state_hdr_print(pjsip_sub_state_hdr *hdr,
}
printed = pjsip_param_print_on( &hdr->other_param, p, endbuf-p,
- &pjsip_PARAM_CHAR_SPEC,
- &pjsip_PARAM_CHAR_SPEC,
+ &pjsip_TOKEN_SPEC,
+ &pjsip_TOKEN_SPEC,
';');
if (printed < 0)
return printed;
diff --git a/pjsip/src/pjsip/sip_auth_msg.c b/pjsip/src/pjsip/sip_auth_msg.c
index 84c41cc9..011e2556 100644
--- a/pjsip/src/pjsip/sip_auth_msg.c
+++ b/pjsip/src/pjsip/sip_auth_msg.c
@@ -81,8 +81,8 @@ static int print_digest_credential(pjsip_digest_credential *cred, char *buf, pj_
copy_advance_pair(buf, ", nc=", 5, cred->nc);
printed = pjsip_param_print_on(&cred->other_param, buf, endbuf-buf,
- &pjsip_PARAM_CHAR_SPEC,
- &pjsip_PARAM_CHAR_SPEC, ',');
+ &pjsip_TOKEN_SPEC,
+ &pjsip_TOKEN_SPEC, ',');
if (printed < 0)
return -1;
buf += printed;
@@ -235,8 +235,8 @@ static int print_digest_challenge( pjsip_digest_challenge *chal,
copy_advance_pair_quote_cond(buf, ",qop=", 5, chal->qop, '"', '"');
printed = pjsip_param_print_on(&chal->other_param, buf, endbuf-buf,
- &pjsip_PARAM_CHAR_SPEC,
- &pjsip_PARAM_CHAR_SPEC, ',');
+ &pjsip_TOKEN_SPEC,
+ &pjsip_TOKEN_SPEC, ',');
if (printed < 0)
return -1;
buf += printed;
diff --git a/pjsip/src/pjsip/sip_msg.c b/pjsip/src/pjsip/sip_msg.c
index d6a33339..72808a5c 100644
--- a/pjsip/src/pjsip/sip_msg.c
+++ b/pjsip/src/pjsip/sip_msg.c
@@ -1039,8 +1039,8 @@ static int pjsip_contact_hdr_print( pjsip_contact_hdr *hdr, char *buf,
}
printed = pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf,
- &pjsip_PARAM_CHAR_SPEC,
- &pjsip_PARAM_CHAR_SPEC, ';');
+ &pjsip_TOKEN_SPEC, &pjsip_TOKEN_SPEC,
+ ';');
if (printed < 0)
return printed;
buf += printed;
@@ -1282,8 +1282,8 @@ static int pjsip_fromto_hdr_print( pjsip_fromto_hdr *hdr,
copy_advance_pair(buf, ";tag=", 5, hdr->tag);
printed = pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf,
- &pjsip_PARAM_CHAR_SPEC,
- &pjsip_PARAM_CHAR_SPEC, ';');
+ &pjsip_TOKEN_SPEC,
+ &pjsip_TOKEN_SPEC, ';');
if (printed < 0)
return -1;
buf += printed;
@@ -1453,8 +1453,8 @@ static int pjsip_routing_hdr_print( pjsip_routing_hdr *hdr,
buf += printed;
printed = pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf,
- &pjsip_PARAM_CHAR_SPEC,
- &pjsip_PARAM_CHAR_SPEC, ';');
+ &pjsip_TOKEN_SPEC,
+ &pjsip_TOKEN_SPEC, ';');
if (printed < 0)
return -1;
buf += printed;
@@ -1672,8 +1672,8 @@ static int pjsip_via_hdr_print( pjsip_via_hdr *hdr,
copy_advance_pair(buf, ";branch=", 8, hdr->branch_param);
printed = pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf,
- &pjsip_PARAM_CHAR_SPEC,
- &pjsip_PARAM_CHAR_SPEC, ';');
+ &pjsip_TOKEN_SPEC,
+ &pjsip_TOKEN_SPEC, ';');
if (printed < 0)
return -1;
buf += printed;
diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c
index b0fbc0d8..df9f02f8 100644
--- a/pjsip/src/pjsip/sip_parser.c
+++ b/pjsip/src/pjsip/sip_parser.c
@@ -40,8 +40,8 @@
#define ESCAPED "%"
#define USER_UNRESERVED "&=+$,;?/"
#define PASS "&=+$,"
-#define TOKEN "-.!%*_=`'~+" /* '+' is because of app/pidf+xml
- * in Content-Type! */
+#define TOKEN "-.!%*_`'~+" /* '=' was removed for parsing
+ * param */
#define HOST "_-."
#define HEX_DIGIT "abcdefABCDEF"
#define PARAM_CHAR "[]/:&+$" UNRESERVED ESCAPED
@@ -138,6 +138,10 @@ static void int_parse_param( pj_scanner *scanner,
pj_pool_t *pool,
pj_str_t *pname,
pj_str_t *pvalue);
+static void int_parse_uri_param( pj_scanner *scanner,
+ pj_pool_t *pool,
+ pj_str_t *pname,
+ pj_str_t *pvalue);
static void int_parse_hparam( pj_scanner *scanner,
pj_pool_t *pool,
pj_str_t *hname,
@@ -324,6 +328,9 @@ static pj_status_t init_parser()
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
pj_cis_add_str( &pjsip_TOKEN_SPEC, TOKEN);
+ /* TOKEN must not have '%' */
+ pj_assert(pj_cis_match(&pjsip_TOKEN_SPEC, '%')==0);
+
status = pj_cis_dup(&pjsip_HOST_SPEC, &pjsip_ALNUM_SPEC);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
pj_cis_add_str( &pjsip_HOST_SPEC, HOST);
@@ -1038,14 +1045,15 @@ parse_headers:
return msg;
}
+
/* Parse parameter (pname ["=" pvalue]). */
-void pjsip_parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,
+static void parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,
pj_str_t *pname, pj_str_t *pvalue,
+ const pj_cis_t *spec, const pj_cis_t *esc_spec,
unsigned option)
{
/* pname */
- parser_get_and_unescape(scanner, pool, &pjsip_PARAM_CHAR_SPEC,
- &pjsip_PARAM_CHAR_SPEC_ESC, pname);
+ parser_get_and_unescape(scanner, pool, spec, esc_spec, pname);
/* init pvalue */
pvalue->ptr = NULL;
@@ -1062,15 +1070,34 @@ void pjsip_parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,
pvalue->ptr++;
pvalue->slen -= 2;
}
- } else if(pj_cis_match(&pjsip_PARAM_CHAR_SPEC, *scanner->curptr)) {
- parser_get_and_unescape(scanner, pool, &pjsip_PARAM_CHAR_SPEC,
- &pjsip_PARAM_CHAR_SPEC_ESC, pvalue);
+ } else if(pj_cis_match(spec, *scanner->curptr)) {
+ parser_get_and_unescape(scanner, pool, spec, esc_spec, pvalue);
}
}
}
}
-/* Parse parameter (";" pname ["=" pvalue]). */
+/* Parse parameter (pname ["=" pvalue]) using token. */
+void pjsip_parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,
+ pj_str_t *pname, pj_str_t *pvalue,
+ unsigned option)
+{
+ parse_param_imp(scanner, pool, pname, pvalue, &pjsip_TOKEN_SPEC,
+ &pjsip_TOKEN_SPEC, option);
+}
+
+
+/* Parse parameter (pname ["=" pvalue]) using paramchar. */
+void pjsip_parse_uri_param_imp(pj_scanner *scanner, pj_pool_t *pool,
+ pj_str_t *pname, pj_str_t *pvalue,
+ unsigned option)
+{
+ parse_param_imp(scanner, pool, pname, pvalue, &pjsip_PARAM_CHAR_SPEC,
+ &pjsip_PARAM_CHAR_SPEC_ESC, option);
+}
+
+
+/* Parse parameter (";" pname ["=" pvalue]) in header. */
static void int_parse_param( pj_scanner *scanner, pj_pool_t *pool,
pj_str_t *pname, pj_str_t *pvalue)
{
@@ -1082,6 +1109,19 @@ static void int_parse_param( pj_scanner *scanner, pj_pool_t *pool,
PJSIP_PARSE_REMOVE_QUOTE);
}
+/* Parse parameter (";" pname ["=" pvalue]) in URI. */
+static void int_parse_uri_param( pj_scanner *scanner, pj_pool_t *pool,
+ pj_str_t *pname, pj_str_t *pvalue)
+{
+ /* Get ';' character */
+ pj_scan_get_char(scanner);
+
+ /* Get pname and optionally pvalue */
+ pjsip_parse_uri_param_imp(scanner, pool, pname, pvalue,
+ PJSIP_PARSE_REMOVE_QUOTE);
+}
+
+
/* Parse header parameter. */
static void int_parse_hparam( pj_scanner *scanner, pj_pool_t *pool,
pj_str_t *hname, pj_str_t *hvalue )
@@ -1297,7 +1337,7 @@ static void* int_parse_sip_url( pj_scanner *scanner,
while (*scanner->curptr == ';' ) {
pj_str_t pname, pvalue;
- int_parse_param( scanner, pool, &pname, &pvalue);
+ int_parse_uri_param( scanner, pool, &pname, &pvalue);
if (!parser_stricmp(pname, pjsip_USER_STR) && pvalue.slen) {
url->user_param = pvalue;
diff --git a/pjsip/src/pjsip/sip_tel_uri.c b/pjsip/src/pjsip/sip_tel_uri.c
index 34d28b15..04141b86 100644
--- a/pjsip/src/pjsip/sip_tel_uri.c
+++ b/pjsip/src/pjsip/sip_tel_uri.c
@@ -55,7 +55,9 @@ static pj_cis_t pjsip_TEL_URIC_SPEC;
static pj_cis_t pjsip_TEL_VISUAL_SEP_SPEC;
static pj_cis_t pjsip_TEL_PNAME_SPEC;
static pj_cis_t pjsip_TEL_PVALUE_SPEC;
+static pj_cis_t pjsip_TEL_PVALUE_SPEC_ESC;
static pj_cis_t pjsip_TEL_PARSING_PVALUE_SPEC;
+static pj_cis_t pjsip_TEL_PARSING_PVALUE_SPEC_ESC;
static pj_str_t pjsip_ISUB_STR = { "isub", 4 };
static pj_str_t pjsip_EXT_STR = { "ext", 3 };
@@ -152,11 +154,18 @@ pj_status_t pjsip_tel_uri_subsys_init(void)
pj_cis_add_num(&pjsip_TEL_PVALUE_SPEC);
pj_cis_add_str(&pjsip_TEL_PVALUE_SPEC, PARAM_CHAR);
+ status = pj_cis_dup(&pjsip_TEL_PVALUE_SPEC_ESC, &pjsip_TEL_PVALUE_SPEC);
+ pj_cis_del_str(&pjsip_TEL_PVALUE_SPEC_ESC, "%");
+
status = pj_cis_dup(&pjsip_TEL_PARSING_PVALUE_SPEC, &pjsip_TEL_URIC_SPEC);
PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
pj_cis_add_cis(&pjsip_TEL_PARSING_PVALUE_SPEC, &pjsip_TEL_PVALUE_SPEC);
pj_cis_add_str(&pjsip_TEL_PARSING_PVALUE_SPEC, "=");
+ status = pj_cis_dup(&pjsip_TEL_PARSING_PVALUE_SPEC_ESC,
+ &pjsip_TEL_PARSING_PVALUE_SPEC);
+ pj_cis_del_str(&pjsip_TEL_PVALUE_SPEC_ESC, "%");
+
status = pjsip_register_uri_parser("tel", &tel_uri_parse);
PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
@@ -393,7 +402,17 @@ static void* tel_uri_parse( pj_scanner *scanner, pj_pool_t *pool,
if (*scanner->curptr == '=') {
pj_scan_get_char(scanner);
- pj_scan_get(scanner, &pjsip_TEL_PARSING_PVALUE_SPEC, &pvalue);
+
+# if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0
+ pj_scan_get_unescape( scanner,
+ &pjsip_TEL_PARSING_PVALUE_SPEC_ESC,
+ &pvalue);
+# else
+ pj_scan_get(scanner, &pjsip_TEL_PARSING_PVALUE_SPEC,
+ &pvalue);
+ *token = pj_str_unescape(pool, &pvalue);
+# endif
+
} else {
pvalue.slen = 0;
pvalue.ptr = NULL;