diff --git a/include/mgba/core/serialize.h b/include/mgba/core/serialize.h index 59ca1c19f..ee9de69a1 100644 --- a/include/mgba/core/serialize.h +++ b/include/mgba/core/serialize.h @@ -16,6 +16,7 @@ enum mStateExtdataTag { EXTDATA_SAVEDATA = 2, EXTDATA_CHEATS = 3, EXTDATA_RTC = 4, + EXTDATA_SCREENSHOT_DIMENSIONS = 5, EXTDATA_META_TIME = 0x101, EXTDATA_META_CREATOR = 0x102, EXTDATA_MAX diff --git a/src/core/serialize.c b/src/core/serialize.c index c562d97e0..53e0aa168 100644 --- a/src/core/serialize.c +++ b/src/core/serialize.c @@ -262,8 +262,18 @@ static void* _loadPNGState(struct mCore* core, struct VFile* vf, struct mStateEx PNGReadClose(png, info, end); return false; } - unsigned width, height; - core->desiredVideoDimensions(core, &width, &height); + + if (!PNGReadHeader(png, info)) { + PNGReadClose(png, info, end); + return false; + } + unsigned width = png_get_image_width(png, info); + unsigned height = png_get_image_height(png, info); + if (width > 0x4000 || height > 0x4000) { + // These images are ridiculously large...let's assume a DOS attempt and reject + PNGReadClose(png, info, end); + return false; + } uint32_t* pixels = malloc(width * height * 4); if (!pixels) { PNGReadClose(png, info, end); @@ -278,8 +288,8 @@ static void* _loadPNGState(struct mCore* core, struct VFile* vf, struct mStateEx .extdata = extdata }; + bool success = true; PNGInstallChunkHandler(png, &bundle, _loadPNGChunkHandler, "gbAs gbAx"); - bool success = PNGReadHeader(png, info); success = success && PNGReadPixels(png, info, pixels, width, height, width); success = success && PNGReadFooter(png, end); PNGReadClose(png, info, end); @@ -295,6 +305,12 @@ static void* _loadPNGState(struct mCore* core, struct VFile* vf, struct mStateEx .clean = free }; mStateExtdataPut(extdata, EXTDATA_SCREENSHOT, &item); + + uint16_t dims[2] = { width, height }; + item.size = sizeof(dims); + item.data = malloc(item.size); + memcpy(item.data, dims, item.size); + mStateExtdataPut(extdata, EXTDATA_SCREENSHOT_DIMENSIONS, &item); } else { free(pixels); }