diff --git a/lib/kcore/strcommon.c b/lib/kcore/strcommon.c index ccc135c110c..3ae237cbacb 100644 --- a/lib/kcore/strcommon.c +++ b/lib/kcore/strcommon.c @@ -373,3 +373,32 @@ int escape_param(str *sin, str *sout) return 0; } +/*! \brief + * escapes a string to use as a CSV field, as specified in RFC4180: + * - enclose sting in double quotes + * - escape double quotes with a second double quote + */ +int escape_csv(str *sin, str *sout) +{ + char *at, *p; + + if (sin==NULL || sout==NULL || sin->s==NULL || sout->s==NULL || + sin->len<0 || sout->len < 2*sin->len+3) + return -1; + + at = sout->s; + p = sin->s; + *at++ = '"'; + while (p < sin->s+sin->len) { + if(*p == '"') { + *at++ = '"'; + } + *at++ = *p++; + } + *at++ = '"'; + *at = 0; + sout->len = at - sout->s; + LM_DBG("escaped string is <%s>\n", sout->s); + + return 0; +} diff --git a/lib/kcore/strcommon.h b/lib/kcore/strcommon.h index a1edc3a2978..e41288434e9 100644 --- a/lib/kcore/strcommon.h +++ b/lib/kcore/strcommon.h @@ -46,5 +46,7 @@ int escape_param(str *sin, str *sout); int unescape_param(str *sin, str *sout); +int escape_csv(str *sin, str *sout); + #endif diff --git a/modules/pv/pv_trans.c b/modules/pv/pv_trans.c index 17ad35d48b1..6836b42e69d 100644 --- a/modules/pv/pv_trans.c +++ b/modules/pv/pv_trans.c @@ -514,6 +514,17 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype, val->flags = PV_VAL_STR; val->rs = st; break; + case TR_S_ESCAPECSV: + if(!(val->flags&PV_VAL_STR)) + val->rs.s = int2str(val->ri, &val->rs.len); + st.s = _tr_buffer; + st.len = TR_BUFFER_SIZE; + if (escape_csv(&val->rs, &st)) + return -1; + memset(val, 0, sizeof(pv_value_t)); + val->flags = PV_VAL_STR; + val->rs = st; + break; case TR_S_SUBSTR: if(tp==NULL || tp->next==NULL) { @@ -2093,6 +2104,9 @@ char* tr_parse_string(str* in, trans_t *t) } else if(name.len==14 && strncasecmp(name.s, "unescape.param", 14)==0) { t->subtype = TR_S_UNESCAPEPARAM; goto done; + } else if(name.len==10 && strncasecmp(name.s, "escape.csv", 10)==0) { + t->subtype = TR_S_ESCAPECSV; + goto done; } else if(name.len==8 && strncasecmp(name.s, "prefixes", 8)==0) { t->subtype = TR_S_PREFIXES; if(*p!=TR_PARAM_MARKER) diff --git a/modules/pv/pv_trans.h b/modules/pv/pv_trans.h index 0d61c8b3db0..c6a702cd1bf 100644 --- a/modules/pv/pv_trans.h +++ b/modules/pv/pv_trans.h @@ -40,7 +40,7 @@ enum _tr_s_subtype { TR_S_ESCAPEPARAM, TR_S_UNESCAPEPARAM, TR_S_TOLOWER, TR_S_TOUPPER, TR_S_STRIP, TR_S_STRIPTAIL, TR_S_PREFIXES, TR_S_PREFIXES_QUOT, TR_S_REPLACE, TR_S_TIMEFORMAT, TR_S_TRIM, TR_S_RTRIM, TR_S_LTRIM, TR_S_RM, TR_S_STRIPTO, - TR_S_URLENCODEPARAM, TR_S_URLDECODEPARAM, TR_S_NUMERIC + TR_S_URLENCODEPARAM, TR_S_URLDECODEPARAM, TR_S_NUMERIC, TR_S_ESCAPECSV }; enum _tr_uri_subtype { TR_URI_NONE=0, TR_URI_USER, TR_URI_HOST, TR_URI_PASSWD, TR_URI_PORT,