diff --git a/CHANGES b/CHANGES index d21167eb3c..47e1b062c0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +7.0.0-dev.54 | 2024-03-12 10:31:19 +0100 + + * GH-3640: Expr: Handle TYPE_VOID in SizeExpr and AssignExpr::Typecheck() (Arne Welzel, Corelight) + + @vpax reported surprising behavior when working with "void values". + While these are not exposed to script land, plumb the places he + pointed out are causing confusing behavior. + + Closes #3640. + 7.0.0-dev.52 | 2024-03-08 19:10:06 +0100 * AST location fixes for -O gen-C++ (Vern Paxson, Corelight) diff --git a/VERSION b/VERSION index d7c545d85b..bca4904f5f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0-dev.52 +7.0.0-dev.54 diff --git a/src/Expr.cc b/src/Expr.cc index b073db85b6..8cd3bb5200 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -1313,7 +1313,9 @@ SizeExpr::SizeExpr(ExprPtr arg_op) : UnaryExpr(EXPR_SIZE, std::move(arg_op)) { auto& t = op->GetType(); - if ( t->Tag() == TYPE_ANY ) + if ( t->Tag() == TYPE_VOID ) + SetError("cannot take size of void"); + else if ( t->Tag() == TYPE_ANY ) SetType(base_type(TYPE_ANY)); else if ( t->Tag() == TYPE_FILE || t->Tag() == TYPE_SUBNET || t->InternalType() == TYPE_INTERNAL_DOUBLE ) SetType(base_type(TYPE_DOUBLE)); @@ -2234,6 +2236,11 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) { TypeTag bt1 = op1->GetType()->Tag(); TypeTag bt2 = op2->GetType()->Tag(); + if ( bt2 == TYPE_VOID ) { + ExprError("can't assign void value"); + return false; + } + if ( bt1 == TYPE_LIST && bt2 == TYPE_ANY ) // This is ok because we cannot explicitly declare lists on // the script level. @@ -2271,7 +2278,7 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) { } } - if ( op1->GetType()->Tag() == TYPE_RECORD && op2->GetType()->Tag() == TYPE_RECORD ) { + if ( bt1 == TYPE_RECORD && bt2 == TYPE_RECORD ) { if ( same_type(op1->GetType(), op2->GetType()) ) return true; diff --git a/testing/btest/Baseline/language.void-errors-2/output b/testing/btest/Baseline/language.void-errors-2/output new file mode 100644 index 0000000000..77c3fb552a --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-2/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 2: identifier not defined: void diff --git a/testing/btest/Baseline/language.void-errors-3/output b/testing/btest/Baseline/language.void-errors-3/output new file mode 100644 index 0000000000..5c126a4aab --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-3/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 1: identifier not defined: void diff --git a/testing/btest/Baseline/language.void-errors-4/output b/testing/btest/Baseline/language.void-errors-4/output new file mode 100644 index 0000000000..60fd435cfe --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-4/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 2: return statement cannot have an expression (return (a)) diff --git a/testing/btest/Baseline/language.void-errors-5/output b/testing/btest/Baseline/language.void-errors-5/output new file mode 100644 index 0000000000..6fe5ee9b76 --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-5/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 4: cannot take size of void (sizeofx[3.4.5.6]) diff --git a/testing/btest/Baseline/language.void-errors-6/output b/testing/btest/Baseline/language.void-errors-6/output new file mode 100644 index 0000000000..80d7585be8 --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-6/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 2: can't assign void value (y = x[3]) diff --git a/testing/btest/Baseline/language.void-errors-7/output b/testing/btest/Baseline/language.void-errors-7/output new file mode 100644 index 0000000000..29dbf68b43 --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-7/output @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 5: can't assign void value (z = x()) +error in <...>/void-errors.zeek, line 6: value of type void illegal (print x()) +error in <...>/void-errors.zeek, line 7: cannot take size of void (sizeofx()) diff --git a/testing/btest/Baseline/language.void-errors/output b/testing/btest/Baseline/language.void-errors/output new file mode 100644 index 0000000000..c64263c499 --- /dev/null +++ b/testing/btest/Baseline/language.void-errors/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 7: identifier not defined: void diff --git a/testing/btest/language/void-errors.zeek b/testing/btest/language/void-errors.zeek new file mode 100644 index 0000000000..042872bd78 --- /dev/null +++ b/testing/btest/language/void-errors.zeek @@ -0,0 +1,43 @@ +# @TEST-DOC: Zeek does not have a script land void type, but internally it does exist (indexing a set, or a function returning no result). Regression test #3640. +# +# @TEST-EXEC-FAIL: zeek -b %INPUT >output 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff output + +# identifier void not defined... +global x: void = 1; + +# @TEST-START-NEXT +type R: record { + x: void; +}; + + +# @TEST-START-NEXT +function x(): void { + return "a"; +}; + +# @TEST-START-NEXT +function x() { + return "a"; +}; + +# @TEST-START-NEXT + +global x = set(3.4.5.6, 9.8.7.6); +print |x|; +print |x[3.4.5.6]|; + +# @TEST-START-NEXT +local x = set(5, 3); +local y: any = x[3]; +print y; + +# @TEST-START-NEXT +function x() { + print "x()"; +} + +global z: any = x(); +print x(); +print |x()|;