TT#114315 pv_headers: fix split detection marker

If we set Diversion in split_headers and we get a header like
> "RULTEST, normalaa" <sip:0046341355354340@whatever.net;user=phone>;reason=unconditional

There was false detection of two Diversion headers.

Skip split marker between double quotes to avoid this

Change-Id: Ib2189bc0029f244fd59f14df5b3d1df745271038
(cherry picked from commit a812be8e0f)
mr9.3
Victor Seva 5 years ago
parent 45bb6b5572
commit f642443991
No known key found for this signature in database
GPG Key ID: B1589889727198E0

@ -59,6 +59,7 @@ sipwise/db_redis_skip_empty_keys.patch
sipwise/db_redis_graceful_scan.patch
sipwise/db_redis_sscan.patch
sipwise/db_redis_sscan_fix_empty_key.patch
sipwise/pv_headers-fix-detection-of-split-marker.patch
### active development
sipwise/lcr-stopper_mode-parameter.patch
#

@ -0,0 +1,149 @@
From: Victor Seva <vseva@sipwise.com>
Date: Wed, 10 Mar 2021 18:36:18 +0100
Subject: pv_headers: fix detection of split marker
If we set Diversion in split_headers and we get a header like
> "RULTEST, normalaa" <sip:0046341355354340@whatever.net;user=phone>;reason=unconditional
There was false detection of two Diversion headers.
Skip split marker between double quotes to avoid this
---
src/modules/pv_headers/pvh_func.c | 5 ++--
src/modules/pv_headers/pvh_hash.c | 2 +-
src/modules/pv_headers/pvh_str.c | 50 ++++++++++++++++++++++++++++++++-------
src/modules/pv_headers/pvh_str.h | 5 ++--
4 files changed, 49 insertions(+), 13 deletions(-)
diff --git a/src/modules/pv_headers/pvh_func.c b/src/modules/pv_headers/pvh_func.c
index 749275e..90fedde 100644
--- a/src/modules/pv_headers/pvh_func.c
+++ b/src/modules/pv_headers/pvh_func.c
@@ -62,6 +62,7 @@ int pvh_collect_headers(struct sip_msg *msg)
char hvals[header_name_size][header_value_size];
int idx = 0, d_size = 0;
str val_part = STR_NULL;
+ char *marker = NULL;
if(pvh_hdrs_collected(msg)) {
LM_ERR("headers are already collected\n");
@@ -95,10 +96,10 @@ int pvh_collect_headers(struct sip_msg *msg)
val.len = hf->body.len;
val.s = hf->body.s;
- if(strchr(val.s, ',') != NULL
+ if(( marker = pvh_detect_split_char(val.s)) != NULL
&& str_hash_case_get(&split_headers, name.s, name.len)) {
- if(pvh_split_values(&val, hvals, &d_size, 1) < 0) {
+ if(pvh_split_values(&val, hvals, &d_size, 1, marker) < 0) {
LM_ERR("could not parse %.*s header comma separated "
"value",
name.len, name.s);
diff --git a/src/modules/pv_headers/pvh_hash.c b/src/modules/pv_headers/pvh_hash.c
index 80297bc..545fcd0 100644
--- a/src/modules/pv_headers/pvh_hash.c
+++ b/src/modules/pv_headers/pvh_hash.c
@@ -37,7 +37,7 @@ int pvh_str_hash_init(struct str_hash_table *ht, str *keys, char *desc)
int idx = 0, d_size = 0;
str val = STR_NULL;
- if(pvh_split_values(keys, split, &d_size, 0) < 0) {
+ if(pvh_split_values(keys, split, &d_size, 0, NULL) < 0) {
LM_ERR("could not parse %s param\n", desc);
return -1;
}
diff --git a/src/modules/pv_headers/pvh_str.c b/src/modules/pv_headers/pvh_str.c
index 6ede032..60c1a2f 100644
--- a/src/modules/pv_headers/pvh_str.c
+++ b/src/modules/pv_headers/pvh_str.c
@@ -103,10 +103,39 @@ int pvh_extract_display_uri(char *suri, str *display, str *duri)
return 1;
}
-int pvh_split_values(
- str *s, char d[][header_value_size], int *d_size, int keep_spaces)
+char *pvh_detect_split_char(char *val)
{
- char p;
+ char *quote_a = NULL, *quote_b = NULL;
+ char *split = NULL;
+
+ if(val == NULL)
+ return NULL;
+
+ split = strchr(val, ',');
+ if(split == NULL) {
+ LM_DBG("no split marker detected\n");
+ return NULL;
+ }
+
+ quote_a = strchr(val, '"');
+ if(quote_a == NULL || split < quote_a) {
+ LM_DBG("split marker detected[%ld], not between quotes\n", split - val);
+ return split;
+ }
+
+ quote_b = strchr(val + (split - quote_a + 1), '"');
+ if(quote_b == NULL) {
+ LM_DBG("split marker detected[%ld], quote occurrence unbalanced[%ld]\n",
+ split - val, quote_b - val);
+ return split;
+ }
+ return pvh_detect_split_char(val + (quote_b - val + 1));
+}
+
+int pvh_split_values(str *s, char d[][header_value_size], int *d_size,
+ int keep_spaces, char *marker)
+{
+ char *p = NULL;
int idx = 0, c_idx = 0;
*d_size = -1;
@@ -115,12 +144,17 @@ int pvh_split_values(
*d_size = 0;
return 1;
}
-
+ if(!marker)
+ marker = pvh_detect_split_char(s->s);
while(idx < s->len) {
- strncpy(&p, s->s + idx++, 1);
- if(keep_spaces == 0 && strncmp(&p, " ", 1) == 0)
+ p = s->s + idx++;
+ if(keep_spaces == 0 && strncmp(p, " ", 1) == 0)
continue;
- if(strncmp(&p, ",", 1) == 0) {
+ if(p == marker) {
+ if(marker && idx < s->len) {
+ LM_DBG("search next split marker[%d]\n", idx);
+ marker = pvh_detect_split_char(p + 1);
+ }
if(c_idx == 0)
continue;
if(c_idx + 1 < header_value_size)
@@ -131,7 +165,7 @@ int pvh_split_values(
}
if(c_idx == 0)
(*d_size)++;
- strncpy(&d[*d_size][c_idx++], &p, 1);
+ strncpy(&d[*d_size][c_idx++], p, 1);
}
if(c_idx > 0) {
diff --git a/src/modules/pv_headers/pvh_str.h b/src/modules/pv_headers/pvh_str.h
index 10aa216..24feb33 100644
--- a/src/modules/pv_headers/pvh_str.h
+++ b/src/modules/pv_headers/pvh_str.h
@@ -34,7 +34,8 @@ int pvh_str_new(str *s, int size);
int pvh_str_free(str *s);
int pvh_str_copy(str *dst, str *src, unsigned int max_size);
int pvh_extract_display_uri(char *suri, str *display, str *duri);
-int pvh_split_values(
- str *s, char d[][header_value_size], int *d_size, int keep_spaces);
+char *pvh_detect_split_char(char *s);
+int pvh_split_values(str *s, char d[][header_value_size], int *d_size,
+ int keep_spaces, char *marker);
#endif /* PV_STR_H */
\ No newline at end of file
Loading…
Cancel
Save