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 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 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"), 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 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 ValidationError::InvalidLaneIndex => f.write_str("Invalid laneidx"),
229 }
230 }
231}