From 4c082afe7117ba2ceee3f441a9dcd4b2f6f50d4c Mon Sep 17 00:00:00 2001 From: David Reid Date: Thu, 12 Mar 2026 06:08:27 +1000 Subject: [PATCH 1/4] Clarify usage of the decoder read callback. --- miniaudio.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/miniaudio.h b/miniaudio.h index c6d493ee..7f219a59 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -9974,7 +9974,19 @@ typedef struct } ma_decoding_backend_vtable; -typedef ma_result (* ma_decoder_read_proc)(ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead, size_t* pBytesRead); /* Returns the number of bytes read. */ +/* +The read callback should return MA_SUCCESS if more than zero bytes were successfully read. If zero +bytes can be read because it reached the end of the file, return MA_AT_END. If any other error +occurs just return any other error code (it's fine to just generically return MA_ERROR). + +Return the actual number of bytes read in `pBytesRead`. Important note: if the number of bytes +actually read is less than the number of bytes requested (bytesToRead), miniaudio will treat it as +if the end of the file has been reached and it will stop decoding. This becomes relevant for things +like streaming data sources, such as internet streams. If you haven't yet received `bytesToRead` +from the network, you need to have your callback wait for it and then only return when the full +number of bytes can be output, or when you've reached the genuine end of the stream. +*/ +typedef ma_result (* ma_decoder_read_proc)(ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead, size_t* pBytesRead); typedef ma_result (* ma_decoder_seek_proc)(ma_decoder* pDecoder, ma_int64 byteOffset, ma_seek_origin origin); typedef ma_result (* ma_decoder_tell_proc)(ma_decoder* pDecoder, ma_int64* pCursor); From 6922366bb141cd40d52eb18614af3c21eafd4c1a Mon Sep 17 00:00:00 2001 From: David Reid Date: Thu, 12 Mar 2026 06:14:00 +1000 Subject: [PATCH 2/4] Don't crash when a decoding seek callback is unavailable. --- miniaudio.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/miniaudio.h b/miniaudio.h index 7f219a59..2db19330 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -62865,6 +62865,10 @@ static ma_result ma_decoder_seek_bytes(ma_decoder* pDecoder, ma_int64 byteOffset { MA_ASSERT(pDecoder != NULL); + if (pDecoder->onSeek != NULL) { + return MA_NOT_IMPLEMENTED; + } + return pDecoder->onSeek(pDecoder, byteOffset, origin); } From 52d09d3688474394512b5c45c085d1fcbf6da57c Mon Sep 17 00:00:00 2001 From: David Reid Date: Thu, 12 Mar 2026 06:15:27 +1000 Subject: [PATCH 3/4] Enforce a read callback to be specified for decoders. --- miniaudio.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/miniaudio.h b/miniaudio.h index 2db19330..1d6f68bd 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -66237,6 +66237,11 @@ static ma_result ma_decoder__preinit(ma_decoder_read_proc onRead, ma_decoder_see MA_ZERO_OBJECT(pDecoder); + /* A read callback must be available. */ + if (onRead == NULL) { + return MA_INVALID_ARGS; + } + dataSourceConfig = ma_data_source_config_init(); dataSourceConfig.vtable = &g_ma_decoder_data_source_vtable; From 0041150de08c5f7852248463d026e39f15318421 Mon Sep 17 00:00:00 2001 From: David Reid Date: Thu, 12 Mar 2026 06:16:57 +1000 Subject: [PATCH 4/4] Update change history. --- CHANGES.md | 5 +++++ miniaudio.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2386d7d8..17b20b1a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +v0.11.26 - TBD +===================== +* Fixed a crash when passing in null for the read or seek callbacks for a decoder. + + v0.11.25 - 2026-03-04 ===================== * Bug fixes to the WAV decoder. diff --git a/miniaudio.h b/miniaudio.h index 1d6f68bd..0fd5c51c 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -1,6 +1,6 @@ /* Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. -miniaudio - v0.11.25 - 2026-03-04 +miniaudio - v0.11.26 - TBD David Reid - mackron@gmail.com @@ -3747,7 +3747,7 @@ extern "C" { #define MA_VERSION_MAJOR 0 #define MA_VERSION_MINOR 11 -#define MA_VERSION_REVISION 25 +#define MA_VERSION_REVISION 26 #define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION) #if defined(_MSC_VER) && !defined(__clang__)