stop letting roms read off the end of the cart and crash the emulator.

This commit is contained in:
zeromus 2010-02-15 11:02:49 +00:00
parent ecf8cf18c7
commit 40b6351dae
3 changed files with 40 additions and 27 deletions

View File

@ -1333,7 +1333,6 @@ u32 MMU_readFromGC()
case 0x00:
case 0xB7:
{
// TODO: prevent read if the address is out of range
// Make sure any reads below 0x8000 redirect to 0x8000+(adr&0x1FF) as on real cart
if((card.command[0] == 0xB7) && (card.address < 0x8000))
{
@ -1342,6 +1341,13 @@ u32 MMU_readFromGC()
card.address = (0x8000 + (card.address&0x1FF));
}
if(card.address >= gameInfo.romsize)
{
INFO("Reading beyond end of cart! ... %08X > %08X\n",card.address, gameInfo.romsize);
}
//but, this is actually handled by the cart rom buffer being oversized and full of 0xFF.
//is this a good idea? We think so.
val = T1ReadLong(MMU.CART_ROM, card.address & MMU.CART_ROM_MASK);
}
break;

View File

@ -195,7 +195,7 @@ NDS_header * NDS_getROMHeader(void)
memcpy(header->logo, MMU.CART_ROM + 192, 156);
header->logoCRC16 = T1ReadWord(MMU.CART_ROM, 348);
header->headerCRC16 = T1ReadWord(MMU.CART_ROM, 350);
memcpy(header->reserved, MMU.CART_ROM + 352, min(160, gameInfo.romsize - 352));
memcpy(header->reserved, MMU.CART_ROM + 352, min(160, (int)gameInfo.romsize - 352));
return header;
}
@ -345,15 +345,16 @@ static void loadrom(std::string fname) {
gameInfo.resize(size);
fread(gameInfo.romdata,1,size,inf);
gameInfo.fillGap();
fclose(inf);
}
int NDS_LoadROM(const char *filename, const char *logicalFilename)
{
int type = ROM_NDS;
u32 mask;
char buf[MAX_PATH];
int type = ROM_NDS;
u32 mask;
char buf[MAX_PATH];
if (filename == NULL)
return -1;
@ -388,15 +389,8 @@ int NDS_LoadROM(const char *filename, const char *logicalFilename)
if (gameInfo.romsize < 352) {
return -1;
}
//zero 25-dec-08 - this used to yield a mask which was 2x large
//mask = size;
mask = gameInfo.romsize-1;
mask |= (mask >>1);
mask |= (mask >>2);
mask |= (mask >>4);
mask |= (mask >>8);
mask |= (mask >>16);
//decrypt if necessary..
//but this is untested and suspected to fail on big endian, so lets not support this on big endian
@ -415,7 +409,7 @@ int NDS_LoadROM(const char *filename, const char *logicalFilename)
FCEUI_StopMovie();
MMU_unsetRom();
NDS_SetROM((u8*)gameInfo.romdata, mask);
NDS_SetROM((u8*)gameInfo.romdata, gameInfo.mask);
NDS_Reset();
memset(buf, 0, MAX_PATH);
@ -492,15 +486,6 @@ int NDS_LoadROM(const char *filename, const char *logicalFilename)
return -1;
}
//zero 25-dec-08 - this used to yield a mask which was 2x large
//mask = size;
mask = size-1;
mask |= (mask >>1);
mask |= (mask >>2);
mask |= (mask >>4);
mask |= (mask >>8);
mask |= (mask >>16);
gameInfo.resize(size);
// Make sure old ROM is freed first(at least this way we won't be eating
@ -508,7 +493,7 @@ int NDS_LoadROM(const char *filename, const char *logicalFilename)
if(MMU.CART_ROM != MMU.UNUSED_RAM)
NDS_FreeROM();
data = new u8[mask + 1];
data = new u8[gameInfo.mask + 1];
if (!data)
{
reader->DeInit(file);
@ -534,7 +519,7 @@ int NDS_LoadROM(const char *filename, const char *logicalFilename)
if (cheatSearch)
cheatSearch->close();
MMU_unsetRom();
NDS_SetROM(data, mask);
NDS_SetROM(data, gameInfo.mask);
NDS_Reset();
free(noext);

View File

@ -280,11 +280,31 @@ struct GameInfo
{
resize(size);
memcpy(romdata,buf,size);
romsize = (u32)size;
fillGap();
}
void fillGap()
{
memset(romdata+romsize,0xFF,allocatedSize-romsize);
}
void resize(int size) {
if(romdata != NULL) delete[] romdata;
romdata = new char[size];
//calculate the necessary mask for the requested size
mask = size-1;
mask |= (mask >>1);
mask |= (mask >>2);
mask |= (mask >>4);
mask |= (mask >>8);
mask |= (mask >>16);
//now, we actually need to over-allocate, because bytes from anywhere protected by that mask
//could be read from the rom
allocatedSize = mask+1;
romdata = new char[allocatedSize];
romsize = size;
}
u32 crc;
@ -294,7 +314,9 @@ struct GameInfo
char ROMfullName[7][0x100];
void populate();
char* romdata;
int romsize;
u32 romsize;
u32 allocatedSize;
u32 mask;
};
typedef struct TSCalInfo