Coverage Report

Created: 2026-07-03 16:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/build/source/src/validation/modules/indices.rs
Line
Count
Source
1
use crate::{
2
    core::{
3
        decoding::reader::WasmDecoder,
4
        structure::modules::indices::{
5
            DataIdx, ElemIdx, FuncIdx, GlobalIdx, Idx, IdxVec, LocalIdx, MemIdx, TableIdx, TypeIdx,
6
        },
7
    },
8
    FuncType, ValType, ValidationError,
9
};
10
11
impl TypeIdx {
12
    /// Validates that a given index is a valid type index.
13
    ///
14
    /// On success a new [`TypeIdx`] is returned, otherwise a
15
    /// [`ValidationError`] is returned.
16
9.57k
    pub fn validate(
17
9.57k
        index: u32,
18
9.57k
        c_types: &IdxVec<TypeIdx, FuncType>,
19
9.57k
    ) -> Result<Self, ValidationError> {
20
9.57k
        c_types
21
9.57k
            .validate_index(index)
22
9.57k
            .ok_or(ValidationError::InvalidTypeIdx(index))
23
9.57k
    }
24
25
    /// Reads a type index from Wasm code and validates that it is a valid index
26
    /// for a given types vector.
27
9.44k
    pub fn decode_and_validate(
28
9.44k
        wasm: &mut WasmDecoder,
29
9.44k
        c_types: &IdxVec<TypeIdx, FuncType>,
30
9.44k
    ) -> Result<Self, ValidationError> {
31
9.44k
        let 
index9.43k
= wasm.decode_var_u32()
?4
;
32
9.43k
        Self::validate(index, c_types)
33
9.44k
    }
34
}
35
36
impl FuncIdx {
37
    /// Validates that a given index is a valid function index.
38
    ///
39
    /// On success a new [`FuncIdx`] is returned, otherwise a
40
    /// [`ValidationError`] is returned.
41
9.22k
    pub fn validate<T>(index: u32, c_funcs: &IdxVec<FuncIdx, T>) -> Result<Self, ValidationError> {
42
9.22k
        c_funcs
43
9.22k
            .validate_index(index)
44
9.22k
            .ok_or(ValidationError::InvalidFuncIdx(index))
45
9.22k
    }
46
47
    /// Reads a function index from Wasm code and validates that it is a valid
48
    /// index for a given functions vector.
49
9.22k
    pub fn decode_and_validate<T>(
50
9.22k
        wasm: &mut WasmDecoder,
51
9.22k
        c_funcs: &IdxVec<FuncIdx, T>,
52
9.22k
    ) -> Result<Self, ValidationError> {
53
9.22k
        let 
index9.22k
= wasm.decode_var_u32()
?2
;
54
9.22k
        Self::validate(index, c_funcs)
55
9.22k
    }
56
}
57
58
impl TableIdx {
59
    /// Validates that a given index is a valid table index.
60
    ///
61
    /// On success a new [`TableIdx`] is returned, otherwise a
62
    /// [`ValidationError`] is returned.
63
1.25k
    pub fn validate<T>(
64
1.25k
        index: u32,
65
1.25k
        c_tables: &IdxVec<TableIdx, T>,
66
1.25k
    ) -> Result<Self, ValidationError> {
67
1.25k
        c_tables
68
1.25k
            .validate_index(index)
69
1.25k
            .ok_or(ValidationError::InvalidTableIdx(index))
70
1.25k
    }
71
72
    /// Reads a table index from Wasm code and validates that it is a valid
73
    /// index for a given tables vector.
74
955
    pub fn decode_and_validate<T>(
75
955
        wasm: &mut WasmDecoder,
76
955
        c_tables: &IdxVec<TableIdx, T>,
77
955
    ) -> Result<Self, ValidationError> {
78
955
        let index = wasm.decode_var_u32()
?0
;
79
955
        Self::validate(index, c_tables)
80
955
    }
81
}
82
83
impl MemIdx {
84
    /// Validates that a given index is a valid memory index.
85
    ///
86
    /// On success a new [`MemIdx`] is returned, otherwise a [`ValidationError`]
87
    /// is returned.
88
5.22k
    pub fn validate<T>(index: u32, c_mems: &IdxVec<MemIdx, T>) -> Result<Self, ValidationError> {
89
5.22k
        c_mems
90
5.22k
            .validate_index(index)
91
5.22k
            .ok_or(ValidationError::InvalidMemIdx(index))
92
5.22k
    }
93
94
    /// Reads a memory index from Wasm code and validates that it is a valid
95
    /// index for a given memories vector.
96
85
    pub fn decode_and_validate<T>(
97
85
        wasm: &mut WasmDecoder,
98
85
        c_mems: &IdxVec<MemIdx, T>,
99
85
    ) -> Result<Self, ValidationError> {
100
85
        let index = wasm.decode_var_u32()
?0
;
101
85
        Self::validate(index, c_mems)
102
85
    }
103
}
104
105
impl GlobalIdx {
106
    /// Validates that a given index is a valid global index.
107
    ///
108
    /// On success a new [`GlobalIdx`] is returned, otherwise a
109
    /// [`ValidationError`] is returned.
110
318
    pub fn validate<T>(
111
318
        index: u32,
112
318
        c_globals: &IdxVec<GlobalIdx, T>,
113
318
    ) -> Result<Self, ValidationError> {
114
318
        c_globals
115
318
            .validate_index(index)
116
318
            .ok_or(ValidationError::InvalidGlobalIdx(index))
117
318
    }
118
119
    /// Reads a global index from Wasm code and validates that it is a valid
120
    /// index for a given globals vector.
121
318
    pub fn decode_and_validate<T>(
122
318
        wasm: &mut WasmDecoder,
123
318
        c_globals: &IdxVec<GlobalIdx, T>,
124
318
    ) -> Result<Self, ValidationError> {
125
318
        let index = wasm.decode_var_u32()
?0
;
126
318
        Self::validate(index, c_globals)
127
318
    }
128
}
129
130
impl ElemIdx {
131
    /// Validates that a given index is a valid element index.
132
    ///
133
    /// On success a new [`ElemIdx`] is returned, otherwise a
134
    /// [`ValidationError`] is returned.
135
231
    pub fn validate<T>(index: u32, c_elems: &IdxVec<ElemIdx, T>) -> Result<Self, ValidationError> {
136
231
        c_elems
137
231
            .validate_index(index)
138
231
            .ok_or(ValidationError::InvalidElemIdx(index))
139
231
    }
140
141
    /// Reads an element index from Wasm code and validates that it is a valid
142
    /// index for a given elements vector.
143
231
    pub fn decode_and_validate<T>(
144
231
        wasm: &mut WasmDecoder,
145
231
        c_elems: &IdxVec<ElemIdx, T>,
146
231
    ) -> Result<Self, ValidationError> {
147
231
        let index = wasm.decode_var_u32()
?0
;
148
231
        Self::validate(index, c_elems)
149
231
    }
150
}
151
152
impl DataIdx {
153
    /// Validates that a given index is a valid data index.
154
    ///
155
    /// On success a new [`DataIdx`] is returned, otherwise a
156
    /// [`ValidationError`] is returned.
157
121
    pub fn validate(index: u32, data_count: u32) -> Result<Self, ValidationError> {
158
121
        (index < data_count)
159
121
            .then_some(<Self as Idx>::new(index))
160
121
            .ok_or(ValidationError::InvalidDataIdx(index))
161
121
    }
162
163
    /// Reads a data index from Wasm code and validates that it is a valid
164
    /// by comparing it to the total number of data segments.
165
121
    pub fn decode_and_validate(
166
121
        wasm: &mut WasmDecoder,
167
121
        data_count: u32,
168
121
    ) -> Result<Self, ValidationError> {
169
121
        let index = wasm.decode_var_u32()
?0
;
170
121
        Self::validate(index, data_count)
171
121
    }
172
}
173
174
impl LocalIdx {
175
    /// Reads a local index from Wasm code and validates that it is valid for a
176
    /// given slice of locals.
177
7.93k
    pub fn decode_and_validate(
178
7.93k
        wasm: &mut WasmDecoder,
179
7.93k
        locals_of_current_function: &[ValType],
180
7.93k
    ) -> Result<Self, ValidationError> {
181
7.93k
        let index = wasm.decode_var_u32()
?0
;
182
7.93k
        let index_as_usize = usize::try_from(index).expect("architecture to be at least 32 bits");
183
184
7.93k
        match locals_of_current_function.get(index_as_usize) {
185
7.91k
            Some(_local) => Ok(Self(index)),
186
20
            None => Err(ValidationError::InvalidLocalIdx(index)),
187
        }
188
7.93k
    }
189
}