mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00

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
126 lines
3.7 KiB
Text
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);
|