[sr-dev] git:andrei/rve_f_params: core: k style fixup_free fixes
Andrei Pelinescu-Onciul
andrei at iptel.org
Thu Aug 5 23:07:01 CEST 2010
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=d756b6bfbaceddb6f05d038e93f49c062e1baa90
Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at 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
More information about the sr-dev
mailing list