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:
y
2023-09-17 10:20:44 -04:00
committed by parazyd
parent 01a1ade3b6
commit 8a333100ef

View File

@@ -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());