X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fppf.c;h=edebdd03768638be3d2fe15a3f179347349d87cb;hp=6fcd5bc1094f837dd4eba1a87c5b417800da21f1;hb=HEAD;hpb=4e44d6f63e9f1af3236fbbe2f59016cd42a67d98 diff --git a/libpcsxcore/ppf.c b/libpcsxcore/ppf.c index 6fcd5bc1..f37687cc 100644 --- a/libpcsxcore/ppf.c +++ b/libpcsxcore/ppf.c @@ -21,6 +21,7 @@ #include "psxcommon.h" #include "ppf.h" +#include "misc.h" #include "cdrom.h" typedef struct tagPPF_DATA { @@ -58,6 +59,7 @@ static void FillPPFCache() { if (iPPFNum <= 0) return; pc = ppfCache = (PPF_CACHE *)malloc(iPPFNum * sizeof(PPF_CACHE)); + if (pc == NULL) return; iPPFNum--; p = ppfHead; @@ -133,6 +135,7 @@ void CheckPPFCache(unsigned char *pB, unsigned char m, unsigned char s, unsigned static void AddToPPF(s32 ladr, s32 pos, s32 anz, unsigned char *ppfmem) { if (ppfHead == NULL) { ppfHead = (PPF_DATA *)malloc(sizeof(PPF_DATA) + anz); + if (ppfHead == NULL) return; ppfHead->addr = ladr; ppfHead->pNext = NULL; ppfHead->pos = pos; @@ -164,6 +167,7 @@ static void AddToPPF(s32 ladr, s32 pos, s32 anz, unsigned char *ppfmem) { } padd = (PPF_DATA *)malloc(sizeof(PPF_DATA) + anz); + if (padd == NULL) return; padd->addr = ladr; padd->pNext = p; padd->pos = pos; @@ -183,7 +187,7 @@ void BuildPPFCache() { char method, undo = 0, blockcheck = 0; int dizlen, dizyn; unsigned char ppfmem[512]; - char szPPF[MAXPATHLEN]; + char szPPF[MAXPATHLEN * 2]; int count, seekpos, pos; u32 anz; // use 32-bit to avoid stupid overflows s32 ladr, off, anx; @@ -212,7 +216,8 @@ void BuildPPFCache() { if (ppffile == NULL) return; memset(buffer, 0, 5); - fread(buffer, 3, 1, ppffile); + if (fread(buffer, 1, 3, ppffile) != 3) + goto fail_io; if (strcmp(buffer, "PPF") != 0) { SysPrintf(_("Invalid PPF patch: %s.\n"), szPPF); @@ -235,12 +240,14 @@ void BuildPPFCache() { fseek(ppffile, -8, SEEK_END); memset(buffer, 0, 5); - fread(buffer, 4, 1, ppffile); + if (fread(buffer, 1, 4, ppffile) != 4) + goto fail_io; if (strcmp(".DIZ", buffer) != 0) { dizyn = 0; } else { - fread(&dizlen, 4, 1, ppffile); + if (fread(&dizlen, 1, 4, ppffile) != 4) + goto fail_io; dizlen = SWAP32(dizlen); dizyn = 1; } @@ -266,12 +273,15 @@ void BuildPPFCache() { fseek(ppffile, -6, SEEK_END); memset(buffer, 0, 5); - fread(buffer, 4, 1, ppffile); + if (fread(buffer, 1, 4, ppffile) != 4) + goto fail_io; dizlen = 0; if (strcmp(".DIZ", buffer) == 0) { fseek(ppffile, -2, SEEK_END); - fread(&dizlen, 2, 1, ppffile); + // TODO: Endian/size unsafe? + if (fread(&dizlen, 1, 2, ppffile) != 2) + goto fail_io; dizlen = SWAP32(dizlen); dizlen += 36; } @@ -298,13 +308,19 @@ void BuildPPFCache() { // now do the data reading do { fseek(ppffile, seekpos, SEEK_SET); - fread(&pos, 4, 1, ppffile); + if (fread(&pos, 1, sizeof(pos), ppffile) != sizeof(pos)) + goto fail_io; pos = SWAP32(pos); - if (method == 2) fread(buffer, 4, 1, ppffile); // skip 4 bytes on ppf3 (no int64 support here) + if (method == 2) { + // skip 4 bytes on ppf3 (no int64 support here) + if (fread(buffer, 1, 4, ppffile) != 4) + goto fail_io; + } anz = fgetc(ppffile); - fread(ppfmem, anz, 1, ppffile); + if (fread(ppfmem, 1, anz, ppffile) != anz) + goto fail_io; ladr = pos / CD_FRAMESIZE_RAW; off = pos % CD_FRAMESIZE_RAW; @@ -331,46 +347,91 @@ void BuildPPFCache() { FillPPFCache(); // build address array SysPrintf(_("Loaded PPF %d.0 patch: %s.\n"), method + 1, szPPF); + +fail_io: +#ifndef NDEBUG + SysPrintf(_("File IO error in <%s:%s>.\n"), __FILE__, __func__); +#endif + fclose(ppffile); } // redump.org SBI files, slightly different handling from PCSX-Reloaded unsigned char *sbi_sectors; +int sbi_len; int LoadSBI(const char *fname, int sector_count) { + int good_sectors = 0; + int clean_eof = 0; char buffer[16]; FILE *sbihandle; - u8 sbitime[3]; + u8 sbitime[3], t; int s; sbihandle = fopen(fname, "rb"); if (sbihandle == NULL) return -1; - sbi_sectors = calloc(1, sector_count / 8); + sbi_len = (sector_count + 7) / 8; + sbi_sectors = calloc(1, sbi_len); if (sbi_sectors == NULL) - return -1; + goto end; // 4-byte SBI header - fread(buffer, 1, 4, sbihandle); - while (!feof(sbihandle)) { - fread(sbitime, 1, 3, sbihandle); - fread(buffer, 1, 11, sbihandle); + if (fread(buffer, 1, 4, sbihandle) != 4) + goto end; + while (1) { + s = fread(sbitime, 1, 3, sbihandle); + if (s != 3) + { + if (s == 0) + clean_eof = 1; + break; + } s = MSF2SECT(btoi(sbitime[0]), btoi(sbitime[1]), btoi(sbitime[2])); - if (s < sector_count) + if (s < sector_count) { sbi_sectors[s >> 3] |= 1 << (s&7); + good_sectors++; + } else SysPrintf(_("SBI sector %d >= %d?\n"), s, sector_count); + + // skip to the next record + if (fread(&t, 1, sizeof(t), sbihandle) != sizeof(t)) + break; + s = -1; + switch (t) { + default: + case 1: + s = 10; + break; + case 2: + case 3: + s = 3; + break; + } + if (s < 0) + break; + if (fseek(sbihandle, s, SEEK_CUR)) + break; } +end: + if (!clean_eof) + SysPrintf(_("SBI: parse failure at 0x%lx\n"), ftell(sbihandle)); + if (!good_sectors) { + free(sbi_sectors); + sbi_sectors = NULL; + sbi_len = 0; + } fclose(sbihandle); - - return 0; + return sbi_sectors ? 0 : -1; } void UnloadSBI(void) { if (sbi_sectors) { free(sbi_sectors); sbi_sectors = NULL; + sbi_len = 0; } }