[sr-dev] git:master: core: handle pv comparison with $null as when defined is used

Daniel-Constantin Mierla miconda at gmail.com
Sun Oct 27 17:02:11 CET 2013


Module: sip-router
Branch: master
Commit: 3856e9e81c8410b220b893a0dfe7114bba6bdc0d
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=3856e9e81c8410b220b893a0dfe7114bba6bdc0d

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Sun Oct 27 16:59:32 2013 +0100

core: handle pv comparison with $null as when defined is used

- reported by Victor Seva, closes FS#358

---

 cfg.y    |   20 ++++++++++++++++++--
 rvalue.c |   14 ++++++++++++++
 rvalue.h |    1 +
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/cfg.y b/cfg.y
index 3b7fbdd..2533f72 100644
--- a/cfg.y
+++ b/cfg.y
@@ -2756,8 +2756,24 @@ rval_expr: rval						{ $$=$1;
 		| rval_expr BIN_LSHIFT rval_expr {$$=mk_rve2(RVE_BLSHIFT_OP, $1,  $3);}
 		| rval_expr BIN_RSHIFT rval_expr {$$=mk_rve2(RVE_BRSHIFT_OP, $1,  $3);}
 		| rval_expr rve_cmpop rval_expr %prec GT { $$=mk_rve2( $2, $1, $3);}
-		| rval_expr rve_equalop rval_expr %prec EQUAL_T
-			{ $$=mk_rve2( $2, $1, $3);}
+		| rval_expr rve_equalop rval_expr %prec EQUAL_T {
+			/* comparing with $null => treat as defined or !defined */
+			if($3->op==RVE_RVAL_OP && $3->left.rval.type==RV_PVAR
+					&& $3->left.rval.v.pvs.type==PVT_NULL) {
+				if($2==RVE_DIFF_OP || $2==RVE_IDIFF_OP
+						|| $2==RVE_STRDIFF_OP) {
+					DBG("comparison with $null switched to notdefined operator\n");
+					$$=mk_rve1(RVE_DEFINED_OP, $1);
+				} else {
+					DBG("comparison with $null switched to defined operator\n");
+					$$=mk_rve1(RVE_NOTDEFINED_OP, $1);
+				}
+				/* free rve struct for $null */
+				rve_destroy($3);
+			} else {
+				$$=mk_rve2($2, $1, $3);
+			}
+		}
 		| rval_expr LOG_AND rval_expr	{ $$=mk_rve2(RVE_LAND_OP, $1, $3);}
 		| rval_expr LOG_OR rval_expr	{ $$=mk_rve2(RVE_LOR_OP, $1, $3);}
 		| LPAREN rval_expr RPAREN		{ $$=$2;}
diff --git a/rvalue.c b/rvalue.c
index cb0db9c..ddc97c2 100644
--- a/rvalue.c
+++ b/rvalue.c
@@ -527,6 +527,7 @@ enum rval_type rve_guess_type( struct rval_expr* rve)
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
+		case RVE_NOTDEFINED_OP:
 		case RVE_INT_OP:
 			return RV_INT;
 		case RVE_PLUS_OP:
@@ -572,6 +573,7 @@ int rve_is_constant(struct rval_expr* rve)
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
+		case RVE_NOTDEFINED_OP:
 		case RVE_INT_OP:
 		case RVE_STR_OP:
 			return rve_is_constant(rve->left.rve);
@@ -636,6 +638,7 @@ static int rve_op_unary(enum rval_expr_op op)
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
+		case RVE_NOTDEFINED_OP:
 		case RVE_INT_OP:
 		case RVE_STR_OP:
 			return 1;
@@ -839,6 +842,7 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
+		case RVE_NOTDEFINED_OP:
 			*type=RV_INT;
 			if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
 				if (type1==RV_INT){
@@ -2112,6 +2116,10 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
 		case RVE_DEFINED_OP:
 			ret=int_rve_defined(h, msg, res, rve->left.rve);
 			break;
+		case RVE_NOTDEFINED_OP:
+			ret=int_rve_defined(h, msg, res, rve->left.rve);
+			*res = !(*res);
+			break;
 		case RVE_STREQ_OP:
 		case RVE_STRDIFF_OP:
 		case RVE_MATCH_OP:
@@ -2233,6 +2241,7 @@ int rval_expr_eval_rvint(			   struct run_act_ctx* h,
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
+		case RVE_NOTDEFINED_OP:
 		case RVE_INT_OP:
 			/* operator forces integer type */
 			ret=rval_expr_eval_int(h, msg, res_i, rve);
@@ -2360,6 +2369,7 @@ struct rvalue* rval_expr_eval(struct run_act_ctx* h, struct sip_msg* msg,
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
+		case RVE_NOTDEFINED_OP:
 		case RVE_INT_OP:
 			/* operator forces integer type */
 			r=rval_expr_eval_int(h, msg, &i, rve);
@@ -2601,6 +2611,7 @@ struct rval_expr* mk_rval_expr1(enum rval_expr_op op, struct rval_expr* rve1,
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
+		case RVE_NOTDEFINED_OP:
 		case RVE_INT_OP:
 		case RVE_STR_OP:
 			break;
@@ -2692,6 +2703,7 @@ static int rve_op_is_assoc(enum rval_expr_op op)
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
+		case RVE_NOTDEFINED_OP:
 		case RVE_INT_OP:
 		case RVE_STR_OP:
 			/* one operand expression => cannot be assoc. */
@@ -2747,6 +2759,7 @@ static int rve_op_is_commutative(enum rval_expr_op op)
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
+		case RVE_NOTDEFINED_OP:
 		case RVE_INT_OP:
 		case RVE_STR_OP:
 			/* one operand expression => cannot be commut. */
@@ -3796,6 +3809,7 @@ int fix_rval_expr(void* p)
 		case RVE_STRLEN_OP:
 		case RVE_STREMPTY_OP:
 		case RVE_DEFINED_OP:
+		case RVE_NOTDEFINED_OP:
 		case RVE_INT_OP:
 		case RVE_STR_OP:
 			ret=fix_rval_expr((void*)rve->left.rve);
diff --git a/rvalue.h b/rvalue.h
index 14675af..c0c2e0e 100644
--- a/rvalue.h
+++ b/rvalue.h
@@ -87,6 +87,7 @@ enum rval_expr_op{
 	RVE_MATCH_OP,  /**< 2 members, string ~),  returns left matches re(right) */
 	/* avp, pvars a.s.o */
 	RVE_DEFINED_OP, /**< one member, returns is_defined(val) (bool) */
+	RVE_NOTDEFINED_OP, /**< one member, returns is_not_defined(val) (bool) */
 	RVE_INT_OP,   /**< one member, returns (int)val  (int) */
 	RVE_STR_OP    /**< one member, returns (str)val  (str) */
 };




More information about the sr-dev mailing list