Module: sip-router Branch: andrei/rve_f_params Commit: d756b6bfbaceddb6f05d038e93f49c062e1baa90 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d756b6bf...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Thu Aug 5 22:55:18 2010 +0200
core: k style fixup_free fixes
- always restore the original parameter pointer value in fixup_free function. - fixup_uint_*() re-written (don't use fparam and hence avoid a pkg_malloc()). - remove fixup_free_uint_*(): since the fixup_uint_*() functions replace the original string pointer directly with an integer, it's never possible to restore the original value => it's not possible to have a proper fixup_free_uint_*(). - fixup_regexp_null() and fixup_free_regexp_null() fixed & re-written. fixup_regexp_null() now uses a hack to save the original pointer so that fixup_free_regexp_null() can restore it (now fixup_free_regexp_null() works). - fixup_pvar_*() and fixup_free_pvar_*() fixed & re-written (similar with fixup_regexp_null()). - fixup_igp_pvar(), fixup_igp_pvar_pvar(), fixup_free_igp_pvar() and fixup_free_igp_pvar_pvar() fixed & re-written (similar with fixup_regexp_null()). - added missing fixup_free_* declarations.
---
mod_fix.c | 292 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- mod_fix.h | 5 + 2 files changed, 277 insertions(+), 20 deletions(-)
diff --git a/mod_fix.c b/mod_fix.c index 69974b0..0f4db9c 100644 --- a/mod_fix.c +++ b/mod_fix.c @@ -51,11 +51,8 @@ int fixup_regexpNL_none(void** param, int param_no); /* textops */ { \ if ((param_no > (maxp)) || (param_no < (minp))) \ return E_UNSPEC; \ - if (*param){ \ - fparam_free_contents((fparam_t*)*param); \ - pkg_free(*param); \ - *param=0; \ - } \ + if (*param) \ + fparam_free_restore(param); \ return 0; \ }
@@ -150,7 +147,7 @@ int fixup_regexpNL_none(void** param, int param_no); /* textops */ int ret; \ if (param && *param){ \ p=(param_no>(no1))? *param - (long)&((fparam_t*)0)->v : *param;\ - if ((ret=fixup_free_fpt_##suffix(&p, param_no))==0) *param=0; \ + if ((ret=fixup_free_fpt_##suffix(&p, param_no))==0) *param=p; \ return ret; \ } \ return 0; \ @@ -169,24 +166,286 @@ int fixup_regexpNL_none(void** param, int param_no); /* textops */
FIXUP_F1T(str_null, 1, 1, FPARAM_STR) FIXUP_F1T(str_str, 1, 2, FPARAM_STR) +FIXUP_F1T(str_all, 1, 100, FPARAM_STR)
-/* TODO: int can be converted in place, no need for pkg_malloc'ed fparam_t*/ +/* + no free fixups possible for unit_* + (they overwrite the pointer with the converted number => the original + value cannot be recovered) FIXUP_F1T(uint_null, 1, 1, FPARAM_INT) FIXUP_F1T(uint_uint, 1, 2, FPARAM_INT) +*/ + + + +int fixup_uint_uint(void** param, int param_no) +{ + str s; + unsigned int num; + + s.s = *param; + s.len = strlen(s.s); + if (likely(str2int(&s, &num) == 0)) { + *param = (void*)(long)num; + } else + /* not a number */ + return E_UNSPEC; + return 0; +} + + + +int fixup_uint_null(void** param, int param_no) +{ + if (param_no == 1) + return fixup_uint_uint(param, param_no); + return E_UNSPEC; +} +
+/* fixup_regexp_null() has to be written "by hand", since + it needs to save the original pointer (the fixup users expects + a pointer to the regex in *param and hence the original value + needed on free cannot be recovered directly). FIXUP_F1T(regexp_null, 1, 1, FPARAM_REGEX) +*/
+struct regex_fixup { + regex_t regex; /* compiled regex */ + void* orig; /* original pointer */ +}; + +int fixup_regexp_null(void** param, int param_no) +{ + struct regex_fixup* re; + + if (param_no != 1) + return E_UNSPEC; + if ((re=pkg_malloc(sizeof(*re))) ==0) { + ERR("No memory left\n"); + goto error; + } + if (regcomp(&re->regex, *param, + REG_EXTENDED|REG_ICASE|REG_NEWLINE)) + goto error; + re->orig = *param; + *param = re; + return 0; +error: + if (re) + pkg_free(re); + return E_UNSPEC; +} + + +int fixup_free_regexp_null(void** param, int param_no) +{ + struct regex_fixup* re; + + if (param_no != 1) + return E_UNSPEC; + if (*param) { + re = *param; + *param = re->orig; + regfree(&re->regex); + pkg_free(re); + } + return 0; +} + +/* fixup_pvar_*() has to be written "by hand", since + it needs to save the original pointer (the fixup users expects + a pointer to the pv_spec_t in *param and hence the original value + needed on free cannot be recovered directly). FIXUP_F1T(pvar_null, 1, 1, FPARAM_PVS) FIXUP_F1T(pvar_pvar, 1, 2, FPARAM_PVS) +*/ + +struct pvs_fixup { + pv_spec_t pvs; /* parsed pv spec */ + void* orig; /* original pointer */ +}; + +int fixup_pvar_all(void** param, int param_no) +{ + struct pvs_fixup* pvs_f; + str name; + + pvs_f = 0; + name.s = *param; + name.len = strlen(name.s); + trim(&name); + if (name.len == 0 || name.s[0] != '$') + /* not a pvs id */ + goto error; + if ((pvs_f=pkg_malloc(sizeof(*pvs_f))) == 0) { + ERR("No memory left\n"); + goto error; + } + if (pv_parse_spec2(&name, &pvs_f->pvs, 1) == 0) + /* not a valid pvs identifier */ + goto error; + pvs_f->orig = *param; + *param = pvs_f; + return 0; +error: + if (pvs_f) + pkg_free(pvs_f); + return E_UNSPEC; +} + + + +int fixup_free_pvar_all(void** param, int param_no) +{ + struct pvs_fixup* pvs_f; + + if (*param) { + pvs_f = *param; + *param = pvs_f->orig; + pv_spec_free_contents(&pvs_f->pvs); + pkg_free(pvs_f); + } + return 0; +} + + + +int fixup_pvar_pvar(void** param, int param_no) +{ + if (param_no > 2) + return E_UNSPEC; + return fixup_free_pvar_all(param, param_no); +} + + + +int fixup_free_pvar_pvar(void** param, int param_no) +{ + if (param_no > 2) + return E_UNSPEC; + return fixup_free_pvar_all(param, param_no); +} + + + +int fixup_pvar_null(void** param, int param_no) +{ + if (param_no != 1) + return E_UNSPEC; + return fixup_pvar_all(param, param_no); +}
+ + +int fixup_free_pvar_null(void** param, int param_no) +{ + if (param_no != 1) + return E_UNSPEC; + return fixup_free_pvar_all(param, param_no); +} + +/* must be written "by hand", see above (fixup_pvar_pvar). FIXUP_F2T(pvar_str, 1, 2, 1, FPARAM_PVS, FPARAM_STR) FIXUP_F2T(pvar_str_str, 1, 3, 1, FPARAM_PVS, FPARAM_STR) +*/ + +int fixup_pvar_str(void** param, int param_no) +{ + if (param_no == 1) + return fixup_pvar_all(param, param_no); + else if (param_no == 2) + return fixup_str_str(param, param_no); + return E_UNSPEC; +} + + + +int fixup_free_pvar_str(void** param, int param_no) +{ + if (param_no == 1) + return fixup_free_pvar_all(param, param_no); + else if (param_no == 2) + return fixup_free_str_str(param, param_no); + return E_UNSPEC; +} + + + +int fixup_pvar_str_str(void** param, int param_no) +{ + if (param_no == 1) + return fixup_pvar_all(param, param_no); + else if (param_no == 2 || param_no == 3) + return fixup_str_all(param, param_no); + return E_UNSPEC; +} + + + +int fixup_free_pvar_str_str(void** param, int param_no) +{ + if (param_no == 1) + return fixup_free_pvar_all(param, param_no); + else if (param_no == 2 || param_no == 3) + return fixup_free_str_all(param, param_no); + return E_UNSPEC; +} + +
FIXUP_F2FP(igp_null, 1, 1, 1, FPARAM_INT|FPARAM_PVS, 0) FIXUP_F2FP(igp_igp, 1, 2, 2, FPARAM_INT|FPARAM_PVS, 0) -FIXUP_F2FP(igp_pvar, 1, 2, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
+/* must be declared by hand, because of the pvar special handling + (see above) +FIXUP_F2FP(igp_pvar, 1, 2, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS) FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS) +*/ + +int fixup_igp_pvar(void** param, int param_no) +{ + if (param_no == 1) + return fixup_igp_null(param, param_no); + else if (param_no == 2) + return fixup_pvar_all(param, param_no); + return E_UNSPEC; +} + + + +int fixup_free_igp_pvar(void** param, int param_no) +{ + if (param_no == 1) + return fixup_free_igp_null(param, param_no); + else if (param_no == 2) + return fixup_free_pvar_all(param, param_no); + return E_UNSPEC; +} + + + +int fixup_igp_pvar_pvar(void** param, int param_no) +{ + if (param_no == 1) + return fixup_igp_null(param, param_no); + else if (param_no == 2 || param_no == 3) + return fixup_pvar_all(param, param_no); + return E_UNSPEC; +} + + + +int fixup_free_igp_pvar_pvar(void** param, int param_no) +{ + if (param_no == 1) + return fixup_free_igp_null(param, param_no); + else if (param_no == 2 || param_no == 3) + return fixup_free_pvar_all(param, param_no); + return E_UNSPEC; +} + +
/** macro for declaring a spve fixup and the corresponding free_fixup * for a function expecting first no1 params as fparam converted spve @@ -203,21 +462,16 @@ FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS) int fixup_##suffix (void** param, int param_no) \ { \ int ret; \ - char * bkp; \ fparam_t* fp; \ if (param_no<=(no1)){ \ if ((ret=fix_param_types(FPARAM_PVE, param))<0){ \ - ERR("Cannot convert function parameter %d to" #type2 "\n", \ + ERR("Cannot convert function parameter %d to spve \n", \ param_no);\ return E_UNSPEC; \ } else{ \ fp=(fparam_t*)*param; \ if ((ret==0) && (fp->v.pve->spec.getf==0)){ \ - bkp=fp->orig; \ - fp->orig=0; /* make sure orig string is not freed */ \ - fparam_free_contents(fp); \ - pkg_free(fp); \ - *param=bkp; \ + fparam_free_restore(param); \ return fix_param_types(FPARAM_STR, param); \ } else if (ret==1) \ return fix_param_types(FPARAM_STR, param); \ @@ -229,11 +483,9 @@ FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS) int fixup_free_##suffix (void** param, int param_no) \ { \ if (param && *param){ \ - if (param_no<=(no1)){ \ - fparam_free_contents((fparam_t*)*param); \ - pkg_free(*param); \ - *param=0; \ - } else \ + if (param_no<=(no1)) \ + fparam_free_restore(param); \ + else \ return fixup_free_spvet_##suffix(param, param_no); \ } \ return 0; \ diff --git a/mod_fix.h b/mod_fix.h index 37bccb6..bd5d8a9 100644 --- a/mod_fix.h +++ b/mod_fix.h @@ -106,7 +106,9 @@ int fixup_pvar_str_str(void** param, int param_no); int fixup_free_pvar_str_str(void** param, int param_no);
int fixup_igp_igp(void** param, int param_no); +int fixup_free_igp_igp(void** param, int param_no); int fixup_igp_null(void** param, int param_no); +int fixup_free_igp_null(void** param, int param_no); int fixup_get_ivalue(struct sip_msg* msg, gparam_p gp, int *val);
int fixup_igp_pvar(void** param, int param_no); @@ -116,8 +118,11 @@ int fixup_igp_pvar_pvar(void** param, int param_no); int fixup_free_igp_pvar_pvar(void** param, int param_no);
int fixup_spve_spve(void** param, int param_no); +int fixup_free_spve_spve(void** param, int param_no); int fixup_spve_null(void** param, int param_no); +int fixup_free_spve_null(void** param, int param_no); int fixup_spve_uint(void** param, int param_no); int fixup_spve_str(void** param, int param_no); +int fixup_free_spve_str(void** param, int param_no);
#endif