compiler: Check owned data decoder validation

62f24fee70c8e37eee6f15d6248664497af705f0f49f4386c979cae27bee3aa1
Alexis Sellier committed ago 1 parent a3152d79
lib/std/lang/il/binary/program.rad +25 -9
184 184
/// Read global data and check initializer extents against declared storage.
185 185
unsafe fn readData 'input (input: &mut reader::Reader 'input) -> *[il::Data] throws (binary::Error) {
186 186
    let n = try reader::count(input, 18);
187 187
    let items = try reader::storage(input, @sizeOf(il::Data), @alignOf(il::Data), n)
188 188
        as *mut [il::Data];
189 -
    for i in 0..n {
189 +
    return try fillData(input, items);
190 +
}
191 +
192 +
/// Fill owned data definitions with checked metadata and initializer extents.
193 +
fn fillData 'input (input: &mut reader::Reader 'input, items: *mut [il::Data]) -> *[il::Data] throws (binary::Error) {
194 +
    for i in 0..items.len {
190 195
        let name = try reader::symbol(input);
191 196
        let size = try reader::integer(input, 4) as u32;
192 197
        let alignment = try reader::integer(input, 4) as u32;
193 198
        if alignment == 0 or (alignment & (alignment - 1)) <> 0 {
194 199
            throw binary::Error::Invalid;
195 200
        }
196 201
        let readOnly = try reader::flag(input);
197 202
        let isZeroInit = try reader::flag(input);
198 203
        let count = try reader::count(input, 5);
199 -
        let values = try reader::storage(input, @sizeOf(il::DataValue), @alignOf(il::DataValue), count)
200 -
            as *mut [il::DataValue];
201 -
        let mut extent: u64 = 0;
202 -
        for j in 0..count {
203 -
            let value = try reader::dataValue(input);
204 -
            set extent = try extendDataExtent(extent, value, size);
205 -
            set values[j] = value;
204 +
        unsafe {
205 +
            let values = try reader::storage(input, @sizeOf(il::DataValue), @alignOf(il::DataValue), count)
206 +
                as *mut [il::DataValue];
207 +
            let initialized = try fillDataValues(input, values, size);
208 +
            set items[i] = il::Data { name, size, alignment, readOnly, isZeroInit, values: initialized };
206 209
        }
207 -
        set items[i] = il::Data { name, size, alignment, readOnly, isZeroInit, values };
208 210
    }
209 211
    return items;
210 212
}
211 213
214 +
/// Fill owned initializer storage within its declared byte extent.
215 +
fn fillDataValues 'input (input: &mut reader::Reader 'input, values: *mut [il::DataValue], size: u32)
216 +
    -> *[il::DataValue] throws (binary::Error)
217 +
{
218 +
    let mut extent: u64 = 0;
219 +
    for i in 0..values.len {
220 +
        unsafe {
221 +
            set values[i] = try reader::dataValue(input);
222 +
        }
223 +
        set extent = try extendDataExtent(extent, values[i], size);
224 +
    }
225 +
    return values;
226 +
}
227 +
212 228
/// Read functions with checked block and register indices.
213 229
unsafe fn readFunctions 'input (input: &mut reader::Reader 'input, limits: binary::Limits)
214 230
    -> *unsafe [*unsafe il::Fn] throws (binary::Error)
215 231
{
216 232
    let n = try reader::count(input, 14);