Open initconf opened 1 year ago
While it shouldn't crash, it's definitely incorrect usage of the ternary operator. That should fail parsing earlier than it is.
One real question here is what we should allow for the right side of a ternary operator. Technically the Eval()
method of any expression should return a ValPtr and be handled, but is that something we actually want? I could see limiting it to constants and any container type. I grepped through all of the base scripts. The majority of our uses there are constant values or strings, lookups into tables or records, or calls to functions such as fmt
.
it's definitely incorrect usage of the ternary operator. [...] I could see limiting it to constants and any container type.
It's valid in other languages though. This already triggers the crash without the ternary operator (and that doesn't look half wrong). I wonder if there's something else going on.
event zeek_init() {
local y: count;
local z = (y = 42);
print fmt("y=%s z=%s", y, z);
}
This one actually works:
# cat a.zeek
event zeek_init()
{
local active = T;
local blah: bool;
local b: bool;
b = (active == T) ? (blah = T) : (blah = F);
print active, b, blah;
}
// ternary.cpp
#include <iostream>
int main(int argc, char *argv[])
{
int x = 2;
int y;
int z = x > 1 ? y = 42 : y = 4711;
std::cout << "y=" << y << " z=" << z << std::endl;
}
cat ternary.js
let x = 2;
var y;
let z = x > 1 ? y = 47 : y = 4711;
console.log(`y=${y} z=${z}`);
At the very least there's a parsing error finding the various expressions in the line of script. I set a breakpoint in the CondExpr
constructor and printed out the three operands passed in from the parser. With the original script:
(lldb) p *op1.ptr_
(zeek::detail::Expr) $2 = {
zeek::Obj = {
location = 0x000000011aae17f0
ref_cnt = 1
notify_plugins = false
}
tag = EXPR_EQ
paren = true
type = {
ptr_ = 0x0000000108c07220
}
original = {
ptr_ = nullptr
}
opt_info = 0x000000011a976f70
}
(lldb) p *op2.ptr_
(zeek::detail::Expr) $3 = {
zeek::Obj = {
location = 0x000000011aae16a0
ref_cnt = 1
notify_plugins = false
}
tag = EXPR_ASSIGN
paren = false
type = {
ptr_ = 0x0000000108c07220
}
original = {
ptr_ = nullptr
}
opt_info = 0x000000011a976ef0
}
(lldb) p *op3.ptr_
(zeek::detail::Expr) $4 = {
zeek::Obj = {
location = 0x000000011aae1640
ref_cnt = 1
notify_plugins = false
}
tag = EXPR_NAME
paren = false
type = {
ptr_ = 0x0000000108c07220
}
original = {
ptr_ = nullptr
}
opt_info = 0x000000011a976eb0
}
With the third line changed to local b = (active == T) ? (blah = T) : (blah = F);
:
(lldb) p *op1.ptr_
(zeek::detail::Expr) $0 = {
zeek::Obj = {
location = 0x000000011aae1760
ref_cnt = 1
notify_plugins = false
}
tag = EXPR_EQ
paren = true
type = {
ptr_ = 0x0000000108c07220
}
original = {
ptr_ = nullptr
}
opt_info = 0x000000011a976f70
}
(lldb) p *op2.ptr_
(zeek::detail::Expr) $1 = {
zeek::Obj = {
location = 0x000000011aae1610
ref_cnt = 1
notify_plugins = false
}
tag = EXPR_ASSIGN
paren = true
type = {
ptr_ = 0x0000000108c07220
}
original = {
ptr_ = nullptr
}
opt_info = 0x000000011a976ef0
}
(lldb) p *op3.ptr_
(zeek::detail::Expr) $2 = {
zeek::Obj = {
location = 0x000000011aae14c0
ref_cnt = 1
notify_plugins = false
}
tag = EXPR_ASSIGN
paren = true
type = {
ptr_ = 0x0000000108c07220
}
original = {
ptr_ = nullptr
}
opt_info = 0x000000011a976e70
}
Note how the third operand changed from an EXPR_NAME
to EXPR_ASSIGN
, which makes a whole lot more sense. It's still not working like that, but at least it's just reporting an error instead of segfaulting:
expression error in /Users/tim/Desktop/2933.zeek, line 5: illegal assignment in initialization ((blah = F))
fatal error: errors occurred while initializing
While trying some other code I stumbled across this construct which can trigger a segfault and a coredump.
Here is backtrace:
here is how to replicate:
Let me know if you want access to the coredump and or any other info.