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

Really, they both should be count. But, they were getting provided as an integer. Port is easy since it is backed by an unsigned value. Enums *should* be unsigned, but aren't. This doesn't address that, it just takes the other name for this operator (absolute value) and makes the enum value positive if it's negative. This fixes a case where using the size of operator on enum/port values in certain contexts (like the default parameter of a struct) would cause an internal error.
143 lines
4.3 KiB
Text
143 lines
4.3 KiB
Text
# @TEST-EXEC: zeek -b %INPUT >output
|
|
# @TEST-EXEC: btest-diff output
|
|
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr
|
|
|
|
# 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;
|
|
};
|
|
|
|
type example_record_with_enum: record {
|
|
e: count &default = |ENUM3|;
|
|
} &redef;
|
|
|
|
type example_record_with_port: record {
|
|
p: count &default = |80/tcp|;
|
|
} &redef;
|
|
|
|
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;
|
|
global with_enum: example_record_with_enum;
|
|
global with_port: example_record_with_port;
|
|
|
|
# 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 occasional, 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|);
|
|
|
|
# Within a record, enum sizeof should still be ok
|
|
print fmt("Enum in record: %d %d", with_enum$e, |with_enum$e|);
|
|
|
|
# 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|);
|
|
|
|
# Within a record, port sizeof should still be ok
|
|
print fmt("Port in record: %d %d", with_port$p, |with_port$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
|
|
# function, 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);
|