dep/libchdr: Correctness fixes for 9e5deb8

This commit is contained in:
Stenzek 2024-10-30 15:04:42 +10:00
parent 5518199206
commit 65d7f3bf2d
No known key found for this signature in database
2 changed files with 29 additions and 18 deletions

View File

@ -715,6 +715,7 @@ static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t
uint32_t framenum; uint32_t framenum;
cdlz_codec_data* cdlz = (cdlz_codec_data*)codec; cdlz_codec_data* cdlz = (cdlz_codec_data*)codec;
chd_error decomp_err; chd_error decomp_err;
uint32_t complen_base;
/* determine header bytes */ /* determine header bytes */
const uint32_t frames = destlen / CD_FRAME_SIZE; const uint32_t frames = destlen / CD_FRAME_SIZE;
@ -722,19 +723,20 @@ static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t
const uint32_t ecc_bytes = (frames + 7) / 8; const uint32_t ecc_bytes = (frames + 7) / 8;
const uint32_t header_bytes = ecc_bytes + complen_bytes; const uint32_t header_bytes = ecc_bytes + complen_bytes;
/* input may be truncated, double-check. both bytes, plus at least one input byte, or the third */ /* input may be truncated, double-check */
if ((ecc_bytes + 2) > complen) if (complen < (ecc_bytes + 2))
return CHDERR_DECOMPRESSION_ERROR; return CHDERR_DECOMPRESSION_ERROR;
/* extract compressed length of base */ /* extract compressed length of base */
uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1]; complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
if (complen_bytes > 2) if (complen_bytes > 2)
{ {
complen_base = (complen_base << 8) | src[ecc_bytes + 2]; if (complen < (ecc_bytes + 3))
if ((ecc_bytes + 3) > complen)
return CHDERR_DECOMPRESSION_ERROR; return CHDERR_DECOMPRESSION_ERROR;
complen_base = (complen_base << 8) | src[ecc_bytes + 2];
} }
if ((header_bytes + complen_base) > complen) if (complen < (header_bytes + complen_base))
return CHDERR_DECOMPRESSION_ERROR; return CHDERR_DECOMPRESSION_ERROR;
/* reset and decode */ /* reset and decode */
@ -813,6 +815,7 @@ static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t
uint32_t framenum; uint32_t framenum;
cdzl_codec_data* cdzl = (cdzl_codec_data*)codec; cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
chd_error decomp_err; chd_error decomp_err;
uint32_t complen_base;
/* determine header bytes */ /* determine header bytes */
const uint32_t frames = destlen / CD_FRAME_SIZE; const uint32_t frames = destlen / CD_FRAME_SIZE;
@ -820,19 +823,20 @@ static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t
const uint32_t ecc_bytes = (frames + 7) / 8; const uint32_t ecc_bytes = (frames + 7) / 8;
const uint32_t header_bytes = ecc_bytes + complen_bytes; const uint32_t header_bytes = ecc_bytes + complen_bytes;
/* input may be truncated, double-check. both bytes, plus at least one input byte, or the third */ /* input may be truncated, double-check */
if ((ecc_bytes + 2) > complen) if (complen < (ecc_bytes + 2))
return CHDERR_DECOMPRESSION_ERROR; return CHDERR_DECOMPRESSION_ERROR;
/* extract compressed length of base */ /* extract compressed length of base */
uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1]; complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
if (complen_bytes > 2) if (complen_bytes > 2)
{ {
complen_base = (complen_base << 8) | src[ecc_bytes + 2]; if (complen < (ecc_bytes + 3))
if ((ecc_bytes + 3) > complen)
return CHDERR_DECOMPRESSION_ERROR; return CHDERR_DECOMPRESSION_ERROR;
complen_base = (complen_base << 8) | src[ecc_bytes + 2];
} }
if ((header_bytes + complen_base) > complen) if (complen < (header_bytes + complen_base))
return CHDERR_DECOMPRESSION_ERROR; return CHDERR_DECOMPRESSION_ERROR;
/* reset and decode */ /* reset and decode */
@ -1188,6 +1192,7 @@ static chd_error cdzs_codec_decompress(void *codec, const uint8_t *src, uint32_t
uint32_t framenum; uint32_t framenum;
cdzs_codec_data* cdzs = (cdzs_codec_data*)codec; cdzs_codec_data* cdzs = (cdzs_codec_data*)codec;
chd_error decomp_err; chd_error decomp_err;
uint32_t complen_base;
/* determine header bytes */ /* determine header bytes */
const uint32_t frames = destlen / CD_FRAME_SIZE; const uint32_t frames = destlen / CD_FRAME_SIZE;
@ -1195,19 +1200,20 @@ static chd_error cdzs_codec_decompress(void *codec, const uint8_t *src, uint32_t
const uint32_t ecc_bytes = (frames + 7) / 8; const uint32_t ecc_bytes = (frames + 7) / 8;
const uint32_t header_bytes = ecc_bytes + complen_bytes; const uint32_t header_bytes = ecc_bytes + complen_bytes;
/* input may be truncated, double-check. both bytes, plus at least one input byte, or the third */ /* input may be truncated, double-check */
if ((ecc_bytes + 2) > complen) if (complen < (ecc_bytes + 2))
return CHDERR_DECOMPRESSION_ERROR; return CHDERR_DECOMPRESSION_ERROR;
/* extract compressed length of base */ /* extract compressed length of base */
uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1]; complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
if (complen_bytes > 2) if (complen_bytes > 2)
{ {
complen_base = (complen_base << 8) | src[ecc_bytes + 2]; if (complen < (ecc_bytes + 3))
if ((ecc_bytes + 3) > complen)
return CHDERR_DECOMPRESSION_ERROR; return CHDERR_DECOMPRESSION_ERROR;
complen_base = (complen_base << 8) | src[ecc_bytes + 2];
} }
if ((header_bytes + complen_base) > complen) if (complen < (header_bytes + complen_base))
return CHDERR_DECOMPRESSION_ERROR; return CHDERR_DECOMPRESSION_ERROR;
/* reset and decode */ /* reset and decode */

5
dep/libchdr/src/link.T Normal file
View File

@ -0,0 +1,5 @@
{
global: chd_*;
local: *;
};