wasm/core/
error.rs

1use alloc::string::String;
2
3use crate::core::indices::GlobalIdx;
4use crate::validation_stack::ValidationStackEntry;
5use crate::RefType;
6use core::fmt::{Display, Formatter};
7use core::str::Utf8Error;
8
9use crate::core::reader::section_header::SectionTy;
10use crate::core::reader::types::ValType;
11
12use super::indices::{DataIdx, ElemIdx, FuncIdx, MemIdx, TableIdx, TypeIdx};
13
14#[derive(Debug, PartialEq, Eq, Clone)]
15pub enum ValidationError {
16    /// The magic number at the very start of the given WASM file is invalid.
17    InvalidMagic,
18    InvalidVersion,
19    MalformedUtf8String(Utf8Error),
20    Eof,
21    InvalidSection(SectionTy, String),
22    InvalidSectionType(u8),
23    SectionOutOfOrder(SectionTy),
24    InvalidNumType,
25    InvalidVecType,
26    InvalidFuncType,
27    InvalidFuncTypeIdx,
28    InvalidRefType,
29    InvalidValType,
30    InvalidExportDesc(u8),
31    InvalidImportDesc(u8),
32    ExprMissingEnd,
33    InvalidInstr(u8),
34    InvalidMultiByteInstr(u8, u32),
35    EndInvalidValueStack,
36    InvalidLocalIdx,
37    InvalidValidationStackValType(Option<ValType>),
38    InvalidValidationStackType(ValidationStackEntry),
39    ExpectedAnOperand,
40    InvalidLimitsType(u8),
41    InvalidMutType(u8),
42    InvalidLimit,
43    MemSizeTooBig,
44    InvalidGlobalIdx(GlobalIdx),
45    GlobalIsConst,
46    MemoryIsNotDefined(MemIdx),
47    //           mem.align, wanted alignment
48    ErroneousAlignment(u32, u32),
49    NoDataSegments,
50    DataSegmentNotFound(DataIdx),
51    InvalidLabelIdx(usize),
52    ValidationCtrlStackEmpty,
53    ElseWithoutMatchingIf,
54    IfWithoutMatchingElse,
55    UnknownTable,
56    TableIsNotDefined(TableIdx),
57    ElementIsNotDefined(ElemIdx),
58    DifferentRefTypes(RefType, RefType),
59    ExpectedARefType(ValType),
60    WrongRefTypeForInteropValue(RefType, RefType),
61    FunctionIsNotDefined(FuncIdx),
62    ReferencingAnUnreferencedFunction(FuncIdx),
63    InvalidTypeIdx(TypeIdx),
64    OnlyFuncRefIsAllowed,
65    TypeUnificationMismatch,
66    InvalidSelectTypeVector,
67    TooManyLocals(usize),
68    Overflow,
69    UnknownFunction,
70    UnknownMemory,
71    UnknownGlobal,
72    DuplicateExportName,
73    UnsupportedMultipleMemoriesProposal,
74    ExprHasTrailingInstructions,
75    FunctionAndCodeSectionsHaveDifferentLengths,
76    DataCountAndDataSectionsLengthAreDifferent,
77    InvalidImportType,
78    InvalidLaneIndex,
79}
80
81impl Display for ValidationError {
82    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
83        match self {
84            ValidationError::InvalidMagic => {
85                f.write_str("The magic number at the very start of the given WASM file is invalid.")
86            }
87            ValidationError::InvalidVersion => f.write_str("The version in the WASM file header is invalid"),
88            ValidationError::MalformedUtf8String(err) => f.write_fmt(format_args!(
89                "A name could not be parsed as it was invalid UTF8: {err}"
90            )),
91            ValidationError::Eof => f.write_str(
92                "A value was expected in the WASM binary but the end of file was reached instead",
93            ),
94            ValidationError::InvalidSection(section, reason) => f.write_fmt(format_args!(
95                "Section '{section:?}' invalid! Reason: {reason}"
96            )),
97            ValidationError::InvalidSectionType(ty) => f.write_fmt(format_args!(
98                "An invalid section type id was found in a section header: {ty}"
99            )),
100            ValidationError::SectionOutOfOrder(ty) => {
101                f.write_fmt(format_args!("The section {ty:?} is out of order"))
102            }
103            ValidationError::InvalidNumType => {
104                f.write_str("An invalid byte was read where a numtype was expected")
105            }
106            ValidationError::InvalidVecType => {
107                f.write_str("An invalid byte was read where a vectype was expected")
108            }
109            ValidationError::InvalidFuncType => {
110                f.write_str("An invalid byte was read where a functype was expected")
111            }
112            ValidationError::InvalidFuncTypeIdx => {
113                f.write_str("An invalid index to the fuctypes table was read")
114            }
115            ValidationError::InvalidRefType => {
116                f.write_str("An invalid byte was read where a reftype was expected")
117            }
118            ValidationError::InvalidValType => {
119                f.write_str("An invalid byte was read where a valtype was expected")
120            }
121            ValidationError::InvalidExportDesc(byte) => f.write_fmt(format_args!(
122                "An invalid byte `{byte:#x?}` was read where an exportdesc was expected"
123            )),
124            ValidationError::InvalidImportDesc(byte) => f.write_fmt(format_args!(
125                "An invalid byte `{byte:#x?}` was read where an importdesc was expected"
126            )),
127            ValidationError::ExprMissingEnd => f.write_str("An expr is missing an end byte"),
128            ValidationError::InvalidInstr(byte) => f.write_fmt(format_args!(
129                "An invalid instruction opcode was found: `{byte:#x?}`"
130            )),
131            ValidationError::InvalidMultiByteInstr(byte1, byte2) => f.write_fmt(format_args!(
132                "An invalid multi-byte instruction opcode was found: `{byte1:#x?} {byte2:#x?}`"
133            )),
134            ValidationError::EndInvalidValueStack => f.write_str(
135                "Different value stack types were expected at the end of a block/function.",
136            ),
137            ValidationError::InvalidLocalIdx => f.write_str("An invalid localidx was used"),
138            ValidationError::InvalidValidationStackValType(ty) => f.write_fmt(format_args!(
139                "An unexpected type was found on the stack when trying to pop another: `{ty:?}`"
140            )),
141            ValidationError::InvalidValidationStackType(ty) => f.write_fmt(format_args!(
142                "An unexpected type was found on the stack: `{ty:?}`"
143            )),
144            ValidationError::InvalidLimitsType(ty) => {
145                f.write_fmt(format_args!("An invalid limits type was found: {ty:#x?}"))
146            }
147            ValidationError::InvalidMutType(byte) => f.write_fmt(format_args!(
148                "An invalid mut/const byte was found: {byte:#x?}"
149            )),
150            ValidationError::InvalidLimit => f.write_str("Size minimum must not be greater than maximum"),
151            ValidationError::MemSizeTooBig => f.write_str("Memory size must be at most 65536 pages (4GiB)"),
152            ValidationError::InvalidGlobalIdx(idx) => f.write_fmt(format_args!(
153                "An invalid global index `{idx}` was specified"
154            )),
155            ValidationError::GlobalIsConst => f.write_str("A const global cannot be written to"),
156            ValidationError::ExpectedAnOperand => f.write_str("Expected a ValType"), // Error => f.write_str("Expected an operand (ValType) on the stack")
157            ValidationError::MemoryIsNotDefined(memidx) => f.write_fmt(format_args!(
158                "C.mems[{memidx}] is NOT defined when it should be"
159            )),
160            ValidationError::ErroneousAlignment(mem_align, minimum_wanted_alignment) => {
161                f.write_fmt(format_args!(
162                    "Alignment ({mem_align}) is not less or equal to {minimum_wanted_alignment}"
163                ))
164            }
165            ValidationError::NoDataSegments => f.write_str("Data Count is None"),
166            ValidationError::DataSegmentNotFound(data_idx) => {
167                f.write_fmt(format_args!("Data Segment {data_idx} not found"))
168            }
169            ValidationError::InvalidLabelIdx(label_idx) => {
170                f.write_fmt(format_args!("invalid label index {label_idx}"))
171            }
172            ValidationError::ValidationCtrlStackEmpty => {
173                f.write_str("cannot retrieve last ctrl block, validation ctrl stack is empty")
174            }
175            ValidationError::ElseWithoutMatchingIf => {
176                f.write_str("read 'else' without a previous matching 'if' instruction")
177            }
178            ValidationError::IfWithoutMatchingElse => {
179                f.write_str("read 'end' without matching 'else' instruction to 'if' instruction")
180            }
181            ValidationError::TableIsNotDefined(table_idx) => f.write_fmt(format_args!(
182                "C.tables[{table_idx}] is NOT defined when it should be"
183            )),
184            ValidationError::ElementIsNotDefined(elem_idx) => f.write_fmt(format_args!(
185                "C.elems[{elem_idx}] is NOT defined when it should be"
186            )),
187            ValidationError::DifferentRefTypes(rref1, rref2) => f.write_fmt(format_args!(
188                "RefType {rref1:?} is NOT equal to RefType {rref2:?}"
189            )),
190            ValidationError::ExpectedARefType(found_valtype) => f.write_fmt(format_args!(
191                "Expected a RefType, found a {found_valtype:?} instead"
192            )),
193            ValidationError::WrongRefTypeForInteropValue(ref_given, ref_wanted) => f.write_fmt(format_args!(
194                "Wrong RefType for InteropValue: Given {ref_given:?} - Needed {ref_wanted:?}"
195            )),
196            ValidationError::FunctionIsNotDefined(func_idx) => f.write_fmt(format_args!(
197                "C.functions[{func_idx}] is NOT defined when it should be"
198            )),
199            ValidationError::ReferencingAnUnreferencedFunction(func_idx) => f.write_fmt(format_args!(
200                "Referenced a function ({func_idx}) that was not referenced in validation"
201            )),
202            ValidationError::InvalidTypeIdx(func_ty_idx) => f.write_fmt(format_args!(
203                "C.fn_types[{func_ty_idx}] is NOT defined when it should be"
204            )),
205            ValidationError::OnlyFuncRefIsAllowed => f.write_str("Only FuncRef is allowed"),
206            ValidationError::TypeUnificationMismatch => {
207                f.write_str("cannot unify types")
208            }
209            ValidationError::InvalidSelectTypeVector => {
210                f.write_str("SELECT T* (0x1C) instruction must have exactly one type in the subsequent type vector")
211            }
212            ValidationError::TooManyLocals(x) => {
213                f.write_fmt(format_args!("Too many locals (more than 2^32-1): {x}"))
214            }
215            ValidationError::Overflow => f.write_str("Overflow"),
216            // TODO: maybe move these to LinkerError also add more info to them (the name's export, function idx, etc)
217            ValidationError::UnknownFunction => f.write_str("Unknown function"),
218            ValidationError::UnknownMemory => f.write_str("Unknown memory"),
219            ValidationError::UnknownGlobal => f.write_str("Unknown global"),
220            ValidationError::UnknownTable => f.write_str("Unknown table"),
221            ValidationError::DuplicateExportName => f.write_str("Duplicate export name"),
222            ValidationError::UnsupportedMultipleMemoriesProposal => f.write_str("Proposal for multiple memories is not yet supported"),
223            ValidationError::ExprHasTrailingInstructions => f.write_str("A code expression has invalid trailing instructions"),
224            ValidationError::FunctionAndCodeSectionsHaveDifferentLengths => f.write_str("The function and code sections have different lengths"),
225            ValidationError::DataCountAndDataSectionsLengthAreDifferent => f.write_str("The data count section specifies a different length than there are actual segments in the data section."),
226            ValidationError::InvalidImportType => f.write_str("Invalid import type"),
227            // TODO: maybe move these to LinkerError also add more info to them (the name's export, function idx, etc)
228            ValidationError::InvalidLaneIndex => f.write_str("Invalid laneidx"),
229        }
230    }
231}