Browse code

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.

Andrei Pelinescu-Onciul authored on 04/08/2010 13:51:46
Showing 3 changed files
... ...
@@ -168,7 +168,7 @@ struct onsend_info* p_onsend=0; /* onsend route send info */
168 168
 					MODF_RVE_PARAM_FREE(src, dst); \
169 169
 					goto error; \
170 170
 				} \
171
-				(dst)[i+2].type = STRING_ST; \
171
+				(dst)[i+2].type = STRING_RVE_ST; \
172 172
 				(dst)[i+2].u.string = s.s; \
173 173
 				(dst)[i+2].u.str.len = s.len; \
174 174
 				rval_destroy(rv); \
... ...
@@ -127,7 +127,8 @@ enum _operand_subtype{
127 127
 		LVAL_ST,  RVE_ST,
128 128
 		RETCODE_ST, CASE_ST,
129 129
 		BLOCK_ST, JUMPTABLE_ST, CONDTABLE_ST, MATCH_CONDTABLE_ST,
130
-		FPARAM_DYN_ST /* temporary only */
130
+		STRING_RVE_ST /* RVE converted to a string (fparam hack) */,
131
+		FPARAM_DYN_ST /* temporary only (fparam hack) */
131 132
 };
132 133
 
133 134
 typedef enum _expr_l_type expr_l_type;
... ...
@@ -935,6 +935,30 @@ int fixup_get_param_count(void **cur_param, int cur_param_no)
935 935
 }
936 936
 
937 937
 
938
+
939
+/** get a pointer to a parameter internal type.
940
+ * @param param
941
+ * @return pointer to the parameter internal type.
942
+ */
943
+action_param_type* fixup_get_param_ptype(void** param)
944
+{
945
+	action_u_t* a;
946
+	a = (void*)((char*)param - (char*)&(((action_u_t*)(0))->u.string));
947
+	return &a->type;
948
+}
949
+
950
+
951
+/** get a parameter internal type.
952
+ * @see fixup_get_param_ptype().
953
+ * @return paramter internal type.
954
+ */
955
+action_param_type fixup_get_param_type(void** param)
956
+{
957
+	return *fixup_get_param_ptype(param);
958
+}
959
+
960
+
961
+
938 962
 /* fixes flag params (resolves possible named flags)
939 963
  * use PARAM_USE_FUNC|PARAM_STRING as a param. type and create
940 964
  * a wrapper function that does just:
... ...
@@ -1216,6 +1240,13 @@ int fix_param_types(int types, void** param)
1216 1240
 	int ret;
1217 1241
 	int t;
1218 1242
 	
1243
+	if (fixup_get_param_type(param) == STRING_RVE_ST &&
1244
+			(types & (FPARAM_INT|FPARAM_STR|FPARAM_STRING))) {
1245
+		/* if called with a RVE already converted to string =>
1246
+		   don't try AVP, PVAR or SELECT (to avoid double
1247
+		   deref., e.g.: $foo="$bar"; f($foo) ) */
1248
+		types &= ~ (FPARAM_AVP|FPARAM_PVS|FPARAM_SELECT|FPARAM_PVE);
1249
+	}
1219 1250
 	for (t=types & ~(types-1); types; types&=(types-1), t=types & ~(types-1)){
1220 1251
 		if ((ret=fix_param(t, param))<=0) return ret;
1221 1252
 	}
... ...
@@ -1236,10 +1267,15 @@ int fix_param_types(int types, void** param)
1236 1267
 int fixup_var_str_12(void** param, int param_no)
1237 1268
 {
1238 1269
 	int ret;
1239
-	if ((sr_cfg_compat!=SR_COMPAT_SER) &&
1240
-		((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret;
1241
-	if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret;
1242
-	if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret;
1270
+	if (fixup_get_param_type(param) != STRING_RVE_ST) {
1271
+		/* if called with a RVE already converted to string =>
1272
+		   don't try AVP, PVAR or SELECT (to avoid double
1273
+		   deref., e.g.: $foo="$bar"; f($foo) ) */
1274
+		if ((sr_cfg_compat!=SR_COMPAT_SER) &&
1275
+			((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret;
1276
+		if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret;
1277
+		if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret;
1278
+	}
1243 1279
 	if ((ret = fix_param(FPARAM_STR, param)) <= 0) return ret;
1244 1280
 	ERR("Error while fixing parameter, AVP, SELECT, and str conversions"
1245 1281
 			" failed\n");
... ...
@@ -1273,10 +1309,15 @@ int fixup_var_str_2(void** param, int param_no)
1273 1309
 int fixup_var_int_12(void** param, int param_no)
1274 1310
 {
1275 1311
 	int ret;
1276
-	if ((sr_cfg_compat!=SR_COMPAT_SER) &&
1277
-		((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret;
1278
-	if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret;
1279
-	if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret;
1312
+	if (fixup_get_param_type(param) != STRING_RVE_ST) {
1313
+		/* if called with a RVE already converted to string =>
1314
+		   don't try AVP, PVAR or SELECT (to avoid double
1315
+		   deref., e.g.: $foo="$bar"; f($foo) ) */
1316
+		if ((sr_cfg_compat!=SR_COMPAT_SER) &&
1317
+			((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret;
1318
+		if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret;
1319
+		if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret;
1320
+	}
1280 1321
 	if ((ret = fix_param(FPARAM_INT, param)) <= 0) return ret;
1281 1322
 	ERR("Error while fixing parameter, AVP, SELECT, and int conversions"
1282 1323
 			" failed\n");