Browse code

core: rval - don't use static buffer for int conversions

- don't use static buffers for string conversions
(rval_get_tmp_str())
- extended rval_cache with enough space to store an int converted
to string
- switched to signed ints (until now all ints where treated as
unsigned)

Andrei Pelinescu-Onciul authored on 17/03/2010 19:09:29
Showing 2 changed files
... ...
@@ -1062,12 +1062,14 @@ error:
1062 1062
   * if rv == undefined select, avp or pvar, return "".
1063 1063
   * if an error occurs while evaluating a select, avp or pvar, behave as
1064 1064
   * for the undefined case (and return success).
1065
-  * The result points either to a temporary string or inside
1066
-  * new_cache. new_cache must be non zero, initialized previously,
1067
-  * and it _must_ be rval_cache_clean(...)'ed when done.
1068
-  * WARNING: it's not intended for general use, it might return a pointer
1069
-  * to a static buffer (int2str) so use the result a.s.a.p, make a copy.
1070
-  * or use rval_get_str() instead.
1065
+  * The result points either inside the passed rv, inside
1066
+  * new_cache or inside an avp. new_cache must be non zero,
1067
+  * initialized previously and it _must_ be rval_cache_clean(...)'ed when
1068
+  * done.
1069
+  * WARNING: it's not intended for general use. It might return a pointer
1070
+  * inside rv so the result _must_ be treated as read-only. rv and new_cache
1071
+  * must not be released/freed until the result is no longer needed.
1072
+  * For general use see  rval_get_str().
1071 1073
   * @param h - script context handle
1072 1074
   * @param msg - sip msg
1073 1075
   * @param tmpv - str return value (pointer to a str struct that will be
... ...
@@ -1089,7 +1091,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
1089 1091
 	
1090 1092
 	switch(rv->type){
1091 1093
 		case RV_INT:
1092
-			tmpv->s=int2str(rv->v.l, &tmpv->len);
1094
+			tmpv->s=sint2strbuf(rv->v.l, tmp_cache->i2s,
1095
+								sizeof(tmp_cache->i2s), &tmpv->len);
1096
+			tmp_cache->cache_type = RV_CACHE_INT2STR;
1093 1097
 			break;
1094 1098
 		case RV_STR:
1095 1099
 			*tmpv=rv->v.s;
... ...
@@ -1099,16 +1103,22 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
1099 1103
 				i=(run_actions(h, rv->v.action, msg)>0);
1100 1104
 			else
1101 1105
 				i=0;
1102
-			tmpv->s=int2str(i, &tmpv->len);
1106
+			tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1107
+								sizeof(tmp_cache->i2s), &tmpv->len);
1108
+			tmp_cache->cache_type = RV_CACHE_INT2STR;
1103 1109
 			break;
1104 1110
 		case RV_BEXPR:
1105 1111
 			i=eval_expr(h, rv->v.bexpr, msg);
1106 1112
 			if (i==EXPR_DROP){
1107 1113
 				i=0; /* false */
1108
-				tmpv->s=int2str(i, &tmpv->len);
1114
+				tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1115
+						sizeof(tmp_cache->i2s), &tmpv->len);
1116
+				tmp_cache->cache_type = RV_CACHE_INT2STR;
1109 1117
 				return EXPR_DROP;
1110 1118
 			}
1111
-			tmpv->s=int2str(i, &tmpv->len);
1119
+			tmpv->s=sint2strbuf(i, tmp_cache->i2s, sizeof(tmp_cache->i2s),
1120
+								&tmpv->len);
1121
+			tmp_cache->cache_type = RV_CACHE_INT2STR;
1112 1122
 			break;
1113 1123
 		case RV_SEL:
1114 1124
 			i=run_select(tmpv, &rv->v.sel, msg);
... ...
@@ -1126,7 +1136,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
1126 1136
 					*tmpv=cache->c.avp_val.s;
1127 1137
 				}else if (cache->val_type==RV_INT){
1128 1138
 					i=cache->c.avp_val.n;
1129
-					tmpv->s=int2str(i, &tmpv->len);
1139
+					tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1140
+										sizeof(tmp_cache->i2s), &tmpv->len);
1141
+					tmp_cache->cache_type = RV_CACHE_INT2STR;
1130 1142
 				}else if (cache->val_type==RV_NONE){
1131 1143
 					goto undef;
1132 1144
 				}else goto error_cache;
... ...
@@ -1141,7 +1153,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
1141 1153
 						*tmpv=tmp_cache->c.avp_val.s;
1142 1154
 					}else{
1143 1155
 						i=tmp_cache->c.avp_val.n;
1144
-						tmpv->s=int2str(i, &tmpv->len);
1156
+						tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1157
+										sizeof(tmp_cache->i2s), &tmpv->len);
1158
+						tmp_cache->cache_type = RV_CACHE_INT2STR;
1145 1159
 					}
1146 1160
 				}else goto undef;
1147 1161
 			}
... ...
@@ -1152,7 +1166,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
1152 1166
 					*tmpv=cache->c.pval.rs;
1153 1167
 				}else if (cache->val_type==RV_INT){
1154 1168
 					i=cache->c.pval.ri;
1155
-					tmpv->s=int2str(i, &tmpv->len);
1169
+					tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1170
+										sizeof(tmp_cache->i2s), &tmpv->len);
1171
+					tmp_cache->cache_type = RV_CACHE_INT2STR;
1156 1172
 				}else if (cache->val_type==RV_NONE){
1157 1173
 					goto undef;
1158 1174
 				}else goto error_cache;
... ...
@@ -1170,7 +1186,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
1170 1186
 					}else if (likely(tmp_cache->c.pval.flags & PV_VAL_INT)){
1171 1187
 						i=tmp_cache->c.pval.ri;
1172 1188
 						pv_value_destroy(&tmp_cache->c.pval);
1173
-						tmpv->s=int2str(i, &tmpv->len);
1189
+						tmpv->s=sint2strbuf(i, tmp_cache->i2s,
1190
+										sizeof(tmp_cache->i2s), &tmpv->len);
1191
+						tmp_cache->cache_type = RV_CACHE_INT2STR;
1174 1192
 					}else{
1175 1193
 						/* no PV_VAL_STR and no PV_VAL_INT => undef
1176 1194
 						   (PV_VAL_NULL) */
... ...
@@ -26,12 +26,14 @@
26 26
  *  2009-04-28  added string and interger versions for the EQ and DIFF
27 27
  *              operators (andrei)
28 28
  *  2009-05-05  casts operator for int & string (andrei)
29
+ *  2010-03-16  space for an int2str result inside rval_cache (andrei)
29 30
  */
30 31
 
31 32
 #ifndef _rvalue_h_
32 33
 #define _rvalue_h_
33 34
 
34 35
 #include "str.h"
36
+#include "ut.h"
35 37
 #include "usr_avp.h"
36 38
 #include "select.h"
37 39
 #include "pvar.h"
... ...
@@ -138,7 +140,8 @@ enum rval_cache_type{
138 140
 	RV_CACHE_EMPTY,
139 141
 	RV_CACHE_PVAR,
140 142
 	RV_CACHE_AVP,
141
-	RV_CACHE_SELECT
143
+	RV_CACHE_SELECT,
144
+	RV_CACHE_INT2STR
142 145
 };
143 146
 
144 147
 /** value cache for a rvalue struct.
... ...
@@ -152,6 +155,7 @@ struct rval_cache{
152 155
 		int_str avp_val; /**< avp value */
153 156
 		pv_value_t pval; /**< pvar value */
154 157
 	}c;
158
+	char i2s[INT2STR_MAX_LEN]; /**< space for converting an int to string*/
155 159
 };
156 160
 
157 161