Module: sip-router Branch: andrei/rve_f_params Commit: 356571397bc86b1d85c588f1a3bfda6b136fbac7 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=35657139...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Wed Aug 4 15:51:46 2010 +0200
core: fix auto-deref. for vars in fparam fixups
When an expression was fixed-up at runtime by the core and the module had fparam-type fixup, the fparam fixup re-evaluated the result, e.g.: $bar=test; $foo="$bar"; f($foo) => "test" instead of "$bar".
Now all the RVE-enabled fparam fixups will avoid this case.
---
action.c | 2 +- route_struct.h | 3 +- sr_module.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 52 insertions(+), 10 deletions(-)
diff --git a/action.c b/action.c index e8a80e5..9c643fb 100644 --- a/action.c +++ b/action.c @@ -168,7 +168,7 @@ struct onsend_info* p_onsend=0; /* onsend route send info */ MODF_RVE_PARAM_FREE(src, dst); \ goto error; \ } \ - (dst)[i+2].type = STRING_ST; \ + (dst)[i+2].type = STRING_RVE_ST; \ (dst)[i+2].u.string = s.s; \ (dst)[i+2].u.str.len = s.len; \ rval_destroy(rv); \ diff --git a/route_struct.h b/route_struct.h index 9c7b40b..178ac77 100644 --- a/route_struct.h +++ b/route_struct.h @@ -127,7 +127,8 @@ enum _operand_subtype{ LVAL_ST, RVE_ST, RETCODE_ST, CASE_ST, BLOCK_ST, JUMPTABLE_ST, CONDTABLE_ST, MATCH_CONDTABLE_ST, - FPARAM_DYN_ST /* temporary only */ + STRING_RVE_ST /* RVE converted to a string (fparam hack) */, + FPARAM_DYN_ST /* temporary only (fparam hack) */ };
typedef enum _expr_l_type expr_l_type; diff --git a/sr_module.c b/sr_module.c index 5089f5f..b729102 100644 --- a/sr_module.c +++ b/sr_module.c @@ -935,6 +935,30 @@ int fixup_get_param_count(void **cur_param, int cur_param_no) }
+ +/** get a pointer to a parameter internal type. + * @param param + * @return pointer to the parameter internal type. + */ +action_param_type* fixup_get_param_ptype(void** param) +{ + action_u_t* a; + a = (void*)((char*)param - (char*)&(((action_u_t*)(0))->u.string)); + return &a->type; +} + + +/** get a parameter internal type. + * @see fixup_get_param_ptype(). + * @return paramter internal type. + */ +action_param_type fixup_get_param_type(void** param) +{ + return *fixup_get_param_ptype(param); +} + + + /* fixes flag params (resolves possible named flags) * use PARAM_USE_FUNC|PARAM_STRING as a param. type and create * a wrapper function that does just: @@ -1216,6 +1240,13 @@ int fix_param_types(int types, void** param) int ret; int t; + if (fixup_get_param_type(param) == STRING_RVE_ST && + (types & (FPARAM_INT|FPARAM_STR|FPARAM_STRING))) { + /* if called with a RVE already converted to string => + don't try AVP, PVAR or SELECT (to avoid double + deref., e.g.: $foo="$bar"; f($foo) ) */ + types &= ~ (FPARAM_AVP|FPARAM_PVS|FPARAM_SELECT|FPARAM_PVE); + } for (t=types & ~(types-1); types; types&=(types-1), t=types & ~(types-1)){ if ((ret=fix_param(t, param))<=0) return ret; } @@ -1236,10 +1267,15 @@ int fix_param_types(int types, void** param) int fixup_var_str_12(void** param, int param_no) { int ret; - if ((sr_cfg_compat!=SR_COMPAT_SER) && - ((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret; - if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret; - if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret; + if (fixup_get_param_type(param) != STRING_RVE_ST) { + /* if called with a RVE already converted to string => + don't try AVP, PVAR or SELECT (to avoid double + deref., e.g.: $foo="$bar"; f($foo) ) */ + if ((sr_cfg_compat!=SR_COMPAT_SER) && + ((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret; + if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret; + if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret; + } if ((ret = fix_param(FPARAM_STR, param)) <= 0) return ret; ERR("Error while fixing parameter, AVP, SELECT, and str conversions" " failed\n"); @@ -1273,10 +1309,15 @@ int fixup_var_str_2(void** param, int param_no) int fixup_var_int_12(void** param, int param_no) { int ret; - if ((sr_cfg_compat!=SR_COMPAT_SER) && - ((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret; - if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret; - if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret; + if (fixup_get_param_type(param) != STRING_RVE_ST) { + /* if called with a RVE already converted to string => + don't try AVP, PVAR or SELECT (to avoid double + deref., e.g.: $foo="$bar"; f($foo) ) */ + if ((sr_cfg_compat!=SR_COMPAT_SER) && + ((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret; + if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret; + if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret; + } if ((ret = fix_param(FPARAM_INT, param)) <= 0) return ret; ERR("Error while fixing parameter, AVP, SELECT, and int conversions" " failed\n");