dep/libchdr: Fix handling of duplicate codecs

This commit is contained in:
Stenzek 2024-11-07 22:48:05 +10:00
parent c461ad7b44
commit 2d22409d2e
No known key found for this signature in database
1 changed files with 31 additions and 10 deletions

View File

@ -1979,22 +1979,16 @@ CHD_EXPORT chd_error chd_open_core_file(core_file *file, int mode, chd_file *par
} }
else else
{ {
int decompnum; int decompnum, needsinit;
/* verify the compression types and initialize the codecs */ /* verify the compression types and initialize the codecs */
for (decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++) for (decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++)
{ {
int i, j; int i;
for (i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++) for (i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++)
{ {
if (codec_interfaces[i].compression == newchd->header.compression[decompnum]) if (codec_interfaces[i].compression == newchd->header.compression[decompnum])
{ {
/* ensure we don't try to initialize the same codec twice */
for (j = 0; j < decompnum; j++)
{
if (newchd->codecintf[j] == &codec_interfaces[i])
EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
}
newchd->codecintf[decompnum] = &codec_interfaces[i]; newchd->codecintf[decompnum] = &codec_interfaces[i];
break; break;
} }
@ -2003,8 +1997,21 @@ CHD_EXPORT chd_error chd_open_core_file(core_file *file, int mode, chd_file *par
if (newchd->codecintf[decompnum] == NULL && newchd->header.compression[decompnum] != 0) if (newchd->codecintf[decompnum] == NULL && newchd->header.compression[decompnum] != 0)
EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT); EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
/* ensure we don't try to initialize the same codec twice */
/* this is "normal" for chds where the user overrides the codecs, it'll have none repeated */
needsinit = (newchd->codecintf[decompnum]->init != NULL);
for (i = 0; i < decompnum; i++)
{
if (newchd->codecintf[decompnum] == newchd->codecintf[i])
{
/* already initialized */
needsinit = 0;
break;
}
}
/* initialize the codec */ /* initialize the codec */
if (newchd->codecintf[decompnum]->init != NULL) if (needsinit)
{ {
void* codec = NULL; void* codec = NULL;
switch (newchd->header.compression[decompnum]) switch (newchd->header.compression[decompnum])
@ -2189,10 +2196,24 @@ CHD_EXPORT void chd_close(chd_file *chd)
for (i = 0 ; i < ARRAY_LENGTH(chd->codecintf); i++) for (i = 0 ; i < ARRAY_LENGTH(chd->codecintf); i++)
{ {
void* codec = NULL; void* codec = NULL;
int j, needsfree;
if (chd->codecintf[i] == NULL) if (chd->codecintf[i] == NULL)
continue; continue;
/* only free each codec at max once */
needsfree = 1;
for (j = 0; j < i; j++)
{
if (chd->codecintf[i] == chd->codecintf[j])
{
needsfree = 0;
break;
}
}
if (!needsfree)
continue;
switch (chd->codecintf[i]->compression) switch (chd->codecintf[i]->compression)
{ {
case CHD_CODEC_ZLIB: case CHD_CODEC_ZLIB: