mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
zkas: fix panic in Analyzer
This issue was discovered with fuzzing. Panic 1: It was possible to assign a variable to a function/opcode with no return type. This caused a index-out-of-bounds panic when the analyzer attempted to access the first element of an empty vector of return types. The analyzer now presents an error when a .zk author attempts to assign a variable to an opcode that has no return types. Panic 2: There was an index-out-of-bounds panic when performing verification on Literals that were passed to Opcodes that use Array types as their arguments. This was fixed by pasting the validation code from the Variable verfication section which handles Arrays properly. (Refactoring should be done to reduce duplication here.)
This commit is contained in:
@@ -253,7 +253,37 @@ impl Analyzer {
|
||||
if let Arg::Lit(v) = arg {
|
||||
// Match this literal type to a VarType for
|
||||
// type checking.
|
||||
|
||||
let var_type = v.typ.to_vartype();
|
||||
// TODO: Refactor the Array type checks here and in the Arg::Var
|
||||
// section so that there is less repetition.
|
||||
// Validation for Array types
|
||||
if arg_types[0] == VarType::BaseArray {
|
||||
if var_type != VarType::Base {
|
||||
return Err(self.error.abort(
|
||||
&format!(
|
||||
"Incorrect argument type. Expected `{:?}`, got `{:?}`.",
|
||||
VarType::Base,
|
||||
var_type
|
||||
),
|
||||
v.line,
|
||||
v.column,
|
||||
))
|
||||
}
|
||||
} else if arg_types[0] == VarType::ScalarArray {
|
||||
if var_type != VarType::Scalar {
|
||||
return Err(self.error.abort(
|
||||
&format!(
|
||||
"Incorrect argument type. Expected `{:?}`, got `{:?}`.",
|
||||
VarType::Scalar,
|
||||
var_type
|
||||
),
|
||||
v.line,
|
||||
v.column,
|
||||
))
|
||||
}
|
||||
}
|
||||
// Validation for non-Array types
|
||||
if var_type != arg_types[idx] {
|
||||
return Err(self.error.abort(
|
||||
&format!(
|
||||
@@ -337,6 +367,14 @@ impl Analyzer {
|
||||
// result on the heap.
|
||||
if statement.typ == StatementType::Assign {
|
||||
let mut var = statement.lhs.clone().unwrap();
|
||||
// Since we are doing an assignment, ensure that there is a return type.
|
||||
if return_types.is_empty() {
|
||||
return Err(self.error.abort(
|
||||
"Cannot perform assignment without a return type",
|
||||
var.line,
|
||||
var.column,
|
||||
))
|
||||
}
|
||||
var.typ = return_types[0];
|
||||
stmt.lhs = Some(var.clone());
|
||||
heap.push(var.clone());
|
||||
|
||||
Reference in New Issue
Block a user