- reported by Victor Seva, closes FS#358
... | ... |
@@ -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 |
}; |