fixes for (mostly ZAM) vector operation issues found by ASAN

This commit is contained in:
Vern Paxson 2024-11-10 15:59:04 -08:00 committed by Arne Welzel
parent 35cac72984
commit c7e5e5feea
8 changed files with 68 additions and 13 deletions

View file

@ -3251,10 +3251,11 @@ bool VectorVal::Assign(unsigned int index, ValPtr element) {
if ( yield_types ) {
const auto& t = element->GetType();
(*yield_types)[index] = t;
auto& yt_i = (*yield_types)[index];
auto& elem = vector_val[index];
if ( elem )
ZVal::DeleteIfManaged(*elem, t);
ZVal::DeleteIfManaged(*elem, yt_i);
yt_i = t;
elem = ZVal(std::move(element), t);
}
else {

View file

@ -20,7 +20,19 @@ op Any-Vector-Elem-Assign
op1-read
set-type $1
classes VVV VVC
eval EvalVectorElemAssign($1, $2,, vv->Assign(ind, $3.ToVal(Z_TYPE)))
eval auto ind = $2.AsCount();
auto vv = $1.AsVector();
auto yt = vv->RawYieldTypes();
if ( ind < vv->Size() && yt && (*yt)[ind] && ZVal::IsManagedType((*yt)[ind]) )
{
auto orig_elem = vv->RawVec()[ind];
if ( ! vv->Assign(ind, $3.ToVal(Z_TYPE)) )
ERROR("value used but not set");
if ( orig_elem )
ZVal::DeleteManagedType(*orig_elem);
}
else if ( ! vv->Assign(ind, $3.ToVal(Z_TYPE)) )
ERROR("value used but not set");
op Vector-Elem-Assign-Any
op1-read

View file

@ -241,13 +241,13 @@ eval auto& vsel = $1->RawVec();
auto& v1 = $2->RawVec();
auto& v2 = $3->RawVec();
auto n = v1.size();
auto res = new vector<std::optional<ZVal>>(n);
vector<std::optional<ZVal>> res(n);
for ( auto i = 0U; i < n; ++i )
if ( vsel[i] )
(*res)[i] = vsel[i]->AsInt() ? v1[i] : v2[i];
res[i] = vsel[i]->AsInt() ? v1[i] : v2[i];
auto& full_res = $$;
Unref(full_res);
full_res = new VectorVal(cast_intrusive<VectorType>(Z_TYPE), res);
full_res = new VectorVal(cast_intrusive<VectorType>(Z_TYPE), &res);
# Our instruction format doesn't accommodate two constants, so for
# the singular case of a V ? C1 : C2 conditional, we split it into

View file

@ -205,8 +205,9 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con
std::string err = "overflow promoting from "; \
err += ov_err; \
err += " arithmetic value"; \
/* The run-time error will throw an exception, so recover intermediary memory. */ \
delete res_zv; \
ZAM_run_time_error(z_loc, err.c_str()); \
res[i] = std::nullopt; \
} \
else \
res[i] = ZVal(cast(vi)); \
@ -594,8 +595,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con
auto& vec2 = v2->RawVec();
auto n = vec2.size();
auto vec1_ptr = new vector<std::optional<ZVal>>(n);
auto& vec1 = *vec1_ptr;
vector<std::optional<ZVal>> vec1(n);
for ( auto i = 0U; i < n; ++i ) {
if ( vec2[i] )
@ -610,7 +610,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con
auto vt = cast_intrusive<VectorType>(std::move(t));
auto old_v1 = v1;
v1 = new VectorVal(std::move(vt), vec1_ptr);
v1 = new VectorVal(std::move(vt), &vec1);
Unref(old_v1);
}
@ -621,8 +621,13 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con
auto& vec2 = v2->RawVec();
auto& vec3 = v3->RawVec();
auto n = vec2.size();
auto vec1_ptr = new vector<std::optional<ZVal>>(n);
auto& vec1 = *vec1_ptr;
if ( vec3.size() != n ) {
ZAM_run_time_error(util::fmt("vector operands are of different sizes (%d vs. %d)", int(n), int(vec3.size())));
return;
}
vector<std::optional<ZVal>> vec1(n);
for ( auto i = 0U; i < vec2.size(); ++i ) {
if ( vec2[i] && vec3[i] )
@ -637,7 +642,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con
auto vt = cast_intrusive<VectorType>(std::move(t));
auto old_v1 = v1;
v1 = new VectorVal(std::move(vt), vec1_ptr);
v1 = new VectorVal(std::move(vt), &vec1);
Unref(old_v1);
}

View file

@ -0,0 +1,3 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
[[a=abc-1]]
[1]

View file

@ -0,0 +1 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.

View file

@ -0,0 +1,16 @@
# @TEST-DOC: Regression test for leak when mixing "any" types (affected both ZAM and non-ZAM)
# @TEST-EXEC: zeek -b -O ZAM %INPUT >output
# @TEST-EXEC: btest-diff output
type X: record {
a: string;
};
event zeek_init()
{
local vec: vector of any;
vec += X($a="abc-1");
print vec;
vec[0] = 1;
print vec;
}

View file

@ -0,0 +1,17 @@
# @TEST-DOC: Regression test for coercing vectors-of-any
# @TEST-EXEC: zeek -b -O ZAM %INPUT >output
# @TEST-EXEC: btest-diff output
module X;
export {
option o: vector of string = vector();
}
event zeek_init()
{
local x: any = vector();
Config::set_value("X::o", vector("a") + (x as vector of string));
print X::o;
print x;
}