Skip to content

Commit

Permalink
dep/libchdr: Correctness fixes for 9e5deb8
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Oct 30, 2024
1 parent 63330df commit 97f94f4
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 18 deletions.
42 changes: 24 additions & 18 deletions dep/libchdr/src/libchdr_chd.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,26 +715,28 @@ static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t
uint32_t framenum;
cdlz_codec_data* cdlz = (cdlz_codec_data*)codec;
chd_error decomp_err;
uint32_t complen_base;

/* determine header bytes */
const uint32_t frames = destlen / CD_FRAME_SIZE;
const uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
const uint32_t ecc_bytes = (frames + 7) / 8;
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 */
if ((ecc_bytes + 2) > complen)
/* input may be truncated, double-check */
if (complen < (ecc_bytes + 2))
return CHDERR_DECOMPRESSION_ERROR;

/* 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)
{
complen_base = (complen_base << 8) | src[ecc_bytes + 2];
if ((ecc_bytes + 3) > complen)
if (complen < (ecc_bytes + 3))
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;

/* reset and decode */
Expand Down Expand Up @@ -813,26 +815,28 @@ static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t
uint32_t framenum;
cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
chd_error decomp_err;
uint32_t complen_base;

/* determine header bytes */
const uint32_t frames = destlen / CD_FRAME_SIZE;
const uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
const uint32_t ecc_bytes = (frames + 7) / 8;
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 */
if ((ecc_bytes + 2) > complen)
/* input may be truncated, double-check */
if (complen < (ecc_bytes + 2))
return CHDERR_DECOMPRESSION_ERROR;

/* 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)
{
complen_base = (complen_base << 8) | src[ecc_bytes + 2];
if ((ecc_bytes + 3) > complen)
if (complen < (ecc_bytes + 3))
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;

/* reset and decode */
Expand Down Expand Up @@ -1188,26 +1192,28 @@ static chd_error cdzs_codec_decompress(void *codec, const uint8_t *src, uint32_t
uint32_t framenum;
cdzs_codec_data* cdzs = (cdzs_codec_data*)codec;
chd_error decomp_err;
uint32_t complen_base;

/* determine header bytes */
const uint32_t frames = destlen / CD_FRAME_SIZE;
const uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
const uint32_t ecc_bytes = (frames + 7) / 8;
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 */
if ((ecc_bytes + 2) > complen)
/* input may be truncated, double-check */
if (complen < (ecc_bytes + 2))
return CHDERR_DECOMPRESSION_ERROR;

/* 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)
{
complen_base = (complen_base << 8) | src[ecc_bytes + 2];
if ((ecc_bytes + 3) > complen)
if (complen < (ecc_bytes + 3))
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;

/* reset and decode */
Expand Down
5 changes: 5 additions & 0 deletions dep/libchdr/src/link.T
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
global: chd_*;
local: *;
};

0 comments on commit 97f94f4

Please sign in to comment.