Browse code

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

- reported by Victor Seva, closes FS#358

Daniel-Constantin Mierla authored on 27/10/2013 15:59:32
Showing 3 changed files
... ...
@@ -2756,8 +2756,24 @@ rval_expr: rval						{ $$=$1;
2756 2756
 		| rval_expr BIN_LSHIFT rval_expr {$$=mk_rve2(RVE_BLSHIFT_OP, $1,  $3);}
2757 2757
 		| rval_expr BIN_RSHIFT rval_expr {$$=mk_rve2(RVE_BRSHIFT_OP, $1,  $3);}
2758 2758
 		| rval_expr rve_cmpop rval_expr %prec GT { $$=mk_rve2( $2, $1, $3);}
2759
-		| rval_expr rve_equalop rval_expr %prec EQUAL_T
2760
-			{ $$=mk_rve2( $2, $1, $3);}
2759
+		| rval_expr rve_equalop rval_expr %prec EQUAL_T {
2760
+			/* comparing with $null => treat as defined or !defined */
2761
+			if($3->op==RVE_RVAL_OP && $3->left.rval.type==RV_PVAR
2762
+					&& $3->left.rval.v.pvs.type==PVT_NULL) {
2763
+				if($2==RVE_DIFF_OP || $2==RVE_IDIFF_OP
2764
+						|| $2==RVE_STRDIFF_OP) {
2765
+					DBG("comparison with $null switched to notdefined operator\n");
2766
+					$$=mk_rve1(RVE_DEFINED_OP, $1);
2767
+				} else {
2768
+					DBG("comparison with $null switched to defined operator\n");
2769
+					$$=mk_rve1(RVE_NOTDEFINED_OP, $1);
2770
+				}
2771
+				/* free rve struct for $null */
2772
+				rve_destroy($3);
2773
+			} else {
2774
+				$$=mk_rve2($2, $1, $3);
2775
+			}
2776
+		}
2761 2777
 		| rval_expr LOG_AND rval_expr	{ $$=mk_rve2(RVE_LAND_OP, $1, $3);}
2762 2778
 		| rval_expr LOG_OR rval_expr	{ $$=mk_rve2(RVE_LOR_OP, $1, $3);}
2763 2779
 		| LPAREN rval_expr RPAREN		{ $$=$2;}
... ...
@@ -527,6 +527,7 @@ enum rval_type rve_guess_type( struct rval_expr* rve)
527 527
 		case RVE_STRLEN_OP:
528 528
 		case RVE_STREMPTY_OP:
529 529
 		case RVE_DEFINED_OP:
530
+		case RVE_NOTDEFINED_OP:
530 531
 		case RVE_INT_OP:
531 532
 			return RV_INT;
532 533
 		case RVE_PLUS_OP:
... ...
@@ -572,6 +573,7 @@ int rve_is_constant(struct rval_expr* rve)
572 572
 		case RVE_STRLEN_OP:
573 573
 		case RVE_STREMPTY_OP:
574 574
 		case RVE_DEFINED_OP:
575
+		case RVE_NOTDEFINED_OP:
575 576
 		case RVE_INT_OP:
576 577
 		case RVE_STR_OP:
577 578
 			return rve_is_constant(rve->left.rve);
... ...
@@ -636,6 +638,7 @@ static int rve_op_unary(enum rval_expr_op op)
636 636
 		case RVE_STRLEN_OP:
637 637
 		case RVE_STREMPTY_OP:
638 638
 		case RVE_DEFINED_OP:
639
+		case RVE_NOTDEFINED_OP:
639 640
 		case RVE_INT_OP:
640 641
 		case RVE_STR_OP:
641 642
 			return 1;
... ...
@@ -839,6 +842,7 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
839 839
 		case RVE_STRLEN_OP:
840 840
 		case RVE_STREMPTY_OP:
841 841
 		case RVE_DEFINED_OP:
842
+		case RVE_NOTDEFINED_OP:
842 843
 			*type=RV_INT;
843 844
 			if (rve_check_type(&type1, rve->left.rve, bad_rve, bad_t, exp_t)){
844 845
 				if (type1==RV_INT){
... ...
@@ -2112,6 +2116,10 @@ int rval_expr_eval_int( struct run_act_ctx* h, struct sip_msg* msg,
2112 2112
 		case RVE_DEFINED_OP:
2113 2113
 			ret=int_rve_defined(h, msg, res, rve->left.rve);
2114 2114
 			break;
2115
+		case RVE_NOTDEFINED_OP:
2116
+			ret=int_rve_defined(h, msg, res, rve->left.rve);
2117
+			*res = !(*res);
2118
+			break;
2115 2119
 		case RVE_STREQ_OP:
2116 2120
 		case RVE_STRDIFF_OP:
2117 2121
 		case RVE_MATCH_OP:
... ...
@@ -2233,6 +2241,7 @@ int rval_expr_eval_rvint(			   struct run_act_ctx* h,
2233 2233
 		case RVE_STRLEN_OP:
2234 2234
 		case RVE_STREMPTY_OP:
2235 2235
 		case RVE_DEFINED_OP:
2236
+		case RVE_NOTDEFINED_OP:
2236 2237
 		case RVE_INT_OP:
2237 2238
 			/* operator forces integer type */
2238 2239
 			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,
2360 2360
 		case RVE_STRLEN_OP:
2361 2361
 		case RVE_STREMPTY_OP:
2362 2362
 		case RVE_DEFINED_OP:
2363
+		case RVE_NOTDEFINED_OP:
2363 2364
 		case RVE_INT_OP:
2364 2365
 			/* operator forces integer type */
2365 2366
 			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,
2601 2601
 		case RVE_STRLEN_OP:
2602 2602
 		case RVE_STREMPTY_OP:
2603 2603
 		case RVE_DEFINED_OP:
2604
+		case RVE_NOTDEFINED_OP:
2604 2605
 		case RVE_INT_OP:
2605 2606
 		case RVE_STR_OP:
2606 2607
 			break;
... ...
@@ -2692,6 +2703,7 @@ static int rve_op_is_assoc(enum rval_expr_op op)
2692 2692
 		case RVE_STRLEN_OP:
2693 2693
 		case RVE_STREMPTY_OP:
2694 2694
 		case RVE_DEFINED_OP:
2695
+		case RVE_NOTDEFINED_OP:
2695 2696
 		case RVE_INT_OP:
2696 2697
 		case RVE_STR_OP:
2697 2698
 			/* one operand expression => cannot be assoc. */
... ...
@@ -2747,6 +2759,7 @@ static int rve_op_is_commutative(enum rval_expr_op op)
2747 2747
 		case RVE_STRLEN_OP:
2748 2748
 		case RVE_STREMPTY_OP:
2749 2749
 		case RVE_DEFINED_OP:
2750
+		case RVE_NOTDEFINED_OP:
2750 2751
 		case RVE_INT_OP:
2751 2752
 		case RVE_STR_OP:
2752 2753
 			/* one operand expression => cannot be commut. */
... ...
@@ -3796,6 +3809,7 @@ int fix_rval_expr(void* p)
3796 3796
 		case RVE_STRLEN_OP:
3797 3797
 		case RVE_STREMPTY_OP:
3798 3798
 		case RVE_DEFINED_OP:
3799
+		case RVE_NOTDEFINED_OP:
3799 3800
 		case RVE_INT_OP:
3800 3801
 		case RVE_STR_OP:
3801 3802
 			ret=fix_rval_expr((void*)rve->left.rve);
... ...
@@ -87,6 +87,7 @@ enum rval_expr_op{
87 87
 	RVE_MATCH_OP,  /**< 2 members, string ~),  returns left matches re(right) */
88 88
 	/* avp, pvars a.s.o */
89 89
 	RVE_DEFINED_OP, /**< one member, returns is_defined(val) (bool) */
90
+	RVE_NOTDEFINED_OP, /**< one member, returns is_not_defined(val) (bool) */
90 91
 	RVE_INT_OP,   /**< one member, returns (int)val  (int) */
91 92
 	RVE_STR_OP    /**< one member, returns (str)val  (str) */
92 93
 };