compiler: Check owned data decoder validation
62f24fee70c8e37eee6f15d6248664497af705f0f49f4386c979cae27bee3aa1
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); |