diff --git a/extras/dr_flac.h b/extras/dr_flac.h index a7527763..60c8693f 100644 --- a/extras/dr_flac.h +++ b/extras/dr_flac.h @@ -1,6 +1,6 @@ /* FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_flac - v0.12.9 - 2020-04-05 +dr_flac - v0.12.10 - 2020-04-10 David Reid - mackron@gmail.com @@ -5879,6 +5879,14 @@ static drflac_bool32 drflac__seek_to_pcm_frame__seek_table(drflac* pFlac, drflac iClosestSeekpoint = iSeekpoint; } + /* There's been cases where the seek table contains only zeros. We need to do some basic validation on the closest seekpoint. */ + if (pFlac->pSeekpoints[iClosestSeekpoint].pcmFrameCount == 0 || pFlac->pSeekpoints[iClosestSeekpoint].pcmFrameCount > pFlac->maxBlockSizeInPCMFrames) { + return DRFLAC_FALSE; + } + if (pFlac->pSeekpoints[iClosestSeekpoint].firstPCMFrame > pFlac->totalPCMFrameCount && pFlac->totalPCMFrameCount > 0) { + return DRFLAC_FALSE; + } + #if !defined(DR_FLAC_NO_CRC) /* At this point we should know the closest seek point. We can use a binary search for this. We need to know the total sample count for this. */ if (pFlac->totalPCMFrameCount > 0) { @@ -5888,9 +5896,23 @@ static drflac_bool32 drflac__seek_to_pcm_frame__seek_table(drflac* pFlac, drflac byteRangeHi = pFlac->firstFLACFramePosInBytes + (drflac_uint64)((drflac_int64)(pFlac->totalPCMFrameCount * pFlac->channels * pFlac->bitsPerSample)/8.0f); byteRangeLo = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset; + /* + If our closest seek point is not the last one, we only need to search between it and the next one. The section below calculates an appropriate starting + value for byteRangeHi which will clamp it appropriately. + + Note that the next seekpoint must have an offset greater than the closest seekpoint because otherwise our binary search algorithm will break down. There + have been cases where a seektable consists of seek points where every byte offset is set to 0 which causes problems. If this happens we need to abort. + */ if (iClosestSeekpoint < pFlac->seekpointCount-1) { - if (pFlac->pSeekpoints[iClosestSeekpoint+1].firstPCMFrame != (((drflac_uint64)0xFFFFFFFF << 32) | 0xFFFFFFFF)) { /* Is it a placeholder seekpoint. */ - byteRangeHi = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iClosestSeekpoint+1].flacFrameOffset-1; /* Must be zero based. */ + drflac_uint32 iNextSeekpoint = iClosestSeekpoint + 1; + + /* Basic validation on the seekpoints to ensure they're usable. */ + if (pFlac->pSeekpoints[iClosestSeekpoint].flacFrameOffset >= pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset || pFlac->pSeekpoints[iNextSeekpoint].pcmFrameCount == 0) { + return DRFLAC_FALSE; /* The next seekpoint doesn't look right. The seek table cannot be trusted from here. Abort. */ + } + + if (pFlac->pSeekpoints[iNextSeekpoint].firstPCMFrame != (((drflac_uint64)0xFFFFFFFF << 32) | 0xFFFFFFFF)) { /* Make sure it's not a placeholder seekpoint. */ + byteRangeHi = pFlac->firstFLACFramePosInBytes + pFlac->pSeekpoints[iNextSeekpoint].flacFrameOffset - 1; /* byteRangeHi must be zero based. */ } } @@ -11692,6 +11714,9 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat /* REVISION HISTORY ================ +v0.12.10 - 2020-04-10 + - Fix some bugs when trying to seek with an invalid seek table. + v0.12.9 - 2020-04-05 - Fix warnings. diff --git a/extras/dr_mp3.h b/extras/dr_mp3.h index 6836b1e6..a9dfac34 100644 --- a/extras/dr_mp3.h +++ b/extras/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.1 - 2020-04-05 +dr_mp3 - v0.6.2 - 2020-04-10 David Reid - mackron@gmail.com @@ -4050,9 +4050,6 @@ static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, DRMP3_ASSERT(pMP3 != NULL); - pConfig->channels = pMP3->channels; - pConfig->sampleRate = pMP3->sampleRate; - for (;;) { drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels; drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp); @@ -4098,7 +4095,7 @@ static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, } if (pConfig != NULL) { - pConfig->channels = pMP3->channels; + pConfig->channels = pMP3->channels; pConfig->sampleRate = pMP3->sampleRate; } @@ -4120,9 +4117,6 @@ static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pC DRMP3_ASSERT(pMP3 != NULL); - pConfig->channels = pMP3->channels; - pConfig->sampleRate = pMP3->sampleRate; - for (;;) { drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels; drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp); @@ -4168,7 +4162,7 @@ static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pC } if (pConfig != NULL) { - pConfig->channels = pMP3->channels; + pConfig->channels = pMP3->channels; pConfig->sampleRate = pMP3->sampleRate; } @@ -4349,6 +4343,9 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.2 - 2020-04-10 + - Fix a crash in drmp3_open_*_and_read_pcm_frames_*() if the output config object is NULL. + v0.6.1 - 2020-04-05 - Fix warnings.