core: k style fixup_free fixes
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Thu, 5 Aug 2010 20:55:18 +0000 (22:55 +0200)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Thu, 5 Aug 2010 20:55:18 +0000 (22:55 +0200)
- 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
mod_fix.h

index 69974b0..0f4db9c 100644 (file)
--- 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; \
index 37bccb6..bd5d8a9 100644 (file)
--- 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