diff --git a/core/imgread/cue.cpp b/core/imgread/cue.cpp index be59d8c90..aa2667506 100644 --- a/core/imgread/cue.cpp +++ b/core/imgread/cue.cpp @@ -211,7 +211,13 @@ Disc* cue_parse(const char* file, std::vector *digest) } if (session_number == 0) + { + if (disc->tracks.size() < 3) { + delete disc; + throw FlycastException("CUE parse error: less than 3 tracks"); + } disc->FillGDSession(); + } else { disc->type = CdRom_XA; diff --git a/core/rend/boxart/pvrparser.h b/core/rend/boxart/pvrparser.h index a4775fbc7..04590a6fd 100644 --- a/core/rend/boxart/pvrparser.h +++ b/core/rend/boxart/pvrparser.h @@ -45,6 +45,7 @@ static bool pvrParse(const u8 *data, u32 len, u32& width, u32& height, std::vect if (len < 16) return false; const u8 *p = data; + const u8 *end = data + len; if (!memcmp("GBIX", p, 4)) { p += 4; @@ -56,6 +57,10 @@ static bool pvrParse(const u8 *data, u32 len, u32& width, u32& height, std::vect WARN_LOG(COMMON, "Invalid PVR file: header not found"); return false; } + if (end - p < 16) { + WARN_LOG(COMMON, "Invalid PVR file: too small"); + return false; + } p += 4; u32 size = *(u32 *)p; p += 4; @@ -66,6 +71,10 @@ static bool pvrParse(const u8 *data, u32 len, u32& width, u32& height, std::vect p += 2; height = *(u16 *)p; p += 2; + if (width > 1024 || height > 1024) { + WARN_LOG(COMMON, "Invalid PVR file: wrong texture dimensions: %d x %d", width, height); + return false; + } ::vq_codebook = p; TexConvFP32 texConv; @@ -133,6 +142,19 @@ static bool pvrParse(const u8 *data, u32 len, u32& width, u32& height, std::vect else if (imgType == PvrVQMipmaps) p += VQMipPoint[texU]; + u32 expectedSize = width * height; + if (imgType == PvrVQ || imgType == PvrVQMipmaps) { + expectedSize /= 4; // 4 pixels per byte + expectedSize += 256 * 4 * 2; // VQ codebook size + } + else + expectedSize *= 2; // 2 bytes per pixel + if (end - p < expectedSize) + { + WARN_LOG(COMMON, "Invalid texture: expected %d bytes, %d remaining", expectedSize, (int)(end - p)); + return false; + } + PixelBuffer pb; pb.init(width, height); texConv(&pb, p, width, height); diff --git a/core/rend/boxart/scraper.cpp b/core/rend/boxart/scraper.cpp index 92c5e95e3..75df6afb8 100644 --- a/core/rend/boxart/scraper.cpp +++ b/core/rend/boxart/scraper.cpp @@ -115,6 +115,7 @@ void OfflineScraper::scrape(GameBoxart& item) item.scraped = true; item.uniqueId.clear(); item.searchName.clear(); + delete disc; return; }