mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
GH-219: fix |x| operator int overflow / floating point type inconsistency
When 'x' is an integral arithmetic expression, it's now coerced to yield a signed integer before taking the absolute value of it to prevent the common issue of unsigned integer overflow/wraparound for values below zero. Using a time or interval value/expression for 'x' now also yields a time or interval, respective, from the |x| operation instead of a double.
This commit is contained in:
parent
bebc0fba6d
commit
3256ac7c49
8 changed files with 21 additions and 6 deletions
|
@ -1360,7 +1360,10 @@ SizeExpr::SizeExpr(Expr* arg_op) : UnaryExpr(EXPR_SIZE, arg_op)
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetType(base_type(TYPE_COUNT));
|
if ( op->Type()->InternalType() == TYPE_INTERNAL_DOUBLE )
|
||||||
|
SetType(op->Type()->Ref());
|
||||||
|
else
|
||||||
|
SetType(base_type(TYPE_COUNT));
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* SizeExpr::Eval(Frame* f) const
|
Val* SizeExpr::Eval(Frame* f) const
|
||||||
|
|
|
@ -425,7 +425,7 @@ Val* Val::SizeVal() const
|
||||||
return val_mgr->GetCount(val.uint_val);
|
return val_mgr->GetCount(val.uint_val);
|
||||||
|
|
||||||
case TYPE_INTERNAL_DOUBLE:
|
case TYPE_INTERNAL_DOUBLE:
|
||||||
return new Val(fabs(val.double_val), TYPE_DOUBLE);
|
return new Val(fabs(val.double_val), type->Tag());
|
||||||
|
|
||||||
case TYPE_INTERNAL_OTHER:
|
case TYPE_INTERNAL_OTHER:
|
||||||
if ( type->Tag() == TYPE_FUNC )
|
if ( type->Tag() == TYPE_FUNC )
|
||||||
|
|
|
@ -728,7 +728,12 @@ expr:
|
||||||
| '|' expr '|' %prec '('
|
| '|' expr '|' %prec '('
|
||||||
{
|
{
|
||||||
set_location(@1, @3);
|
set_location(@1, @3);
|
||||||
$$ = new SizeExpr($2);
|
auto e = $2;
|
||||||
|
|
||||||
|
if ( IsIntegral(e->Type()->Tag()) )
|
||||||
|
e = new ArithCoerceExpr(e, TYPE_INT);
|
||||||
|
|
||||||
|
$$ = new SizeExpr(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
| expr TOK_AS type
|
| expr TOK_AS type
|
||||||
|
|
|
@ -15,6 +15,7 @@ add different time units (PASS)
|
||||||
subtract different time units (PASS)
|
subtract different time units (PASS)
|
||||||
absolute value (PASS)
|
absolute value (PASS)
|
||||||
absolute value (PASS)
|
absolute value (PASS)
|
||||||
|
absolute value (PASS)
|
||||||
assignment operator (PASS)
|
assignment operator (PASS)
|
||||||
assignment operator (PASS)
|
assignment operator (PASS)
|
||||||
multiplication operator (PASS)
|
multiplication operator (PASS)
|
||||||
|
|
|
@ -2,6 +2,7 @@ IPv4 Address 1.2.3.4: 32
|
||||||
IPv6 Address ::1: 128
|
IPv6 Address ::1: 128
|
||||||
Boolean T: 1
|
Boolean T: 1
|
||||||
Count 10: 10
|
Count 10: 10
|
||||||
|
Expr: 4
|
||||||
Double -1.23: 1.230000
|
Double -1.23: 1.230000
|
||||||
Enum ENUM3: 2
|
Enum ENUM3: 2
|
||||||
File 21.000000
|
File 21.000000
|
||||||
|
|
|
@ -70,8 +70,9 @@ event bro_init()
|
||||||
test_case( "compare different time units", in13 >= in35 );
|
test_case( "compare different time units", in13 >= in35 );
|
||||||
test_case( "add different time units", in13 + in14 == 4min );
|
test_case( "add different time units", in13 + in14 == 4min );
|
||||||
test_case( "subtract different time units", in24 - in23 == 0sec );
|
test_case( "subtract different time units", in24 - in23 == 0sec );
|
||||||
test_case( "absolute value", |in25| == 2.0*3600 );
|
test_case( "absolute value", |in25| == 2hr );
|
||||||
test_case( "absolute value", |in36| == 2.5*86400 );
|
test_case( "absolute value", |in36| == 2.5day );
|
||||||
|
test_case( "absolute value", |5sec - 9sec| == 4sec );
|
||||||
in34 += 2hr;
|
in34 += 2hr;
|
||||||
test_case( "assignment operator", in34 == 122min );
|
test_case( "assignment operator", in34 == 122min );
|
||||||
in34 -= 2hr;
|
in34 -= 2hr;
|
||||||
|
|
|
@ -64,6 +64,10 @@ print fmt("Boolean %s: %d", b, |b|);
|
||||||
# Size of count: identity.
|
# Size of count: identity.
|
||||||
print fmt("Count %s: %d", c, |c|);
|
print fmt("Count %s: %d", c, |c|);
|
||||||
|
|
||||||
|
# Size of integral arithmetic expression should coerce to int before absolute
|
||||||
|
# value operation to help prevent common unsigned int overflow situations.
|
||||||
|
print fmt("Expr: %d", |5 - 9|);
|
||||||
|
|
||||||
# Size of double: returns absolute value.
|
# Size of double: returns absolute value.
|
||||||
print fmt("Double %s: %f", d, |d|);
|
print fmt("Double %s: %f", d, |d|);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ event bro_init()
|
||||||
test_case( "inequality", t1 != t3 );
|
test_case( "inequality", t1 != t3 );
|
||||||
test_case( "equality", t1 == t4 );
|
test_case( "equality", t1 == t4 );
|
||||||
test_case( "subtract time", t2 - t1 == 3sec);
|
test_case( "subtract time", t2 - t1 == 3sec);
|
||||||
test_case( "size operator", |t5| == 1234567890.0 );
|
test_case( "size operator", |t5| == t5 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue