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 <[email protected]>
Committer: Daniel-Constantin Mierla <[email protected]>
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) */
 };


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to