UPDATE: Harden bink2 bridge (#385)

fix stride overflow, check decode return values, null movie on open failure
This commit is contained in:
Granthik
2026-07-18 16:19:59 +05:30
committed by GitHub
parent f84d869795
commit 01b80fe381
+19 -4
View File
@@ -5,7 +5,6 @@
* Build this small adapter with a licensed RAD Bink 2 SDK. The SDK and its * Build this small adapter with a licensed RAD Bink 2 SDK. The SDK and its
* headers are not distributed by SharpEmu. See docs/bink2-bridge.md. * headers are not distributed by SharpEmu. See docs/bink2-bridge.md.
*/ */
#include <stdint.h> #include <stdint.h>
#include "bink.h" #include "bink.h"
@@ -20,9 +19,16 @@ int sharpemu_bink2_open_utf8(const char *path, HBINK *movie, sharpemu_bink2_info
HBINK bink; HBINK bink;
if (!path || !movie || !info) return 0; if (!path || !movie || !info) return 0;
*movie = NULL;
bink = BinkOpen(path, 0); bink = BinkOpen(path, 0);
if (!bink) return 0; if (!bink) return 0;
if (bink->Width == 0 || bink->Height == 0) {
BinkClose(bink);
return 0;
}
*movie = bink; *movie = bink;
info->width = bink->Width; info->width = bink->Width;
info->height = bink->Height; info->height = bink->Height;
@@ -34,14 +40,23 @@ int sharpemu_bink2_open_utf8(const char *path, HBINK *movie, sharpemu_bink2_info
int sharpemu_bink2_decode_next_bgra(HBINK movie, uint8_t *destination, int sharpemu_bink2_decode_next_bgra(HBINK movie, uint8_t *destination,
uint32_t stride, uint32_t destination_bytes) { uint32_t stride, uint32_t destination_bytes) {
uint64_t needed; uint64_t needed;
if (!movie || !destination || stride < movie->Width * 4) return 0; uint64_t min_stride;
if (!movie || !destination) return 0;
min_stride = (uint64_t)movie->Width * 4;
if ((uint64_t)stride < min_stride) return 0;
needed = (uint64_t)stride * movie->Height; needed = (uint64_t)stride * movie->Height;
if (needed > destination_bytes) return 0; if (needed > destination_bytes) return 0;
/* Async Bink I/O has not filled the next frame yet; retry on the next host present. */ /* Async Bink I/O has not filled the next frame yet; retry on the next host present. */
if (BinkWait(movie)) return 0; if (BinkWait(movie)) return 0;
BinkDoFrame(movie);
BinkCopyToBuffer(movie, destination, stride, movie->Height, 0, 0, BINKSURFACE32RA); if (!BinkDoFrame(movie)) return 0;
if (!BinkCopyToBuffer(movie, destination, stride, movie->Height, 0, 0, BINKSURFACE32RA)) return 0;
BinkNextFrame(movie); BinkNextFrame(movie);
return 1; return 1;
} }