diff --git a/debian/patches/series b/debian/patches/series index 74f40a3d5..ba53221ba 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -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 # diff --git a/debian/patches/sipwise/pv_headers-fix-detection-of-split-marker.patch b/debian/patches/sipwise/pv_headers-fix-detection-of-split-marker.patch new file mode 100644 index 000000000..be6197799 --- /dev/null +++ b/debian/patches/sipwise/pv_headers-fix-detection-of-split-marker.patch @@ -0,0 +1,149 @@ +From: Victor Seva +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" ;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