zeek/testing/btest/language/sizeof.zeek
Jon Siwek 73c1af838c GH-251 (revert): remove coercion-to-signed-integer for |x| expressions
For `|x|`, where `x` is an expression with an integral result, an
implicit coercion of that result into signed `int` type no longer takes
place.

This was actually the behavior before Zeek 3.0 as well, but the attempt
to prevent mistakes that easily result from integer literals in Zeek
being unsigned like `|5 - 9|` causing an overflow/wraparound and
yielding a very large number is not generally consistent since overflows
are still generally able to happen in other ways and also in other
contexts besides just absolute-values.  So the preference was to revert
to a behavior that favors consistency.  For reference, see
https://github.com/zeek/zeek/pull/251#issuecomment-713956976
2020-10-22 17:41:53 -07:00

126 lines
3.7 KiB
Text

# @TEST-EXEC: zeek -b %INPUT >output 2>&1
# @TEST-EXEC: btest-diff output
# Demo policy for the sizeof operator "|x|".
# ------------------------------------------
#
# This script creates various types and values and shows the result of the
# sizeof operator on these values.
#
# For any types not covered in this script, the sizeof operator's semantics
# are not defined and its application returns a count of 0. At the moment
# the only type where this should happen is string patterns.
type example_enum: enum { ENUM1, ENUM2, ENUM3 };
type example_record: record {
i: int &optional;
j: int &optional;
k: int &optional;
};
global a: addr = 1.2.3.4;
global a6: addr = [::1];
global b: bool = T;
global c: count = 10;
global d: double = -1.23;
global f: file = open("sizeof_demo.log");
global i: int = -10;
global iv: interval = -5sec;
global p: port = 80/tcp;
global r: example_record = [ $i = +10 ];
global si: set[int];
global s: string = "Hello";
global sn: subnet = 192.168.0.0/24;
global t: table[string] of string;
global ti: time = current_time();
global v: vector of string;
# Additional initialization
#
print f, "12345678901234567890";
add si[1];
add si[10];
add si[100];
t["foo"] = "Hello";
t["bar"] = "World";
v[0] = "Hello";
v[4] = "World";
# Print out the sizes of the various vals:
#-----------------------------------------
# Size of addr: returns number of bits required to represent the address
# which is 32 for IPv4 or 128 for IPv6
print fmt("IPv4 Address %s: %d", a, |a|);
print fmt("IPv6 Address %s: %d", a6, |a6|);
# Size of boolean: returns 1 or 0.
print fmt("Boolean %s: %d", b, |b|);
# Size of count: identity.
print fmt("Count %s: %d", c, |c|);
# Integer literals that lack a "+" or "-" modifier are of the unsigned "count"
# type, so this wraps to a very large number. It may be more intuitive if it
# were to coerce to a signed integer, but it can also be more favorable to
# simply have consistent behavior across arbitrary arithmetic expressions even
# if that may result in occassional, unintended overflow/wrapping.
print fmt("Expr: %d", |5 - 9|);
# Same arithmetic on signed integers is likely what's originally intended.
print fmt("Signed Expr: %d", |+5 - +9|);
# Size of double: returns absolute value.
print fmt("Double %s: %f", d, |d|);
# Size of enum: returns numeric value of enum constant.
print fmt("Enum %s: %d", ENUM3, |ENUM3|);
# Size of file: returns current file size.
# Note that this is a double so that file sizes >> 4GB
# can be expressed.
print fmt("File %f", |f|);
# Size of function: returns number of arguments.
print fmt("Function add_interface: %d", |add_interface|);
# Size of integer: returns absolute value.
print fmt("Integer %s: %d", i, |i|);
# Size of interval: returns double representation of the interval
print fmt("Interval %s: %f", iv, |iv|);
# Size of port: returns port number as a count.
print fmt("Port %s: %d", p, |p|);
# Size of record: returns number of fields (assigned + unassigned)
print fmt("Record %s: %d", r, |r|);
# Size of set: returns number of elements in set.
# Don't print the set, as its order depends on the seeding of the hash
# fnction, and it's not worth the trouble to normalize it.
print fmt("Set: %d", |si|);
# Size of string: returns string length.
print fmt("String '%s': %d", s, |s|);
# Size of subnet: returns size of net as a double
# (so that 2^32 can be expressed too).
print fmt("Subnet %s: %f", sn, |sn|);
# Size of table: returns number of elements in table
print fmt("Table %d", |t|);
# Size of time: returns double representation of the time
# print fmt("Time %s: %f", ti, |ti|);
# Size of vector: returns largest assigned index.
# Note that this is not the number of assigned values.
# The following prints "5":
#
print fmt("Vector %s: %d", v, |v|);
close(f);