From 09b02e6d5cc95a8e46a8e12c27073cecf60394ae Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Tue, 9 Dec 2025 04:49:15 +0300
Subject: [PATCH] update to latest dr_flac.h and dr_mp3.h from mainstream
---
src/codecs/dr_libs/dr_flac.h | 68 ++++++++++++++----------------------
src/codecs/dr_libs/dr_mp3.h | 37 +++++++++++---------
2 files changed, 48 insertions(+), 57 deletions(-)
diff --git a/src/codecs/dr_libs/dr_flac.h b/src/codecs/dr_libs/dr_flac.h
index ff0a1306..c36c5515 100644
--- a/src/codecs/dr_libs/dr_flac.h
+++ b/src/codecs/dr_libs/dr_flac.h
@@ -2732,7 +2732,7 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
return r;
}
- #elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !defined(DRFLAC_64BIT) /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */
+ #elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !(defined(__thumb__) && !defined(__thumb2__)) && !defined(DRFLAC_64BIT) /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */
{
unsigned int r;
__asm__ __volatile__ (
@@ -11798,58 +11798,43 @@ static type* drflac__full_read_and_close_ ## extension (drflac* pFlac, unsigned
{ \
type* pSampleData = NULL; \
drflac_uint64 totalPCMFrameCount; \
+ type buffer[4096]; \
+ drflac_uint64 pcmFramesRead; \
+ size_t sampleDataBufferSize = sizeof(buffer); \
\
DRFLAC_ASSERT(pFlac != NULL); \
\
- totalPCMFrameCount = pFlac->totalPCMFrameCount; \
+ totalPCMFrameCount = 0; \
\
- if (totalPCMFrameCount == 0) { \
- type buffer[4096]; \
- drflac_uint64 pcmFramesRead; \
- size_t sampleDataBufferSize = sizeof(buffer); \
- \
- pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks); \
- if (pSampleData == NULL) { \
- goto on_error; \
- } \
- \
- while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \
- if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \
- type* pNewSampleData; \
- size_t newSampleDataBufferSize; \
+ pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks); \
+ if (pSampleData == NULL) { \
+ goto on_error; \
+ } \
\
- newSampleDataBufferSize = sampleDataBufferSize * 2; \
- pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \
- if (pNewSampleData == NULL) { \
- drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks); \
- goto on_error; \
- } \
+ while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \
+ if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \
+ type* pNewSampleData; \
+ size_t newSampleDataBufferSize; \
\
- sampleDataBufferSize = newSampleDataBufferSize; \
- pSampleData = pNewSampleData; \
+ newSampleDataBufferSize = sampleDataBufferSize * 2; \
+ pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \
+ if (pNewSampleData == NULL) { \
+ drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks); \
+ goto on_error; \
} \
\
- DRFLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \
- totalPCMFrameCount += pcmFramesRead; \
+ sampleDataBufferSize = newSampleDataBufferSize; \
+ pSampleData = pNewSampleData; \
} \
\
- /* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to \
- protect those ears from random noise! */ \
- DRFLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \
- } else { \
- drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type); \
- if (dataSize > (drflac_uint64)DRFLAC_SIZE_MAX) { \
- goto on_error; /* The decoded data is too big. */ \
- } \
- \
- pSampleData = (type*)drflac__malloc_from_callbacks((size_t)dataSize, &pFlac->allocationCallbacks); /* <-- Safe cast as per the check above. */ \
- if (pSampleData == NULL) { \
- goto on_error; \
- } \
- \
- totalPCMFrameCount = drflac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData); \
+ DRFLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \
+ totalPCMFrameCount += pcmFramesRead; \
} \
\
+ /* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to \
+ protect those ears from random noise! */ \
+ DRFLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \
+ \
if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; \
if (channelsOut) *channelsOut = pFlac->channels; \
if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount; \
@@ -12176,6 +12161,7 @@ REVISION HISTORY
v0.13.2 - TBD
- Improve robustness of the parsing of picture metadata to improve support for memory constrained embedded devices.
- Fix a warning about an assigned by unused variable.
+ - Improvements to drflac_open_and_read_pcm_frames_*() and family to avoid excessively large memory allocations from malformed files.
v0.13.1 - 2025-09-10
- Fix an error with the NXDK build.
diff --git a/src/codecs/dr_libs/dr_mp3.h b/src/codecs/dr_libs/dr_mp3.h
index 3617b6b6..a1e157f9 100644
--- a/src/codecs/dr_libs/dr_mp3.h
+++ b/src/codecs/dr_libs/dr_mp3.h
@@ -1234,7 +1234,7 @@ static float drmp3_L3_ldexp_q2(float y, int exp_q2)
I've had reports of GCC 14 throwing an incorrect -Wstringop-overflow warning here. This is an attempt
to silence this warning.
*/
-#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__)
+#if (defined(__GNUC__) && (__GNUC__ >= 13)) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
@@ -1299,7 +1299,7 @@ static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *is
scf[i] = drmp3_L3_ldexp_q2(gain, iscf[i] << scf_shift);
}
}
-#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__)
+#if (defined(__GNUC__) && (__GNUC__ >= 13)) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
@@ -3018,23 +3018,27 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
((drmp3_uint32)ape[26] << 16) |
((drmp3_uint32)ape[27] << 24);
- streamEndOffset -= 32 + tagSize;
- streamLen -= 32 + tagSize;
-
- /* Fire a metadata callback for the APE data. Must include both the main content and footer. */
- if (onMeta != NULL) {
- /* We first need to seek to the start of the APE tag. */
- if (onSeek(pUserData, streamEndOffset, DRMP3_SEEK_END)) {
- size_t apeTagSize = (size_t)tagSize + 32;
- drmp3_uint8* pTagData = (drmp3_uint8*)drmp3_malloc(apeTagSize, pAllocationCallbacks);
- if (pTagData != NULL) {
- if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) {
- drmp3__on_meta(pMP3, DRMP3_METADATA_TYPE_APE, pTagData, apeTagSize);
+ if (32 + tagSize < streamLen) {
+ streamEndOffset -= 32 + tagSize;
+ streamLen -= 32 + tagSize;
+
+ /* Fire a metadata callback for the APE data. Must include both the main content and footer. */
+ if (onMeta != NULL) {
+ /* We first need to seek to the start of the APE tag. */
+ if (onSeek(pUserData, streamEndOffset, DRMP3_SEEK_END)) {
+ size_t apeTagSize = (size_t)tagSize + 32;
+ drmp3_uint8* pTagData = (drmp3_uint8*)drmp3_malloc(apeTagSize, pAllocationCallbacks);
+ if (pTagData != NULL) {
+ if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) {
+ drmp3__on_meta(pMP3, DRMP3_METADATA_TYPE_APE, pTagData, apeTagSize);
+ }
+
+ drmp3_free(pTagData, pAllocationCallbacks);
}
-
- drmp3_free(pTagData, pAllocationCallbacks);
}
}
+ } else {
+ /* The tag size is larger than the stream. Invalid APE tag. */
}
}
}
@@ -5004,6 +5008,7 @@ REVISION HISTORY
v0.7.2 - TBD
- Reduce stack space to improve robustness on embedded systems.
- Fix a compilation error with MSVC Clang toolset relating to cpuid.
+ - Fix an error with APE tag parsing.
v0.7.1 - 2025-09-10
- Silence a warning with GCC.