scraper: skip invalid textures. invalid CUE crash. memory leak

Sanity check of PVR texture params before converting it to avoid crash
(MINIDUMP-K).
.cue gdrom needs at least 3 tracks.
Delete disc if invalid.
This commit is contained in:
Flyinghead 2022-12-25 11:27:48 +01:00
parent 96aaa8b14a
commit bfc44f2b4e
3 changed files with 29 additions and 0 deletions

View File

@ -211,7 +211,13 @@ Disc* cue_parse(const char* file, std::vector<u8> *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;

View File

@ -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<u32> pb;
pb.init(width, height);
texConv(&pb, p, width, height);

View File

@ -115,6 +115,7 @@ void OfflineScraper::scrape(GameBoxart& item)
item.scraped = true;
item.uniqueId.clear();
item.searchName.clear();
delete disc;
return;
}