Module: sip-router Branch: andrei/rve_f_params Commit: e5fa2eb3563d532ff88b8c42aa2baa307804b4ee URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e5fa2eb3...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Wed Mar 17 20:09:29 2010 +0100
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)
---
rvalue.c | 46 ++++++++++++++++++++++++++++++++-------------- rvalue.h | 6 +++++- 2 files changed, 37 insertions(+), 15 deletions(-)
diff --git a/rvalue.c b/rvalue.c index d02b194..921edb4 100644 --- a/rvalue.c +++ b/rvalue.c @@ -1062,12 +1062,14 @@ error: * if rv == undefined select, avp or pvar, return "". * if an error occurs while evaluating a select, avp or pvar, behave as * for the undefined case (and return success). - * The result points either to a temporary string or inside - * new_cache. new_cache must be non zero, initialized previously, - * and it _must_ be rval_cache_clean(...)'ed when done. - * WARNING: it's not intended for general use, it might return a pointer - * to a static buffer (int2str) so use the result a.s.a.p, make a copy. - * or use rval_get_str() instead. + * The result points either inside the passed rv, inside + * new_cache or inside an avp. new_cache must be non zero, + * initialized previously and it _must_ be rval_cache_clean(...)'ed when + * done. + * WARNING: it's not intended for general use. It might return a pointer + * inside rv so the result _must_ be treated as read-only. rv and new_cache + * must not be released/freed until the result is no longer needed. + * For general use see rval_get_str(). * @param h - script context handle * @param msg - sip msg * @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, switch(rv->type){ case RV_INT: - tmpv->s=int2str(rv->v.l, &tmpv->len); + tmpv->s=sint2strbuf(rv->v.l, tmp_cache->i2s, + sizeof(tmp_cache->i2s), &tmpv->len); + tmp_cache->cache_type = RV_CACHE_INT2STR; break; case RV_STR: *tmpv=rv->v.s; @@ -1099,16 +1103,22 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg, i=(run_actions(h, rv->v.action, msg)>0); else i=0; - tmpv->s=int2str(i, &tmpv->len); + tmpv->s=sint2strbuf(i, tmp_cache->i2s, + sizeof(tmp_cache->i2s), &tmpv->len); + tmp_cache->cache_type = RV_CACHE_INT2STR; break; case RV_BEXPR: i=eval_expr(h, rv->v.bexpr, msg); if (i==EXPR_DROP){ i=0; /* false */ - tmpv->s=int2str(i, &tmpv->len); + tmpv->s=sint2strbuf(i, tmp_cache->i2s, + sizeof(tmp_cache->i2s), &tmpv->len); + tmp_cache->cache_type = RV_CACHE_INT2STR; return EXPR_DROP; } - tmpv->s=int2str(i, &tmpv->len); + tmpv->s=sint2strbuf(i, tmp_cache->i2s, sizeof(tmp_cache->i2s), + &tmpv->len); + tmp_cache->cache_type = RV_CACHE_INT2STR; break; case RV_SEL: 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, *tmpv=cache->c.avp_val.s; }else if (cache->val_type==RV_INT){ i=cache->c.avp_val.n; - tmpv->s=int2str(i, &tmpv->len); + tmpv->s=sint2strbuf(i, tmp_cache->i2s, + sizeof(tmp_cache->i2s), &tmpv->len); + tmp_cache->cache_type = RV_CACHE_INT2STR; }else if (cache->val_type==RV_NONE){ goto undef; }else goto error_cache; @@ -1141,7 +1153,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg, *tmpv=tmp_cache->c.avp_val.s; }else{ i=tmp_cache->c.avp_val.n; - tmpv->s=int2str(i, &tmpv->len); + tmpv->s=sint2strbuf(i, tmp_cache->i2s, + sizeof(tmp_cache->i2s), &tmpv->len); + tmp_cache->cache_type = RV_CACHE_INT2STR; } }else goto undef; } @@ -1152,7 +1166,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg, *tmpv=cache->c.pval.rs; }else if (cache->val_type==RV_INT){ i=cache->c.pval.ri; - tmpv->s=int2str(i, &tmpv->len); + tmpv->s=sint2strbuf(i, tmp_cache->i2s, + sizeof(tmp_cache->i2s), &tmpv->len); + tmp_cache->cache_type = RV_CACHE_INT2STR; }else if (cache->val_type==RV_NONE){ goto undef; }else goto error_cache; @@ -1170,7 +1186,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg, }else if (likely(tmp_cache->c.pval.flags & PV_VAL_INT)){ i=tmp_cache->c.pval.ri; pv_value_destroy(&tmp_cache->c.pval); - tmpv->s=int2str(i, &tmpv->len); + tmpv->s=sint2strbuf(i, tmp_cache->i2s, + sizeof(tmp_cache->i2s), &tmpv->len); + tmp_cache->cache_type = RV_CACHE_INT2STR; }else{ /* no PV_VAL_STR and no PV_VAL_INT => undef (PV_VAL_NULL) */ diff --git a/rvalue.h b/rvalue.h index f658c5e..90c02b3 100644 --- a/rvalue.h +++ b/rvalue.h @@ -26,12 +26,14 @@ * 2009-04-28 added string and interger versions for the EQ and DIFF * operators (andrei) * 2009-05-05 casts operator for int & string (andrei) + * 2010-03-16 space for an int2str result inside rval_cache (andrei) */
#ifndef _rvalue_h_ #define _rvalue_h_
#include "str.h" +#include "ut.h" #include "usr_avp.h" #include "select.h" #include "pvar.h" @@ -138,7 +140,8 @@ enum rval_cache_type{ RV_CACHE_EMPTY, RV_CACHE_PVAR, RV_CACHE_AVP, - RV_CACHE_SELECT + RV_CACHE_SELECT, + RV_CACHE_INT2STR };
/** value cache for a rvalue struct. @@ -152,6 +155,7 @@ struct rval_cache{ int_str avp_val; /**< avp value */ pv_value_t pval; /**< pvar value */ }c; + char i2s[INT2STR_MAX_LEN]; /**< space for converting an int to string*/ };