diff --git a/debian/patches/series b/debian/patches/series index d95af0bd2..80f1f123b 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -23,6 +23,10 @@ upstream/debug/modules-debugger-add-dbg_pv_dump-config-function.patch upstream/debug/reset_msgid.patch upstream/websocket.patch upstream/uac_redirect-get_redirect-check-reason-value-before-.patch +upstream/avpops-allow-use-of-avps-as-second-parameter-on-re-o.patch +upstream/avops-use-pv_cache_get-instead-of-pv_parse_spec.patch +upstream/pv-Move-pv_xavp_name_t-declaration-to-core-pvar.h.patch +upstream/avpops-allow-xavp-semantics-on-second-parameter.patch no_lib64_on_64_bits.patch no_INSTALL_file.patch fix_export.patch diff --git a/debian/patches/upstream/avops-use-pv_cache_get-instead-of-pv_parse_spec.patch b/debian/patches/upstream/avops-use-pv_cache_get-instead-of-pv_parse_spec.patch new file mode 100644 index 000000000..51f7a37e2 --- /dev/null +++ b/debian/patches/upstream/avops-use-pv_cache_get-instead-of-pv_parse_spec.patch @@ -0,0 +1,444 @@ +From 108b28dfc603f6f6bb41afdb8312805d6f9c83f4 Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Wed, 18 Sep 2013 14:15:17 +0200 +Subject: [PATCH] avops: use pv_cache_get instead of pv_parse_spec. + +--- + modules/avpops/avpops.c | 28 ++++++++++----------- + modules/avpops/avpops_impl.c | 56 ++++++++++++++++++++--------------------- + modules/avpops/avpops_impl.h | 2 +- + modules/avpops/avpops_parse.c | 28 ++++++++++----------- + 4 files changed, 57 insertions(+), 57 deletions(-) + +diff --git a/modules/avpops/avpops.c b/modules/avpops/avpops.c +index 674469b..1f793d6 100644 +--- a/modules/avpops/avpops.c ++++ b/modules/avpops/avpops.c +@@ -266,16 +266,16 @@ static int fixup_db_avp(void** param, int param_no, int allow_scheme) + } else { + /* is a variable $xxxxx */ + s.len = strlen(s.s); +- p = pv_parse_spec(&s, &sp->u.sval); +- if (p==0 || sp->u.sval.type==PVT_NULL || sp->u.sval.type==PVT_EMPTY) ++ sp->u.sval = pv_cache_get(&s); ++ if (sp->u.sval==0 || sp->u.sval->type==PVT_NULL || sp->u.sval->type==PVT_EMPTY) + { + LM_ERR("bad param 1; " + "expected : $pseudo-variable or int/str value\n"); + return E_UNSPEC; + } + +- if(sp->u.sval.type==PVT_RURI || sp->u.sval.type==PVT_FROM +- || sp->u.sval.type==PVT_TO || sp->u.sval.type==PVT_OURI) ++ if(sp->u.sval->type==PVT_RURI || sp->u.sval->type==PVT_FROM ++ || sp->u.sval->type==PVT_TO || sp->u.sval->type==PVT_OURI) + { + sp->opd = ((flags==0)?AVPOPS_FLAG_URI0:flags)|AVPOPS_VAL_PVAR; + } else { +@@ -396,7 +396,7 @@ static int fixup_delete_avp(void** param, int param_no) + " pseudo-variable in param \n"); + return E_UNSPEC; + } +- if (ap->u.sval.type!=PVT_AVP) ++ if (ap->u.sval->type!=PVT_AVP) + { + LM_ERR("bad param; expected : $avp(name)\n"); + return E_UNSPEC; +@@ -500,7 +500,7 @@ static int fixup_copy_avp(void** param, int param_no) + } + + /* attr name is mandatory */ +- if (ap->u.sval.type!=PVT_AVP) ++ if (ap->u.sval->type!=PVT_AVP) + { + LM_ERR("you must specify only AVP as parameter\n"); + return E_UNSPEC; +@@ -566,7 +566,7 @@ static int fixup_pushto_avp(void** param, int param_no) + return E_OUT_OF_MEM; + } + +- switch(ap->u.sval.type) { ++ switch(ap->u.sval->type) { + case PVT_RURI: + ap->opd = AVPOPS_VAL_NONE|AVPOPS_USE_RURI; + if ( p && !( +@@ -623,7 +623,7 @@ static int fixup_pushto_avp(void** param, int param_no) + LM_ERR("unable to get pseudo-variable in param 2\n"); + return E_OUT_OF_MEM; + } +- if (ap->u.sval.type==PVT_NULL) ++ if (ap->u.sval->type==PVT_NULL) + { + LM_ERR("bad param 2; expected : $pseudo-variable ...\n"); + pkg_free(ap); +@@ -669,7 +669,7 @@ static int fixup_check_avp(void** param, int param_no) + return E_OUT_OF_MEM; + } + /* attr name is mandatory */ +- if (ap->u.sval.type==PVT_NULL) ++ if (ap->u.sval->type==PVT_NULL) + { + LM_ERR("null pseudo-variable in param 1\n"); + return E_UNSPEC; +@@ -745,7 +745,7 @@ static int fixup_subst(void** param, int param_no) + LM_ERR("unable to get pseudo-variable in param 2 [%s]\n", s); + return E_OUT_OF_MEM; + } +- if (ap->u.sval.type!=PVT_AVP) ++ if (ap->u.sval->type!=PVT_AVP) + { + LM_ERR("bad attribute name <%s>\n", (char*)*param); + pkg_free(av); +@@ -779,7 +779,7 @@ static int fixup_subst(void** param, int param_no) + return E_OUT_OF_MEM; + } + +- if (ap->u.sval.type!=PVT_AVP) ++ if (ap->u.sval->type!=PVT_AVP) + { + LM_ERR("bad attribute name <%s>!\n", s); + pkg_free(av); +@@ -865,7 +865,7 @@ static int fixup_op_avp(void** param, int param_no) + LM_ERR("unable to get pseudo-variable in param 1\n"); + return E_OUT_OF_MEM; + } +- if (av[0]->u.sval.type!=PVT_AVP) ++ if (av[0]->u.sval->type!=PVT_AVP) + { + LM_ERR("bad attribute name <%s>\n", (char*)*param); + pkg_free(av); +@@ -884,7 +884,7 @@ static int fixup_op_avp(void** param, int param_no) + LM_ERR("unable to get pseudo-variable in param 1 (2)\n"); + return E_OUT_OF_MEM; + } +- if (ap->u.sval.type!=PVT_AVP) ++ if (ap->u.sval->type!=PVT_AVP) + { + LM_ERR("bad attribute name/alias <%s>!\n", s); + pkg_free(av); +@@ -930,7 +930,7 @@ static int fixup_is_avp_set(void** param, int param_no) + return E_OUT_OF_MEM; + } + +- if (ap->u.sval.type!=PVT_AVP) ++ if (ap->u.sval->type!=PVT_AVP) + { + LM_ERR("bad attribute name <%s>\n", (char*)*param); + return E_UNSPEC; +diff --git a/modules/avpops/avpops_impl.c b/modules/avpops/avpops_impl.c +index 7dcd371..65a5239 100644 +--- a/modules/avpops/avpops_impl.c ++++ b/modules/avpops/avpops_impl.c +@@ -216,7 +216,7 @@ static int dbrow2avp(struct db_row *row, struct db_param *dbp, int_str attr, + /* added the avp */ + db_flags |= AVP_IS_IN_DB; + /* set script flags */ +- db_flags |= dbp->a.u.sval.pvp.pvn.u.isname.type&0xff00; ++ db_flags |= dbp->a.u.sval->pvp.pvn.u.isname.type&0xff00; + return add_avp( (unsigned short)db_flags, avp_attr, avp_val); + } + +@@ -274,7 +274,7 @@ static int avpops_get_aname(struct sip_msg* msg, struct fis_param *ap, + return -1; + } + +- return pv_get_avp_name(msg, &ap->u.sval.pvp, avp_name, name_type); ++ return pv_get_avp_name(msg, &ap->u.sval->pvp, avp_name, name_type); + } + + #define AVPOPS_ATTR_LEN 64 +@@ -301,7 +301,7 @@ int ops_dbload_avps (struct sip_msg* msg, struct fis_param *sp, + /* get uuid from avp */ + if (sp->opd&AVPOPS_VAL_PVAR) + { +- if(pv_get_spec_value(msg, &(sp->u.sval), &xvalue)!=0) ++ if(pv_get_spec_value(msg, sp->u.sval, &xvalue)!=0) + { + LM_CRIT("failed to get PVAR value (%d/%d)\n", sp->opd, sp->ops); + goto error; +@@ -343,9 +343,9 @@ int ops_dbload_avps (struct sip_msg* msg, struct fis_param *sp, + /* is dynamic avp name ? */ + if(dbp->a.type==AVPOPS_VAL_PVAR) + { +- if(pv_has_dname(&(dbp->a.u.sval))) ++ if(pv_has_dname(dbp->a.u.sval)) + { +- if(pv_get_spec_name(msg, &(dbp->a.u.sval.pvp), &xvalue)!=0) ++ if(pv_get_spec_name(msg, &(dbp->a.u.sval->pvp), &xvalue)!=0) + { + LM_CRIT("failed to get value for P2\n"); + goto error; +@@ -394,7 +394,7 @@ int ops_dbload_avps (struct sip_msg* msg, struct fis_param *sp, + memset(&avp_name, 0, sizeof(int_str)); + if(dbp->a.type==AVPOPS_VAL_PVAR) + { +- if(pv_has_dname(&dbp->a.u.sval)) ++ if(pv_has_dname(dbp->a.u.sval)) + { + if(xvalue.flags&PV_TYPE_INT) + { +@@ -404,8 +404,8 @@ int ops_dbload_avps (struct sip_msg* msg, struct fis_param *sp, + avp_type = AVP_NAME_STR; + } + } else { +- avp_name = dbp->a.u.sval.pvp.pvn.u.isname.name; +- avp_type = dbp->a.u.sval.pvp.pvn.u.isname.type; ++ avp_name = dbp->a.u.sval->pvp.pvn.u.isname.name; ++ avp_type = dbp->a.u.sval->pvp.pvn.u.isname.type; + } + } + //if ( dbrow2avp( &res->rows[i], dbp->a.opd, avp_name, sh_flg) < 0 ) +@@ -442,7 +442,7 @@ int ops_dbdelete_avps (struct sip_msg* msg, struct fis_param *sp, + /* get uuid from avp */ + if (sp->opd&AVPOPS_VAL_PVAR) + { +- if(pv_get_spec_value(msg, &(sp->u.sval), &xvalue)!=0) ++ if(pv_get_spec_value(msg, sp->u.sval, &xvalue)!=0) + { + LM_CRIT("failed to get PVAR value (%d/%d)\n", sp->opd, sp->ops); + goto error; +@@ -484,9 +484,9 @@ int ops_dbdelete_avps (struct sip_msg* msg, struct fis_param *sp, + /* is dynamic avp name ? */ + if(dbp->a.type==AVPOPS_VAL_PVAR) + { +- if(pv_has_dname(&dbp->a.u.sval)) ++ if(pv_has_dname(dbp->a.u.sval)) + { +- if(pv_get_spec_name(msg, &(dbp->a.u.sval.pvp), &xvalue)!=0) ++ if(pv_get_spec_name(msg, &(dbp->a.u.sval->pvp), &xvalue)!=0) + { + LM_CRIT("failed to get value for P2\n"); + goto error; +@@ -562,7 +562,7 @@ int ops_dbstore_avps (struct sip_msg* msg, struct fis_param *sp, + /* get uuid from avp */ + if (sp->opd&AVPOPS_VAL_PVAR) + { +- if(pv_get_spec_value(msg, &(sp->u.sval), &xvalue)!=0) ++ if(pv_get_spec_value(msg, sp->u.sval, &xvalue)!=0) + { + LM_CRIT("failed to get PVAR value (%d/%d)\n", sp->opd, sp->ops); + goto error; +@@ -610,9 +610,9 @@ int ops_dbstore_avps (struct sip_msg* msg, struct fis_param *sp, + /* is dynamic avp name ? */ + if(dbp->a.type==AVPOPS_VAL_PVAR) + { +- if(pv_has_dname(&dbp->a.u.sval)) ++ if(pv_has_dname(dbp->a.u.sval)) + { +- if(pv_get_spec_name(msg, &(dbp->a.u.sval.pvp), &xvalue)!=0) ++ if(pv_get_spec_name(msg, &(dbp->a.u.sval->pvp), &xvalue)!=0) + { + LM_CRIT("failed to get value for P2\n"); + goto error; +@@ -647,14 +647,14 @@ int ops_dbstore_avps (struct sip_msg* msg, struct fis_param *sp, + goto error; + } + } else { +- name_type = dbp->a.u.sval.pvp.pvn.u.isname.type; +- avp_name = dbp->a.u.sval.pvp.pvn.u.isname.name; ++ name_type = dbp->a.u.sval->pvp.pvn.u.isname.type; ++ avp_name = dbp->a.u.sval->pvp.pvn.u.isname.name; + } + } + + /* set the script flags */ + if(dbp->a.type==AVPOPS_VAL_PVAR) +- name_type |= dbp->a.u.sval.pvp.pvn.u.isname.type&0xff00; ++ name_type |= dbp->a.u.sval->pvp.pvn.u.isname.type&0xff00; + + /* set uuid/(username and domain) fields */ + +@@ -795,8 +795,8 @@ int ops_delete_avp(struct sip_msg* msg, struct fis_param *ap) + ((ap->opd&AVPOPS_VAL_INT)&&((avp->flags&AVP_NAME_STR))==0) || + ((ap->opd&AVPOPS_VAL_STR)&&(avp->flags&AVP_NAME_STR)) ) ) + continue; +- if((ap->u.sval.pvp.pvn.u.isname.type&AVP_SCRIPT_MASK)!=0 +- && ((ap->u.sval.pvp.pvn.u.isname.type&AVP_SCRIPT_MASK) ++ if((ap->u.sval->pvp.pvn.u.isname.type&AVP_SCRIPT_MASK)!=0 ++ && ((ap->u.sval->pvp.pvn.u.isname.type&AVP_SCRIPT_MASK) + &avp->flags)==0) + continue; + /* remove avp */ +@@ -925,7 +925,7 @@ int ops_pushto_avp (struct sip_msg* msg, struct fis_param* dst, + + avp = NULL; + flags = 0; +- if(src->u.sval.type==PVT_AVP) ++ if(src->u.sval->type==PVT_AVP) + { + /* search for the avp */ + if(avpops_get_aname(msg, src, &avp_name, &name_type)!=0) +@@ -941,7 +941,7 @@ int ops_pushto_avp (struct sip_msg* msg, struct fis_param* dst, + } + flags = avp->flags; + } else { +- if(pv_get_spec_value(msg, &(src->u.sval), &xvalue)!=0) ++ if(pv_get_spec_value(msg, src->u.sval, &xvalue)!=0) + { + LM_ERR("cannot get src value\n"); + goto error; +@@ -1073,7 +1073,7 @@ int ops_check_avp( struct sip_msg* msg, struct fis_param* src, + regex_t *re; + + /* look if the required avp(s) is/are present */ +- if(src->u.sval.type==PVT_AVP) ++ if(src->u.sval->type==PVT_AVP) + { + /* search for the avp */ + if(avpops_get_aname(msg, src, &avp_name1, &name_type1)!=0) +@@ -1091,7 +1091,7 @@ int ops_check_avp( struct sip_msg* msg, struct fis_param* src, + } else { + avp1 = 0; + flags = 0; +- if(pv_get_spec_value(msg, &(src->u.sval), &xvalue)!=0) ++ if(pv_get_spec_value(msg, src->u.sval, &xvalue)!=0) + { + LM_ERR("cannot get src value\n"); + goto error; +@@ -1123,7 +1123,7 @@ cycle1: + { + /* the 2nd operator is variable -> get avp value */ + check_flags = 0; +- if(val->u.sval.type==PVT_AVP) ++ if(val->u.sval->type==PVT_AVP) + { + /* search for the avp */ + if(avpops_get_aname(msg, val, &avp_name2, &name_type2)!=0) +@@ -1140,7 +1140,7 @@ cycle1: + check_flags = avp2->flags; + } else { + avp2 = 0; +- if(pv_get_spec_value(msg, &(val->u.sval), &xvalue)!=0) ++ if(pv_get_spec_value(msg, val->u.sval, &xvalue)!=0) + { + LM_ERR("cannot get dst value\n"); + goto error; +@@ -1538,7 +1538,7 @@ cycle1: + if (val->opd&AVPOPS_VAL_PVAR) + { + /* the 2nd operator is variable -> get value */ +- if(val->u.sval.type==PVT_AVP) ++ if(val->u.sval->type==PVT_AVP) + { + /* search for the avp */ + if(avpops_get_aname(msg, val, &avp_name2, &name_type2)!=0) +@@ -1560,7 +1560,7 @@ cycle1: + } + } else { + avp2 = 0; +- if(pv_get_spec_value(msg, &(val->u.sval), &xvalue)!=0) ++ if(pv_get_spec_value(msg, val->u.sval, &xvalue)!=0) + { + LM_ERR("cannot get dst value\n"); + goto error; +@@ -1680,7 +1680,7 @@ int ops_is_avp_set(struct sip_msg* msg, struct fis_param *ap) + } + + /* get avp index */ +- if(pv_get_spec_index(msg, &ap->u.sval.pvp, &index, &findex)!=0) ++ if(pv_get_spec_index(msg, &ap->u.sval->pvp, &index, &findex)!=0) + { + LM_ERR("failed to get AVP index\n"); + return -1; +diff --git a/modules/avpops/avpops_impl.h b/modules/avpops/avpops_impl.h +index 6e38007..9e55222 100644 +--- a/modules/avpops/avpops_impl.h ++++ b/modules/avpops/avpops_impl.h +@@ -104,7 +104,7 @@ struct fis_param + int opd; /* operand flags */ + int type; + union { +- pv_spec_t sval; /* values int or str */ ++ pv_spec_t *sval; /* values int or str */ + int n; + str s; + } u; +diff --git a/modules/avpops/avpops_parse.c b/modules/avpops/avpops_parse.c +index 47bb984..3a16f18 100644 +--- a/modules/avpops/avpops_parse.c ++++ b/modules/avpops/avpops_parse.c +@@ -69,7 +69,8 @@ struct fis_param *avpops_parse_pvar(char *in) + } + memset( ap, 0, sizeof(struct fis_param)); + s.s = in; s.len = strlen(s.s); +- if(pv_parse_spec(&s, &ap->u.sval)==0) ++ ap->u.sval = pv_cache_get(&s); ++ if(ap->u.sval==NULL) + { + pkg_free(ap); + return NULL; +@@ -87,7 +88,6 @@ int parse_avp_db(char *s, struct db_param *dbp, int allow_scheme) + str tmp; + str s0; + char have_scheme; +- char *p; + char *p0; + unsigned int flags; + +@@ -129,12 +129,12 @@ int parse_avp_db(char *s, struct db_param *dbp, int allow_scheme) + goto error; + } + } +- dbp->a.u.sval.pvp.pvn.u.isname.type |= (flags<<8)&0xff00; ++ dbp->a.u.sval->pvp.pvn.u.isname.type |= (flags<<8)&0xff00; + dbp->a.type = AVPOPS_VAL_NONE; + } else { + s0.s = s; s0.len = strlen(s0.s); +- p = pv_parse_spec(&s0, &dbp->a.u.sval); +- if (p==0 || *p!='\0' || dbp->a.u.sval.type!=PVT_AVP) ++ dbp->a.u.sval = pv_cache_get(&s0); ++ if (dbp->a.u.sval==0 || dbp->a.u.sval->type!=PVT_AVP) + { + LM_ERR("bad param - expected : $avp(name) or int/str value\n"); + return E_UNSPEC; +@@ -147,22 +147,22 @@ int parse_avp_db(char *s, struct db_param *dbp, int allow_scheme) + if (dbp->a.type == AVPOPS_VAL_PVAR) + { + dbp->a.opd = AVPOPS_VAL_PVAR; +- if(pv_has_sname(&dbp->a.u.sval)) ++ if(pv_has_sname(dbp->a.u.sval)) + { + dbp->sa.s=(char*)pkg_malloc( +- dbp->a.u.sval.pvp.pvn.u.isname.name.s.len+1); ++ dbp->a.u.sval->pvp.pvn.u.isname.name.s.len+1); + if (dbp->sa.s==0) + { + LM_ERR("no more pkg mem\n"); + goto error; + } +- memcpy(dbp->sa.s, dbp->a.u.sval.pvp.pvn.u.isname.name.s.s, +- dbp->a.u.sval.pvp.pvn.u.isname.name.s.len); +- dbp->sa.len = dbp->a.u.sval.pvp.pvn.u.isname.name.s.len; ++ memcpy(dbp->sa.s, dbp->a.u.sval->pvp.pvn.u.isname.name.s.s, ++ dbp->a.u.sval->pvp.pvn.u.isname.name.s.len); ++ dbp->sa.len = dbp->a.u.sval->pvp.pvn.u.isname.name.s.len; + dbp->sa.s[dbp->sa.len] = 0; + dbp->a.opd = AVPOPS_VAL_PVAR|AVPOPS_VAL_STR; +- } else if(pv_has_iname(&dbp->a.u.sval)) { +- ul = (unsigned long)dbp->a.u.sval.pvp.pvn.u.isname.name.n; ++ } else if(pv_has_iname(dbp->a.u.sval)) { ++ ul = (unsigned long)dbp->a.u.sval->pvp.pvn.u.isname.name.n; + tmp.s = int2str( ul, &(tmp.len) ); + dbp->sa.s = (char*)pkg_malloc( tmp.len + 1 ); + if (dbp->sa.s==0) +@@ -514,7 +514,7 @@ struct fis_param* parse_check_value(char *s) + LM_ERR("unable to get pseudo-variable\n"); + goto error; + } +- if (vp->u.sval.type==PVT_NULL) ++ if (vp->u.sval->type==PVT_NULL) + { + LM_ERR("bad param; expected : $pseudo-variable or int/str value\n"); + goto error; +@@ -620,7 +620,7 @@ struct fis_param* parse_op_value(char *s) + LM_ERR("unable to get pseudo-variable\n"); + goto error; + } +- if (vp->u.sval.type==PVT_NULL) ++ if (vp->u.sval->type==PVT_NULL) + { + LM_ERR("bad param; expected : $pseudo-variable or int/str value\n"); + goto error; +-- +1.7.10.4 + diff --git a/debian/patches/upstream/avpops-allow-use-of-avps-as-second-parameter-on-re-o.patch b/debian/patches/upstream/avpops-allow-use-of-avps-as-second-parameter-on-re-o.patch new file mode 100644 index 000000000..3ead5b979 --- /dev/null +++ b/debian/patches/upstream/avpops-allow-use-of-avps-as-second-parameter-on-re-o.patch @@ -0,0 +1,104 @@ +From bbecaa597aa4fb3fa08773cd6cd9b8558c7ce3a8 Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Wed, 21 Aug 2013 11:04:08 +0200 +Subject: [PATCH] avpops: allow use of avps as second parameter on re + operation at avp_check function + +--- + modules/avpops/avpops.c | 35 +++++++++++++++-------------------- + modules/avpops/avpops_impl.c | 20 ++++++++++++++++---- + 2 files changed, 31 insertions(+), 24 deletions(-) + +diff --git a/modules/avpops/avpops.c b/modules/avpops/avpops.c +index 4de02a1..674469b 100644 +--- a/modules/avpops/avpops.c ++++ b/modules/avpops/avpops.c +@@ -683,28 +683,23 @@ static int fixup_check_avp(void** param, int param_no) + /* if REGEXP op -> compile the expresion */ + if (ap->ops&AVPOPS_OP_RE) + { +- if ( (ap->opd&AVPOPS_VAL_STR)==0 ) ++ if ( (ap->opd&AVPOPS_VAL_STR)!=0 ) + { +- LM_ERR("regexp operation requires string value\n"); +- return E_UNSPEC; +- } +- re = pkg_malloc(sizeof(regex_t)); +- if (re==0) +- { +- LM_ERR("no more pkg mem\n"); +- return E_OUT_OF_MEM; +- } +- LM_DBG("compiling regexp <%.*s>\n", ap->u.s.len, ap->u.s.s); +- if (regcomp(re, ap->u.s.s, +- REG_EXTENDED|REG_ICASE|REG_NEWLINE)) +- { +- pkg_free(re); +- LM_ERR("bad re <%.*s>\n", ap->u.s.len, ap->u.s.s); +- return E_BAD_RE; ++ re = (regex_t*) pkg_malloc(sizeof(regex_t)); ++ if (re==0) ++ { ++ LM_ERR("no more pkg mem\n"); ++ return E_OUT_OF_MEM; ++ } ++ LM_DBG("compiling regexp <%.*s>\n", ap->u.s.len, ap->u.s.s); ++ if (regcomp(re, ap->u.s.s,REG_EXTENDED|REG_ICASE|REG_NEWLINE)) ++ { ++ pkg_free(re); ++ LM_ERR("bad re <%.*s>\n", ap->u.s.len, ap->u.s.s); ++ return E_BAD_RE; ++ } ++ ap->u.s.s = (char*)re; + } +- /* free the string and link the regexp */ +- // pkg_free(ap->sval.p.s); +- ap->u.s.s = (char*)re; + } else if (ap->ops&AVPOPS_OP_FM) { + if ( !( ap->opd&AVPOPS_VAL_PVAR || + (!(ap->opd&AVPOPS_VAL_PVAR) && ap->opd&AVPOPS_VAL_STR) ) ) +diff --git a/modules/avpops/avpops_impl.c b/modules/avpops/avpops_impl.c +index 81a8053..7dcd371 100644 +--- a/modules/avpops/avpops_impl.c ++++ b/modules/avpops/avpops_impl.c +@@ -1069,6 +1069,8 @@ int ops_check_avp( struct sip_msg* msg, struct fis_param* src, + int flags; + pv_value_t xvalue; + char backup; ++ regex_t re_temp; ++ regex_t *re; + + /* look if the required avp(s) is/are present */ + if(src->u.sval.type==PVT_AVP) +@@ -1228,14 +1230,24 @@ cycle2: + if (strncasecmp(avp_val.s.s,check_val.s.s,n)>=0) + return 1; + } else if (val->ops&AVPOPS_OP_RE) { ++ if (val->opd&AVPOPS_VAL_PVAR) { ++ LM_DBG("compiling regexp <%.*s>\n", check_val.s.len, check_val.s.s); ++ if (regcomp(&re_temp, check_val.s.s,REG_EXTENDED|REG_ICASE|REG_NEWLINE)) ++ { ++ LM_ERR("bad re <%.*s>\n", check_val.s.len, check_val.s.s); ++ goto next; ++ } ++ re = &re_temp; ++ } ++ else re = (regex_t*)check_val.s.s; + backup = avp_val.s.s[avp_val.s.len]; + avp_val.s.s[avp_val.s.len] = '\0'; +- if (regexec((regex_t*)check_val.s.s, avp_val.s.s, 1, &pmatch,0)==0) +- { +- avp_val.s.s[avp_val.s.len] = backup; +- return 1; ++ rt=regexec(re, avp_val.s.s, 1, &pmatch,0); ++ if (val->opd&AVPOPS_VAL_PVAR) { ++ regfree(re); + } + avp_val.s.s[avp_val.s.len] = backup; ++ if (rt==0) return 1; + } else if (val->ops&AVPOPS_OP_FM){ + backup = avp_val.s.s[avp_val.s.len]; + avp_val.s.s[avp_val.s.len] = '\0'; +-- +1.7.10.4 + diff --git a/debian/patches/upstream/avpops-allow-xavp-semantics-on-second-parameter.patch b/debian/patches/upstream/avpops-allow-xavp-semantics-on-second-parameter.patch new file mode 100644 index 000000000..f3e46791f --- /dev/null +++ b/debian/patches/upstream/avpops-allow-xavp-semantics-on-second-parameter.patch @@ -0,0 +1,163 @@ +From 0968ce561b3bb8ea2ad2c7c53c03091e8518a6fe Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Fri, 20 Sep 2013 11:08:52 +0200 +Subject: [PATCH] avpops: allow xavp semantics on second parameter + +--- + modules/avpops/avpops_impl.c | 112 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 112 insertions(+) + +diff --git a/modules/avpops/avpops_impl.c b/modules/avpops/avpops_impl.c +index 65a5239..4fa2a53 100644 +--- a/modules/avpops/avpops_impl.c ++++ b/modules/avpops/avpops_impl.c +@@ -45,6 +45,7 @@ + #include "../../parser/parse_from.h" + #include "../../parser/parse_uri.h" + #include "../../mem/mem.h" ++#include "../../xavp.h" + #include "avpops_impl.h" + #include "avpops_db.h" + +@@ -1051,6 +1052,86 @@ error: + return -1; + } + ++int get_xavp(struct sip_msg *msg, pv_xavp_name_t *xname, ++ sr_xavp_t **avp, int *flag) ++{ ++ int idxf = 0; ++ int idx = 0; ++ int count; ++ ++ if(xname==NULL) ++ { ++ LM_ERR("bad parameters\n"); ++ return -1; ++ } ++ ++ if(xname->index.type==PVT_EXTRA) ++ { ++ /* get the index */ ++ if(pv_get_spec_index(msg, &xname->index.pvp, &idx, &idxf)!=0) ++ { ++ LM_ERR("invalid index\n"); ++ return -1; ++ } ++ LM_DBG("key1 idx:%d idxf:%d\n", idx, idxf); ++ if(idxf==PV_IDX_ALL) ++ LM_ERR("idx:* at first key not implemented. Using idx:0\n"); ++ } ++ /* fix the index */ ++ if(idx<0) ++ { ++ count = xavp_count(&xname->name, NULL); ++ idx = count + idx; ++ } ++ *avp = xavp_get_by_index(&xname->name, idx, NULL); ++ if(*avp==NULL) ++ return -1; ++ if(xname->next==NULL) ++ return 0; ++ ++ idx = 0; ++ idxf = 0; ++ if(xname->next->index.type==PVT_EXTRA) ++ { ++ /* get the index */ ++ if(pv_get_spec_index(msg, &xname->next->index.pvp, &idx, &idxf)!=0) ++ { ++ LM_ERR("invalid index\n"); ++ return -1; ++ } ++ LM_DBG("key2 idx:%d idxf:%d\n", idx, idxf); ++ *flag=idxf; ++ } ++ /* fix the index */ ++ if(idx<0) ++ { ++ count = xavp_count(&xname->next->name, &(*avp)->val.v.xavp); ++ idx = count + idx; ++ } ++ *avp = xavp_get_by_index(&xname->next->name, idx, &(*avp)->val.v.xavp); ++ if(*avp==NULL) ++ return -1; ++ return 1; ++} ++ ++int check_xavp_param(struct sip_msg* msg, pv_spec_p spec, sr_xavp_t **xavp, ++ int *flag) ++{ ++ int res; ++ pv_xavp_name_t *xname = (pv_xavp_name_t*)spec->pvp.pvn.u.dname; ++ res = get_xavp(msg, xname, xavp, flag); ++ if(res<=0) ++ { ++ if(res==0) ++ LM_ERR("xavp has to have key2\n"); ++ LM_DBG("no dst xavp found\n"); ++ goto error; ++ } ++ return 1; ++error: ++ return -1; ++} ++ + int ops_check_avp( struct sip_msg* msg, struct fis_param* src, + struct fis_param* val) + { +@@ -1071,6 +1152,8 @@ int ops_check_avp( struct sip_msg* msg, struct fis_param* src, + char backup; + regex_t re_temp; + regex_t *re; ++ sr_xavp_t *xavp2 = NULL; ++ int xavp_flags=0; + + /* look if the required avp(s) is/are present */ + if(src->u.sval->type==PVT_AVP) +@@ -1138,6 +1221,30 @@ cycle1: + goto error; + } + check_flags = avp2->flags; ++ } ++ else if(val->u.sval->type==PVT_XAVP) ++ { ++ avp2 = 0; ++ if(xavp2==NULL) ++ { ++ if(check_xavp_param(msg, val->u.sval, &xavp2, &xavp_flags)<0) ++ { ++ goto error; ++ } ++ } ++ if(xavp2->val.type!=SR_XTYPE_INT&&xavp2->val.type!=SR_XTYPE_STR) ++ { ++ LM_ERR("cannot dst value is not INT or STR\n"); ++ goto error; ++ } ++ check_flags = 0; ++ if(xavp2->val.type==SR_XTYPE_INT) ++ { ++ check_val.n = xavp2->val.v.i; ++ } else { ++ check_flags = AVP_VAL_STR; ++ check_val.s = xavp2->val.v.s; ++ } + } else { + avp2 = 0; + if(pv_get_spec_value(msg, val->u.sval, &xvalue)!=0) +@@ -1308,6 +1415,11 @@ next: + { + check_flags = avp2->flags; + goto cycle2; ++ } else if ((xavp2!=NULL) && (xavp_flags&PV_IDX_ALL) ++ && (xavp2=xavp_get_next(xavp2))!=NULL) ++ { ++ LM_DBG("xavp->next\n"); ++ goto cycle1; + /* cycle for the first value -> next avp */ + } else { + if(avp1 && val->ops&AVPOPS_FLAG_ALL) +-- +1.7.10.4 + diff --git a/debian/patches/upstream/pv-Move-pv_xavp_name_t-declaration-to-core-pvar.h.patch b/debian/patches/upstream/pv-Move-pv_xavp_name_t-declaration-to-core-pvar.h.patch new file mode 100644 index 000000000..088650f55 --- /dev/null +++ b/debian/patches/upstream/pv-Move-pv_xavp_name_t-declaration-to-core-pvar.h.patch @@ -0,0 +1,50 @@ +From df472fa9bdaa1a796dd220c99a64b1539c8854b5 Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Fri, 20 Sep 2013 11:07:14 +0200 +Subject: [PATCH] pv: Move pv_xavp_name_t declaration to core pvar.h + +--- + modules/pv/pv_xavp.h | 6 ------ + pvar.h | 10 ++++++++++ + 2 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/modules/pv/pv_xavp.h b/modules/pv/pv_xavp.h +index 2e12870..4851b3f 100644 +--- a/modules/pv/pv_xavp.h ++++ b/modules/pv/pv_xavp.h +@@ -23,12 +23,6 @@ + + #include "../../pvar.h" + +-typedef struct _pv_xavp_name { +- str name; +- pv_spec_t index; +- struct _pv_xavp_name *next; +-} pv_xavp_name_t; +- + int pv_get_xavp(struct sip_msg *msg, pv_param_t *param, + pv_value_t *res); + int pv_set_xavp(struct sip_msg* msg, pv_param_t *param, +diff --git a/pvar.h b/pvar.h +index c35ae94..4d69a43 100644 +--- a/pvar.h ++++ b/pvar.h +@@ -288,5 +288,15 @@ void tr_param_free(tr_param_t *tp); + + int register_trans_mod(char *mod_name, tr_export_t *items); + ++ ++/** ++ * XAVP ++ */ ++typedef struct _pv_xavp_name { ++ str name; ++ pv_spec_t index; ++ struct _pv_xavp_name *next; ++} pv_xavp_name_t; ++ + #endif + +-- +1.7.10.4 +