|
@@ -44,12 +44,43 @@
|
|
* ("" == "")
|
|
* ("" == "")
|
|
* NOTE: expr == undef, with defined(expr) is always evaluated this way:
|
|
* NOTE: expr == undef, with defined(expr) is always evaluated this way:
|
|
expr == (type_of(expr))undef
|
|
expr == (type_of(expr))undef
|
|
|
|
+ * RV_STR2INT_VERBOSE_ERR - if a string conversion to int fails, log (L_WARN)
|
|
|
|
+ * the string that caused it (only the string, not
|
|
|
|
+ * the expression position).
|
|
|
|
+ * RV_STR2INT_ERR - if a string conversion to int fails, don't ignore
|
|
|
|
+ * the error (return error).
|
|
|
|
+ * RVAL_GET_INT_ERR_WARN - if a conversion to int fails, log a warning with
|
|
|
|
+ * the expression position.
|
|
|
|
+ * Depends on RV_STR2INT_ERR.
|
|
|
|
+ * RVAL_GET_INT_ERR_IGN - if a conversion to int fails, ignore the error
|
|
|
|
+ * (the result will be 0). Can be combined with
|
|
|
|
+ * RVAL_GET_INT_ERR_WARN.
|
|
|
|
+ * Depends on RV_STR2INT_ERR.
|
|
*/
|
|
*/
|
|
|
|
|
|
#include "rvalue.h"
|
|
#include "rvalue.h"
|
|
|
|
|
|
#include <stdlib.h> /* abort() */
|
|
#include <stdlib.h> /* abort() */
|
|
|
|
|
|
|
|
+/* if defined warn when str2int conversions fail */
|
|
|
|
+#define RV_STR2INT_VERBOSE_ERR
|
|
|
|
+
|
|
|
|
+/* if defined rval_get_int will fail if str2int conversion fail
|
|
|
|
+ (else convert to 0) */
|
|
|
|
+#define RV_STR2INT_ERR
|
|
|
|
+
|
|
|
|
+/* if a rval_get_int fails (conversion to int), warn
|
|
|
|
+ Depends on RV_STR2INT_ERR.
|
|
|
|
+ */
|
|
|
|
+#define RVAL_GET_INT_ERR_WARN
|
|
|
|
+
|
|
|
|
+/* if a rval_get_int fails, ignore it (expression evaluation will not fail,
|
|
|
|
+ the int conversion will result in 0).
|
|
|
|
+ Can be combined with RVAL_GET_INT_ERR_WARN.
|
|
|
|
+ Depends on RV_STR2INT_ERR.
|
|
|
|
+ */
|
|
|
|
+#define RVAL_GET_INT_ERR_IGN
|
|
|
|
+
|
|
/* minimum size alloc'ed for STR RVs (to accomodate
|
|
/* minimum size alloc'ed for STR RVs (to accomodate
|
|
* strops without reallocs) */
|
|
* strops without reallocs) */
|
|
#define RV_STR_EXTRA 80
|
|
#define RV_STR_EXTRA 80
|
|
@@ -127,15 +158,19 @@ void rve_destroy(struct rval_expr* rve)
|
|
if (rve->left.rval.refcnt==1)
|
|
if (rve->left.rval.refcnt==1)
|
|
rval_destroy(&rve->left.rval);
|
|
rval_destroy(&rve->left.rval);
|
|
else
|
|
else
|
|
- BUG("rval expr rval with invalid refcnt: %d\n",
|
|
|
|
- rve->left.rval.refcnt);
|
|
|
|
|
|
+ BUG("rval expr rval with invalid refcnt: %d (%d,%d-%d,%d)"
|
|
|
|
+ "\n", rve->left.rval.refcnt,
|
|
|
|
+ rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
}
|
|
}
|
|
if (rve->right.rval.refcnt){
|
|
if (rve->right.rval.refcnt){
|
|
if (rve->right.rval.refcnt==1)
|
|
if (rve->right.rval.refcnt==1)
|
|
rval_destroy(&rve->right.rval);
|
|
rval_destroy(&rve->right.rval);
|
|
else
|
|
else
|
|
- BUG("rval expr rval with invalid refcnt: %d\n",
|
|
|
|
- rve->right.rval.refcnt);
|
|
|
|
|
|
+ BUG("rval expr rval with invalid refcnt: %d (%d,%d-%d,%d)"
|
|
|
|
+ "\n", rve->right.rval.refcnt,
|
|
|
|
+ rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
}
|
|
}
|
|
}else{
|
|
}else{
|
|
if (rve->left.rve)
|
|
if (rve->left.rve)
|
|
@@ -802,7 +837,9 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
|
|
break;
|
|
break;
|
|
case RVE_NONE_OP:
|
|
case RVE_NONE_OP:
|
|
default:
|
|
default:
|
|
- BUG("unexpected rve op %d\n", rve->op);
|
|
|
|
|
|
+ BUG("unexpected rve op %d (%d,%d-%d,%d)\n", rve->op,
|
|
|
|
+ rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
if (bad_rve) *bad_rve=rve;
|
|
if (bad_rve) *bad_rve=rve;
|
|
if (bad_t) *bad_t=RV_NONE;
|
|
if (bad_t) *bad_t=RV_NONE;
|
|
if (exp_t) *exp_t=RV_STR;
|
|
if (exp_t) *exp_t=RV_STR;
|
|
@@ -835,11 +872,12 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
|
|
pv_value_t pval;
|
|
pv_value_t pval;
|
|
str tmp;
|
|
str tmp;
|
|
str* s;
|
|
str* s;
|
|
- int r;
|
|
|
|
|
|
+ int r, ret;
|
|
int destroy_pval;
|
|
int destroy_pval;
|
|
|
|
|
|
destroy_pval=0;
|
|
destroy_pval=0;
|
|
s=0;
|
|
s=0;
|
|
|
|
+ ret=0;
|
|
switch(rv->type){
|
|
switch(rv->type){
|
|
case RV_INT:
|
|
case RV_INT:
|
|
*i=rv->v.l;
|
|
*i=rv->v.l;
|
|
@@ -931,15 +969,12 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
|
|
BUG("rv type %d not handled\n", rv->type);
|
|
BUG("rv type %d not handled\n", rv->type);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
- return 0;
|
|
|
|
|
|
+ return ret;
|
|
undef:
|
|
undef:
|
|
eval_error: /* same as undefined */
|
|
eval_error: /* same as undefined */
|
|
/* handle undefined => result 0, return success */
|
|
/* handle undefined => result 0, return success */
|
|
*i=0;
|
|
*i=0;
|
|
return 0;
|
|
return 0;
|
|
-error_cache:
|
|
|
|
- BUG("invalid cached value:cache type %d, value type %d\n",
|
|
|
|
- cache?cache->cache_type:0, cache?cache->val_type:0);
|
|
|
|
rv_str:
|
|
rv_str:
|
|
/* rv is of string type => try to convert it to int */
|
|
/* rv is of string type => try to convert it to int */
|
|
/* if "" => 0 (most likely case) */
|
|
/* if "" => 0 (most likely case) */
|
|
@@ -947,17 +982,73 @@ rv_str:
|
|
else if (unlikely(str2sint(s, i)!=0)){
|
|
else if (unlikely(str2sint(s, i)!=0)){
|
|
/* error converting to int => non numeric => 0 */
|
|
/* error converting to int => non numeric => 0 */
|
|
*i=0;
|
|
*i=0;
|
|
|
|
+#ifdef RV_STR2INT_VERBOSE_ERR
|
|
|
|
+ WARN("automatic string to int conversion for \"%.*s\" failed\n",
|
|
|
|
+ s->len, ZSW(s->s));
|
|
|
|
+ /* return an error code */
|
|
|
|
+#endif
|
|
|
|
+#ifdef RV_STR2INT_ERR
|
|
|
|
+ ret=-1;
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
if (destroy_pval)
|
|
if (destroy_pval)
|
|
pv_value_destroy(&pval);
|
|
pv_value_destroy(&pval);
|
|
- return 0;
|
|
|
|
|
|
+ return ret;
|
|
|
|
+error_cache:
|
|
|
|
+ BUG("invalid cached value:cache type %d, value type %d\n",
|
|
|
|
+ cache?cache->cache_type:0, cache?cache->val_type:0);
|
|
error:
|
|
error:
|
|
|
|
+ if (destroy_pval)
|
|
|
|
+ pv_value_destroy(&pval);
|
|
*i=0;
|
|
*i=0;
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+/** log a message, appending rve position and a '\n'.*/
|
|
|
|
+#define RVE_LOG(lev, rve, txt) \
|
|
|
|
+ LOG((lev), txt " (%d,%d-%d,%d)\n", \
|
|
|
|
+ (rve)->fpos.s_line, rve->fpos.s_col, \
|
|
|
|
+ (rve)->fpos.e_line, rve->fpos.e_col )
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/** macro for checking and handling rval_get_int() retcode.
|
|
|
|
+ * check if the return code is an rval_get_int error and if so
|
|
|
|
+ * handle the error (e.g. print a log message, ignore the error by
|
|
|
|
+ * setting ret to 0 a.s.o.)
|
|
|
|
+ * @param ret - retcode as returned by rval_get_int() (might be changed)
|
|
|
|
+ * @param txt - warning message txt (no pointer allowed)
|
|
|
|
+ * @param rve - rval_expr, used to access the config. pos
|
|
|
|
+ */
|
|
|
|
+#if defined RVAL_GET_INT_ERR_WARN && defined RVAL_GET_INT_ERR_IGN
|
|
|
|
+#define rval_get_int_handle_ret(ret, txt, rve) \
|
|
|
|
+ do { \
|
|
|
|
+ if (unlikely((ret)<0)) { \
|
|
|
|
+ RVE_LOG(L_WARN, rve, txt); \
|
|
|
|
+ (ret)=0; \
|
|
|
|
+ } \
|
|
|
|
+ }while(0)
|
|
|
|
+#elif defined RVAL_GET_INT_ERR_WARN
|
|
|
|
+#define rval_get_int_handle_ret(ret, txt, rve) \
|
|
|
|
+ do { \
|
|
|
|
+ if (unlikely((ret)<0)) \
|
|
|
|
+ RVE_LOG(L_WARN, rve, txt); \
|
|
|
|
+ }while(0)
|
|
|
|
+#elif define RVAL_GET_INT_ERR_IGN \
|
|
|
|
+ do { \
|
|
|
|
+ if (unlikely((ret)<0)) \
|
|
|
|
+ (ret)=0; \
|
|
|
|
+ } while(0)
|
|
|
|
+#else
|
|
|
|
+#define rval_get_int_handle_ret(ret, txt, rve) /* do nothing */
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
/** get the string value of an rv in a tmp variable
|
|
/** get the string value of an rv in a tmp variable
|
|
* *s=(str)rv
|
|
* *s=(str)rv
|
|
* if rv == undefined select, avp or pvar, return "".
|
|
* if rv == undefined select, avp or pvar, return "".
|
|
@@ -1743,6 +1834,8 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
|
|
switch(rve->op){
|
|
switch(rve->op){
|
|
case RVE_RVAL_OP:
|
|
case RVE_RVAL_OP:
|
|
ret=rval_get_int(h, msg, res, &rve->left.rval, 0);
|
|
ret=rval_get_int(h, msg, res, &rve->left.rval, 0);
|
|
|
|
+ rval_get_int_handle_ret(ret, "rval expression conversion to int"
|
|
|
|
+ " failed", rve);
|
|
break;
|
|
break;
|
|
case RVE_UMINUS_OP:
|
|
case RVE_UMINUS_OP:
|
|
case RVE_BOOL_OP:
|
|
case RVE_BOOL_OP:
|
|
@@ -1870,7 +1963,7 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
|
|
#endif /* UNDEF_EQ_* */
|
|
#endif /* UNDEF_EQ_* */
|
|
rval_cache_clean(&c1);
|
|
rval_cache_clean(&c1);
|
|
rval_destroy(rv1);
|
|
rval_destroy(rv1);
|
|
- }else{
|
|
|
|
|
|
+ }else{
|
|
/* left value == defined and != int => str
|
|
/* left value == defined and != int => str
|
|
* => lval == (str) val */
|
|
* => lval == (str) val */
|
|
if (unlikely((rv2=rval_expr_eval(h, msg,
|
|
if (unlikely((rv2=rval_expr_eval(h, msg,
|
|
@@ -1893,8 +1986,10 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
|
|
ret=-1;
|
|
ret=-1;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- /* conver to int */
|
|
|
|
|
|
+ /* convert to int */
|
|
ret=rval_get_int(h, msg, res, rv1, 0); /* convert to int */
|
|
ret=rval_get_int(h, msg, res, rv1, 0); /* convert to int */
|
|
|
|
+ rval_get_int_handle_ret(ret, "rval expression conversion to int"
|
|
|
|
+ " failed", rve);
|
|
rval_destroy(rv1);
|
|
rval_destroy(rv1);
|
|
break;
|
|
break;
|
|
case RVE_STR_OP:
|
|
case RVE_STR_OP:
|
|
@@ -1909,6 +2004,8 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
|
|
if (unlikely(rv1)){
|
|
if (unlikely(rv1)){
|
|
/* expr evaluated to string => (int)(str)v == (int)v */
|
|
/* expr evaluated to string => (int)(str)v == (int)v */
|
|
ret=rval_get_int(h, msg, res, rv1, &c1); /* convert to int */
|
|
ret=rval_get_int(h, msg, res, rv1, &c1); /* convert to int */
|
|
|
|
+ rval_get_int_handle_ret(ret, "rval expression conversion"
|
|
|
|
+ " to int failed", rve);
|
|
rval_destroy(rv1);
|
|
rval_destroy(rv1);
|
|
rval_cache_clean(&c1);
|
|
rval_cache_clean(&c1);
|
|
} /* else (rv1==0)
|
|
} /* else (rv1==0)
|
|
@@ -1960,7 +2057,9 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
|
|
break;
|
|
break;
|
|
case RVE_NONE_OP:
|
|
case RVE_NONE_OP:
|
|
/*default:*/
|
|
/*default:*/
|
|
- BUG("invalid rval int expression operation %d\n", rve->op);
|
|
|
|
|
|
+ BUG("invalid rval int expression operation %d (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->op, rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
ret=-1;
|
|
ret=-1;
|
|
};
|
|
};
|
|
return ret;
|
|
return ret;
|
|
@@ -2010,12 +2109,10 @@ int rval_expr_eval_rvint( struct run_act_ctx* h,
|
|
type=rval_get_btype(h, msg, rv1, cache);
|
|
type=rval_get_btype(h, msg, rv1, cache);
|
|
if (type==RV_INT){
|
|
if (type==RV_INT){
|
|
r=rval_get_int(h, msg, res_i, rv1, cache);
|
|
r=rval_get_int(h, msg, res_i, rv1, cache);
|
|
- if (unlikely(r<0)){
|
|
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
|
|
+ rval_get_int_handle_ret(r, "rval expression conversion"
|
|
|
|
+ " to int failed", rve);
|
|
*res_rv=0;
|
|
*res_rv=0;
|
|
- ret=0;
|
|
|
|
|
|
+ ret=r; /* equiv. to if (r<0) goto error */
|
|
}else{
|
|
}else{
|
|
/* RV_STR, RV_PVAR, RV_AVP a.s.o => return rv1 and the
|
|
/* RV_STR, RV_PVAR, RV_AVP a.s.o => return rv1 and the
|
|
cached resolved value in cache*/
|
|
cached resolved value in cache*/
|
|
@@ -2059,14 +2156,21 @@ int rval_expr_eval_rvint( struct run_act_ctx* h,
|
|
rval_cache_init(&c1);
|
|
rval_cache_init(&c1);
|
|
r=rval_expr_eval_rvint(h, msg, &rv1, &i, rve->left.rve, &c1);
|
|
r=rval_expr_eval_rvint(h, msg, &rv1, &i, rve->left.rve, &c1);
|
|
if (unlikely(r<0)){
|
|
if (unlikely(r<0)){
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
|
|
+ ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
|
|
|
|
+ rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col
|
|
|
|
+ );
|
|
rval_cache_clean(&c1);
|
|
rval_cache_clean(&c1);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
if (rv1==0){
|
|
if (rv1==0){
|
|
if (unlikely((r=rval_expr_eval_int(h, msg, &j,
|
|
if (unlikely((r=rval_expr_eval_int(h, msg, &j,
|
|
rve->right.rve))<0)){
|
|
rve->right.rve))<0)){
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
|
|
+ ERR("rval expression evaluation failed (%d,%d-%d,%d)"
|
|
|
|
+ "\n", rve->right.rve->fpos.s_line,
|
|
|
|
+ rve->right.rve->fpos.s_col,
|
|
|
|
+ rve->right.rve->fpos.e_line,
|
|
|
|
+ rve->right.rve->fpos.e_col);
|
|
rval_cache_clean(&c1);
|
|
rval_cache_clean(&c1);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
@@ -2075,7 +2179,11 @@ int rval_expr_eval_rvint( struct run_act_ctx* h,
|
|
}else{
|
|
}else{
|
|
rv2=rval_expr_eval(h, msg, rve->right.rve);
|
|
rv2=rval_expr_eval(h, msg, rve->right.rve);
|
|
if (unlikely(rv2==0)){
|
|
if (unlikely(rv2==0)){
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
|
|
+ ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->right.rve->fpos.s_line,
|
|
|
|
+ rve->right.rve->fpos.s_col,
|
|
|
|
+ rve->right.rve->fpos.e_line,
|
|
|
|
+ rve->right.rve->fpos.e_col);
|
|
rval_cache_clean(&c1);
|
|
rval_cache_clean(&c1);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
@@ -2091,7 +2199,9 @@ int rval_expr_eval_rvint( struct run_act_ctx* h,
|
|
break;
|
|
break;
|
|
case RVE_NONE_OP:
|
|
case RVE_NONE_OP:
|
|
/*default:*/
|
|
/*default:*/
|
|
- BUG("invalid rval expression operation %d\n", rve->op);
|
|
|
|
|
|
+ BUG("invalid rval expression operation %d (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->op, rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
};
|
|
};
|
|
rval_destroy(rv1);
|
|
rval_destroy(rv1);
|
|
@@ -2168,29 +2278,39 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
|
|
}
|
|
}
|
|
return ret;
|
|
return ret;
|
|
}else{
|
|
}else{
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
|
|
+ ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case RVE_PLUS_OP:
|
|
case RVE_PLUS_OP:
|
|
rv1=rval_expr_eval(h, msg, rve->left.rve);
|
|
rv1=rval_expr_eval(h, msg, rve->left.rve);
|
|
if (unlikely(rv1==0)){
|
|
if (unlikely(rv1==0)){
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
|
|
+ ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
|
|
|
|
+ rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
rval_cache_init(&c1);
|
|
rval_cache_init(&c1);
|
|
type=rval_get_btype(h, msg, rv1, &c1);
|
|
type=rval_get_btype(h, msg, rv1, &c1);
|
|
switch(type){
|
|
switch(type){
|
|
case RV_INT:
|
|
case RV_INT:
|
|
- if (unlikely((r=rval_get_int(h, msg, &i, rv1, &c1))<0)){
|
|
|
|
|
|
+ r=rval_get_int(h, msg, &i, rv1, &c1);
|
|
|
|
+ rval_get_int_handle_ret(r, "rval expression left side "
|
|
|
|
+ "conversion to int failed",
|
|
|
|
+ rve);
|
|
|
|
+ if (unlikely(r<0)){
|
|
rval_cache_clean(&c1);
|
|
rval_cache_clean(&c1);
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
if (unlikely((r=rval_expr_eval_int(h, msg, &j,
|
|
if (unlikely((r=rval_expr_eval_int(h, msg, &j,
|
|
rve->right.rve))<0)){
|
|
rve->right.rve))<0)){
|
|
rval_cache_clean(&c1);
|
|
rval_cache_clean(&c1);
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
|
|
+ ERR("rval expression evaluation failed (%d,%d-%d,%d):"
|
|
|
|
+ " could not evaluate right side to int\n",
|
|
|
|
+ rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
int_intop2(&r, rve->op, i, j);
|
|
int_intop2(&r, rve->op, i, j);
|
|
@@ -2212,26 +2332,38 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
|
|
case RV_NONE:
|
|
case RV_NONE:
|
|
rv2=rval_expr_eval(h, msg, rve->right.rve);
|
|
rv2=rval_expr_eval(h, msg, rve->right.rve);
|
|
if (unlikely(rv2==0)){
|
|
if (unlikely(rv2==0)){
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
|
|
+ ERR("rval expression evaluation failed (%d,%d-%d,%d)"
|
|
|
|
+ "\n", rve->right.rve->fpos.s_line,
|
|
|
|
+ rve->right.rve->fpos.s_col,
|
|
|
|
+ rve->right.rve->fpos.e_line,
|
|
|
|
+ rve->right.rve->fpos.e_col);
|
|
rval_cache_clean(&c1);
|
|
rval_cache_clean(&c1);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
ret=rval_str_add2(h, msg, rv1, &c1, rv2, 0);
|
|
ret=rval_str_add2(h, msg, rv1, &c1, rv2, 0);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
- BUG("rv unsupported basic type %d\n", type);
|
|
|
|
|
|
+ BUG("rv unsupported basic type %d (%d,%d-%d,%d)\n", type,
|
|
|
|
+ rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
}
|
|
}
|
|
rval_cache_clean(&c1);
|
|
rval_cache_clean(&c1);
|
|
break;
|
|
break;
|
|
case RVE_CONCAT_OP:
|
|
case RVE_CONCAT_OP:
|
|
rv1=rval_expr_eval(h, msg, rve->left.rve);
|
|
rv1=rval_expr_eval(h, msg, rve->left.rve);
|
|
if (unlikely(rv1==0)){
|
|
if (unlikely(rv1==0)){
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
|
|
+ ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
|
|
|
|
+ rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
rv2=rval_expr_eval(h, msg, rve->right.rve);
|
|
rv2=rval_expr_eval(h, msg, rve->right.rve);
|
|
if (unlikely(rv2==0)){
|
|
if (unlikely(rv2==0)){
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
|
|
+ ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->right.rve->fpos.s_line,
|
|
|
|
+ rve->right.rve->fpos.s_col,
|
|
|
|
+ rve->right.rve->fpos.e_line,
|
|
|
|
+ rve->right.rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
ret=rval_str_add2(h, msg, rv1, 0, rv2, 0);
|
|
ret=rval_str_add2(h, msg, rv1, 0, rv2, 0);
|
|
@@ -2239,14 +2371,18 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
|
|
case RVE_STR_OP:
|
|
case RVE_STR_OP:
|
|
rv1=rval_expr_eval(h, msg, rve->left.rve);
|
|
rv1=rval_expr_eval(h, msg, rve->left.rve);
|
|
if (unlikely(rv1==0)){
|
|
if (unlikely(rv1==0)){
|
|
- ERR("rval expression evaluation failed\n");
|
|
|
|
|
|
+ ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->left.rve->fpos.s_line, rve->left.rve->fpos.s_col,
|
|
|
|
+ rve->left.rve->fpos.e_line, rve->left.rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
ret=rval_convert(h, msg, RV_STR, rv1, 0);
|
|
ret=rval_convert(h, msg, RV_STR, rv1, 0);
|
|
break;
|
|
break;
|
|
case RVE_NONE_OP:
|
|
case RVE_NONE_OP:
|
|
/*default:*/
|
|
/*default:*/
|
|
- BUG("invalid rval expression operation %d\n", rve->op);
|
|
|
|
|
|
+ BUG("invalid rval expression operation %d (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->op, rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
};
|
|
};
|
|
rval_destroy(rv1);
|
|
rval_destroy(rv1);
|
|
@@ -2697,18 +2833,24 @@ static int rve_replace_with_ct_rv(struct rval_expr* rve, struct rvalue* rv)
|
|
flags=0;
|
|
flags=0;
|
|
if (rv->type==RV_INT){
|
|
if (rv->type==RV_INT){
|
|
if (rval_get_int(0, 0, &i, rv, 0)!=0){
|
|
if (rval_get_int(0, 0, &i, rv, 0)!=0){
|
|
- BUG("unexpected int evaluation failure\n");
|
|
|
|
|
|
+ BUG("unexpected int evaluation failure (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
v.l=i;
|
|
v.l=i;
|
|
}else if(rv->type==RV_STR){
|
|
}else if(rv->type==RV_STR){
|
|
if (rval_get_str(0, 0, &v.s, rv, 0)<0){
|
|
if (rval_get_str(0, 0, &v.s, rv, 0)<0){
|
|
- BUG("unexpected str evaluation failure\n");
|
|
|
|
|
|
+ BUG("unexpected str evaluation failure(%d,%d-%d,%d)\n",
|
|
|
|
+ rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
flags|=RV_CNT_ALLOCED_F;
|
|
flags|=RV_CNT_ALLOCED_F;
|
|
}else{
|
|
}else{
|
|
- BUG("unknown constant expression type %d\n", rv->type);
|
|
|
|
|
|
+ BUG("unknown constant expression type %d (%d,%d-%d,%d)\n", rv->type,
|
|
|
|
+ rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
return rve_replace_with_val(rve, type, &v, flags);
|
|
return rve_replace_with_val(rve, type, &v, flags);
|
|
@@ -2862,7 +3004,9 @@ static int rve_opt_01(struct rval_expr* rve, enum rval_type rve_type)
|
|
referencing a ct_rve->left.rval if ct_rve is a rval, which
|
|
referencing a ct_rve->left.rval if ct_rve is a rval, which
|
|
would prevent rve_destroy(ct_rve) from working */
|
|
would prevent rve_destroy(ct_rve) from working */
|
|
if ((rv=rval_expr_eval_new(0, 0, ct_rve))==0){
|
|
if ((rv=rval_expr_eval_new(0, 0, ct_rve))==0){
|
|
- ERR("optimization failure, bad expression\n");
|
|
|
|
|
|
+ ERR("optimization failure, bad expression (%d,%d-%d,%d)\n",
|
|
|
|
+ ct_rve->fpos.s_line, ct_rve->fpos.s_col,
|
|
|
|
+ ct_rve->fpos.e_line, ct_rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
op=rve->op;
|
|
op=rve->op;
|
|
@@ -3213,7 +3357,9 @@ static int rve_optimize(struct rval_expr* rve)
|
|
return 0;
|
|
return 0;
|
|
if (rve_is_constant(rve)){
|
|
if (rve_is_constant(rve)){
|
|
if ((rv=rval_expr_eval_new(0, 0, rve))==0){
|
|
if ((rv=rval_expr_eval_new(0, 0, rve))==0){
|
|
- ERR("optimization failure, bad expression\n");
|
|
|
|
|
|
+ ERR("optimization failure, bad expression (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->fpos.s_line, rve->fpos.s_col,
|
|
|
|
+ rve->fpos.e_line, rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
op=rve->op;
|
|
op=rve->op;
|
|
@@ -3256,7 +3402,11 @@ static int rve_optimize(struct rval_expr* rve)
|
|
/* $v - a => $v + (-a) (easier to optimize)*/
|
|
/* $v - a => $v + (-a) (easier to optimize)*/
|
|
if ((rve->op==RVE_MINUS_OP) && (rve_is_constant(rve->right.rve))){
|
|
if ((rve->op==RVE_MINUS_OP) && (rve_is_constant(rve->right.rve))){
|
|
if ((rv=rval_expr_eval_new(0, 0, rve->right.rve))==0){
|
|
if ((rv=rval_expr_eval_new(0, 0, rve->right.rve))==0){
|
|
- ERR("optimization failure, bad expression\n");
|
|
|
|
|
|
+ ERR("optimization failure, bad expression (%d,%d-%d,%d)\n",
|
|
|
|
+ rve->right.rve->fpos.s_line,
|
|
|
|
+ rve->right.rve->fpos.s_col,
|
|
|
|
+ rve->right.rve->fpos.e_line,
|
|
|
|
+ rve->right.rve->fpos.e_col);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
if (rv->type==RV_INT){
|
|
if (rv->type==RV_INT){
|