[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