gb: refuse a map header that does not fit wOverworldMap
The buffer is ds 1300 and every real map plus its three-block border fits in it. A header that says otherwise is one read mid-load, and decoding it would read past the buffer into somebody else s WRAM, so it is a refusal rather than a clamp.
This commit is contained in:
parent
44a7011299
commit
abd3e563a8
2 changed files with 15 additions and 0 deletions
|
|
@ -49,6 +49,13 @@ pub const MAP_BORDER: usize = 3;
|
|||
/// which is why `wCurMapWidth` in blocks is `map_size().width` in tiles divided by this.
|
||||
pub const TILES_PER_BLOCK: u8 = 2;
|
||||
|
||||
/// Bytes `wOverworldMap` has for the loaded map: `ds 1300` (`ram/wram.asm`).
|
||||
///
|
||||
/// A map plus its border of [`MAP_BORDER`] blocks has to fit in this, and every real map does. A
|
||||
/// header that says otherwise is a header read mid-load, which is why the bound is a refusal
|
||||
/// rather than a clamp.
|
||||
pub const OVERWORLD_MAP_BYTES: usize = 1300;
|
||||
|
||||
/// Which of a quadrant's two rows the collision read takes its tile id from: the lower one.
|
||||
///
|
||||
/// A map tile is a 2x2 patch of screen tiles and only one of the four is ever asked about, because
|
||||
|
|
|
|||
|
|
@ -895,6 +895,14 @@ pub fn map_grid(memory: &mut dyn MemoryReader) -> Result<MapGrid, GridRefusal> {
|
|||
let height_blocks = read(memory, ram::wCurMapHeight);
|
||||
let stride = u16::from(width_blocks) + (mapgrid::MAP_BORDER as u16) * 2;
|
||||
let border = mapgrid::MAP_BORDER as u16;
|
||||
// The map plus its border has to fit in `wOverworldMap`, which every real map does. One that
|
||||
// does not is a header caught mid-load, and reading past the buffer would be reading somebody
|
||||
// else's WRAM.
|
||||
if usize::from(stride) * (usize::from(height_blocks) + mapgrid::MAP_BORDER * 2)
|
||||
> mapgrid::OVERWORLD_MAP_BYTES
|
||||
{
|
||||
return Err(GridRefusal::NoHeader);
|
||||
}
|
||||
let mut blocks = Vec::with_capacity(usize::from(width_blocks) * usize::from(height_blocks));
|
||||
for row in 0..u16::from(height_blocks) {
|
||||
for column in 0..u16::from(width_blocks) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue