From 9bda0379af08b44450754b9b41ff25bf983b0339 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 16 Jul 2020 12:49:01 +0200 Subject: [PATCH 01/33] increment version number to 0.21.26 --- NEWS | 2 ++ android/AndroidManifest.xml | 4 ++-- doc/conf.py | 2 +- meson.build | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index e831815b5..94c2cf2e3 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +ver 0.21.26 (not yet released) + ver 0.21.25 (2020/07/06) * protocol: - fix crash when using "rangeid" while playing diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index e2a31db83..746a2490f 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="49" + android:versionName="0.21.26"> diff --git a/doc/conf.py b/doc/conf.py index 4c3b663fa..b271647ad 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -38,7 +38,7 @@ author = 'Max Kellermann' # built documents. # # The short X.Y version. -version = '0.21.25' +version = '0.21.26' # The full version, including alpha/beta/rc tags. release = version diff --git a/meson.build b/meson.build index c1e6b1322..ae3ba2909 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'mpd', ['c', 'cpp'], - version: '0.21.25', + version: '0.21.26', meson_version: '>= 0.49.0', default_options: [ 'c_std=c99', From cf674e92730b1b37b39e16ed936356aa170455f0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 16 Jul 2020 12:55:04 +0200 Subject: [PATCH 02/33] input/Init: downgrade PluginUnconfigured to LogLevel::DEBUG `LogLevel::INFO` is logged by default, but this message shall only appear with `--verbose`. This finally solves https://github.com/MusicPlayerDaemon/MPD/issues/430 --- src/input/Init.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/Init.cxx b/src/input/Init.cxx index e944ff697..3d1c8f2ed 100644 --- a/src/input/Init.cxx +++ b/src/input/Init.cxx @@ -59,7 +59,7 @@ input_stream_global_init(const ConfigData &config, EventLoop &event_loop) plugin->init(event_loop, *block); input_plugins_enabled[i] = true; } catch (const PluginUnconfigured &e) { - LogFormat(LogLevel::INFO, e, + LogFormat(LogLevel::DEBUG, e, "Input plugin '%s' is not configured", plugin->name); continue; From 6c40d2a65647bcd04f07d8a8cc86f3819c5601cc Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 20 Jul 2020 12:32:02 +0200 Subject: [PATCH 03/33] python/build/libs.py: update libmpdclient to 2.19 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index e211a0107..d4c809232 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -10,8 +10,8 @@ from build.ffmpeg import FfmpegProject from build.boost import BoostProject libmpdclient = MesonProject( - 'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.18.tar.xz', - '4cb01e1f567e0169aca94875fb6e1200e7f5ce35b63a4df768ec1591fb1081fa', + 'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.19.tar.xz', + '158aad4c2278ab08e76a3f2b0166c99b39fae00ee17231bd225c5a36e977a189', 'lib/libmpdclient.a', ) From 64e8abf203893c97cf7ecd94dda8c8dddcc56310 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 20 Jul 2020 12:34:12 +0200 Subject: [PATCH 04/33] python/build/libs.py: update libvorbis to 1.3.7 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index d4c809232..67e4e72e4 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -25,8 +25,8 @@ libogg = AutotoolsProject( ) libvorbis = AutotoolsProject( - 'http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.6.tar.xz', - 'af00bb5a784e7c9e69f56823de4637c350643deedaf333d0fa86ecdba6fcb415', + 'http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.xz', + 'b33cc4934322bcbf6efcbacf49e3ca01aadbea4114ec9589d1b1e9d20f72954b', 'lib/libvorbis.a', [ '--disable-shared', '--enable-static', From 587c0f6232e21d71b53c5ab7eec87b431bb1c70e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 20 Jul 2020 12:37:15 +0200 Subject: [PATCH 05/33] python/build/libs.py: update FFmpeg to 4.3.1 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index 67e4e72e4..afeefa51a 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -148,8 +148,8 @@ gme = CmakeProject( ) ffmpeg = FfmpegProject( - 'http://ffmpeg.org/releases/ffmpeg-4.2.3.tar.xz', - '9df6c90aed1337634c1fb026fb01c154c29c82a64ea71291ff2da9aacb9aad31', + 'http://ffmpeg.org/releases/ffmpeg-4.3.1.tar.xz', + 'ad009240d46e307b4e03a213a0f49c11b650e445b1f8be0dda2a9212b34d2ffb', 'lib/libavcodec.a', [ '--disable-shared', '--enable-static', From 77c2efe17112899bc4dff8ea8a37c6c4a4da992e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 20 Jul 2020 12:37:53 +0200 Subject: [PATCH 06/33] python/build/libs.py: update CURL to 7.71.1 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index afeefa51a..d5403b7a9 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -377,8 +377,8 @@ ffmpeg = FfmpegProject( ) curl = AutotoolsProject( - 'http://curl.haxx.se/download/curl-7.70.0.tar.xz', - '032f43f2674008c761af19bf536374128c16241fb234699a55f9fb603fcfbae7', + 'http://curl.haxx.se/download/curl-7.71.1.tar.xz', + '40f83eda27cdbeb25cd4da48cefb639af1b9395d6026d2da1825bf059239658c', 'lib/libcurl.a', [ '--disable-shared', '--enable-static', From 64a1386eb652f5c34572fafc88b5fae9ac5a849d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 20 Jul 2020 14:41:06 +0200 Subject: [PATCH 07/33] output/sles: move SampleFormat selection to switch/case block --- src/output/plugins/sles/SlesOutputPlugin.cxx | 22 +++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/output/plugins/sles/SlesOutputPlugin.cxx b/src/output/plugins/sles/SlesOutputPlugin.cxx index 09968559d..b2e1b311d 100644 --- a/src/output/plugins/sles/SlesOutputPlugin.cxx +++ b/src/output/plugins/sles/SlesOutputPlugin.cxx @@ -188,6 +188,25 @@ SlesOutput::Open(AudioFormat &audio_format) ? SL_BYTEORDER_LITTLEENDIAN : SL_BYTEORDER_BIGENDIAN; + switch (audio_format.format) { + /* note: Android doesn't support + SL_PCMSAMPLEFORMAT_FIXED_24 and + SL_PCMSAMPLEFORMAT_FIXED_32, so let's not bother + implement it here; SL_PCMSAMPLEFORMAT_FIXED_8 + appears to be unsigned, so not usable for us (and + converting S8 to U8 is not worth the trouble) */ + + case SampleFormat::S16: + /* bitsPerSample and containerSize already set for 16 + bit */ + break; + + default: + /* fall back to 16 bit */ + audio_format.format = SampleFormat::S16; + break; + } + SLDataSource audioSrc = { &loc_bufq, &format_pcm }; SLDataLocator_OutputMix loc_outmix = { @@ -291,9 +310,6 @@ SlesOutput::Open(AudioFormat &audio_format) n_queued = 0; next = 0; filled = 0; - - // TODO: support other sample formats - audio_format.format = SampleFormat::S16; } void From 448b397cb840b1f0d796892807e77ef8fe7d620a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 20 Jul 2020 14:46:24 +0200 Subject: [PATCH 08/33] output/sles: support floating point samples According to https://developer.android.com/ndk/guides/audio/opensl/android-extensions This feature was mentioned in https://github.com/MusicPlayerDaemon/MPD/issues/922 --- NEWS | 2 ++ src/output/plugins/sles/SlesOutputPlugin.cxx | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 94c2cf2e3..b698d4f5f 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.21.26 (not yet released) +* output + - sles: support floating point samples ver 0.21.25 (2020/07/06) * protocol: diff --git a/src/output/plugins/sles/SlesOutputPlugin.cxx b/src/output/plugins/sles/SlesOutputPlugin.cxx index b2e1b311d..bf1d2154a 100644 --- a/src/output/plugins/sles/SlesOutputPlugin.cxx +++ b/src/output/plugins/sles/SlesOutputPlugin.cxx @@ -173,12 +173,12 @@ SlesOutput::Open(AudioFormat &audio_format) if (audio_format.channels > 2) audio_format.channels = 1; - SLDataFormat_PCM format_pcm; + SLAndroidDataFormat_PCM_EX format_pcm; format_pcm.formatType = SL_DATAFORMAT_PCM; format_pcm.numChannels = audio_format.channels; /* from the Android NDK docs: "Note that the field samplesPerSec is actually in units of milliHz, despite the misleading name." */ - format_pcm.samplesPerSec = audio_format.sample_rate * 1000u; + format_pcm.sampleRate = audio_format.sample_rate * 1000u; format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; format_pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16; format_pcm.channelMask = audio_format.channels == 1 @@ -187,6 +187,7 @@ SlesOutput::Open(AudioFormat &audio_format) format_pcm.endianness = IsLittleEndian() ? SL_BYTEORDER_LITTLEENDIAN : SL_BYTEORDER_BIGENDIAN; + format_pcm.representation = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT; switch (audio_format.format) { /* note: Android doesn't support @@ -201,6 +202,16 @@ SlesOutput::Open(AudioFormat &audio_format) bit */ break; + case SampleFormat::FLOAT: + /* Android has an OpenSLES extension for floating + point samples: + https://developer.android.com/ndk/guides/audio/opensl/android-extensions */ + format_pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX; + format_pcm.bitsPerSample = format_pcm.containerSize = + SL_PCMSAMPLEFORMAT_FIXED_32; + format_pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT; + break; + default: /* fall back to 16 bit */ audio_format.format = SampleFormat::S16; From 3a08a6ad727852a236b5c2fc66ebeb8845519761 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 20 Jul 2020 15:27:40 +0200 Subject: [PATCH 09/33] doc/plugins.rst: document sample formats for OpenSLES --- doc/plugins.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/plugins.rst b/doc/plugins.rst index 5690cf5c0..d485e6fb2 100644 --- a/doc/plugins.rst +++ b/doc/plugins.rst @@ -1072,7 +1072,8 @@ sles Plugin using the `OpenSL ES `__ audio API. Its primary use is local playback on Android, where -:ref:`ALSA ` is not available. +:ref:`ALSA ` is not available. It supports 16 bit and +floating point samples. solaris From 3c745b4bc686e9ad060ca58d9097a328be815dc8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 20 Jul 2020 18:13:37 +0200 Subject: [PATCH 10/33] neighbor/smbclient: remove obsolete commented code --- src/neighbor/plugins/SmbclientNeighborPlugin.cxx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx index d6b426f74..6b2075ff9 100644 --- a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx +++ b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx @@ -103,11 +103,6 @@ NeighborExplorer::List SmbclientNeighborExplorer::GetList() const noexcept { const std::lock_guard protect(mutex); - /* - List list; - for (const auto &i : servers) - list.emplace_front(i.Export()); - */ return list; } From c876d6a51cddfb5853fde65a32da4920799b8942 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Mon, 20 Jul 2020 19:59:20 -0700 Subject: [PATCH 11/33] lib/icu: fix build without libc iconv support Need to check for it in iconv.h. Otherwise meson prefixes a __builtin variant in the check. --- src/lib/icu/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/icu/meson.build b/src/lib/icu/meson.build index 5386a62b4..bd6e30944 100644 --- a/src/lib/icu/meson.build +++ b/src/lib/icu/meson.build @@ -18,7 +18,7 @@ if icu_dep.found() 'Init.cxx', ] elif not get_option('iconv').disabled() - have_iconv = compiler.has_function('iconv') + have_iconv = compiler.has_function('iconv', prefix : '#include ') conf.set('HAVE_ICONV', have_iconv) if not have_iconv and get_option('iconv').enabled() error('iconv() not available') From 2bdf1b228478a2b407b0ed60231b2eec52f9e662 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 1 Jul 2020 15:25:39 +0200 Subject: [PATCH 12/33] test/meson.build: add explicit dependency from run_output on libevent.a We could exclude that feature if neither ALSA nor httpd are enabled, but that's too complicated for this small debug program. --- test/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/test/meson.build b/test/meson.build index a1dc7840d..0befdc71e 100644 --- a/test/meson.build +++ b/test/meson.build @@ -624,6 +624,7 @@ executable( dependencies: [ output_glue_dep, encoder_glue_dep, + event_dep, ], ) From 4f6c54ecb384398f33a48c1f1a2879fe44127ead Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 14 Aug 2020 14:36:30 +0200 Subject: [PATCH 13/33] output/osx: catch kAudioDevicePropertyHogMode errors Our AudioObjectGetPropertyDataT() wrapper throws exception on error, and calling it from OSXOutput::Disable() can cause MPD crash due to std::terminate(). Closes https://github.com/MusicPlayerDaemon/MPD/issues/932 --- NEWS | 1 + src/output/plugins/OSXOutputPlugin.cxx | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index b698d4f5f..e23b1d0e5 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ ver 0.21.26 (not yet released) * output + - osx: fix crash bug - sles: support floating point samples ver 0.21.25 (2020/07/06) diff --git a/src/output/plugins/OSXOutputPlugin.cxx b/src/output/plugins/OSXOutputPlugin.cxx index 0a51af7a5..f4a843119 100644 --- a/src/output/plugins/OSXOutputPlugin.cxx +++ b/src/output/plugins/OSXOutputPlugin.cxx @@ -477,7 +477,7 @@ osx_output_set_buffer_size(AudioUnit au, AudioStreamBasicDescription desc) } static void -osx_output_hog_device(AudioDeviceID dev_id, bool hog) +osx_output_hog_device(AudioDeviceID dev_id, bool hog) noexcept { static constexpr AudioObjectPropertyAddress aopa = { kAudioDevicePropertyHogMode, @@ -485,8 +485,16 @@ osx_output_hog_device(AudioDeviceID dev_id, bool hog) kAudioObjectPropertyElementMaster }; - pid_t hog_pid = AudioObjectGetPropertyDataT(dev_id, - aopa); + pid_t hog_pid; + + try { + hog_pid = AudioObjectGetPropertyDataT(dev_id, aopa); + } catch (...) { + Log(LogLevel::DEBUG, std::current_exception(), + "Failed to query HogMode"); + return; + } + if (hog) { if (hog_pid != -1) { FormatDebug(osx_output_domain, From cbcdc73f9a01ade6848619c3f25eafdbb79b1155 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 14 Aug 2020 16:35:19 +0200 Subject: [PATCH 14/33] system/ByteOrder: add `noexcept` --- src/util/ByteOrder.hxx | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/util/ByteOrder.hxx b/src/util/ByteOrder.hxx index 719d3a083..f52c2bd38 100644 --- a/src/util/ByteOrder.hxx +++ b/src/util/ByteOrder.hxx @@ -74,39 +74,39 @@ #endif constexpr bool -IsLittleEndian() +IsLittleEndian() noexcept { return IS_LITTLE_ENDIAN; } constexpr bool -IsBigEndian() +IsBigEndian() noexcept { return IS_BIG_ENDIAN; } constexpr uint16_t -GenericByteSwap16(uint16_t value) +GenericByteSwap16(uint16_t value) noexcept { return (value >> 8) | (value << 8); } constexpr uint32_t -GenericByteSwap32(uint32_t value) +GenericByteSwap32(uint32_t value) noexcept { return (value >> 24) | ((value >> 8) & 0x0000ff00) | ((value << 8) & 0x00ff0000) | (value << 24); } constexpr uint64_t -GenericByteSwap64(uint64_t value) +GenericByteSwap64(uint64_t value) noexcept { return uint64_t(GenericByteSwap32(uint32_t(value >> 32))) | (uint64_t(GenericByteSwap32(value)) << 32); } constexpr uint16_t -ByteSwap16(uint16_t value) +ByteSwap16(uint16_t value) noexcept { #if CLANG_OR_GCC_VERSION(4,8) return __builtin_bswap16(value); @@ -116,7 +116,7 @@ ByteSwap16(uint16_t value) } constexpr uint32_t -ByteSwap32(uint32_t value) +ByteSwap32(uint32_t value) noexcept { #if CLANG_OR_GCC_VERSION(4,3) return __builtin_bswap32(value); @@ -126,7 +126,7 @@ ByteSwap32(uint32_t value) } constexpr uint64_t -ByteSwap64(uint64_t value) +ByteSwap64(uint64_t value) noexcept { #if CLANG_OR_GCC_VERSION(4,3) return __builtin_bswap64(value); @@ -139,7 +139,7 @@ ByteSwap64(uint64_t value) * Converts a 16bit value from big endian to the system's byte order */ constexpr uint16_t -FromBE16(uint16_t value) +FromBE16(uint16_t value) noexcept { return IsBigEndian() ? value : ByteSwap16(value); } @@ -148,7 +148,7 @@ FromBE16(uint16_t value) * Converts a 32bit value from big endian to the system's byte order */ constexpr uint32_t -FromBE32(uint32_t value) +FromBE32(uint32_t value) noexcept { return IsBigEndian() ? value : ByteSwap32(value); } @@ -157,7 +157,7 @@ FromBE32(uint32_t value) * Converts a 64bit value from big endian to the system's byte order */ constexpr uint64_t -FromBE64(uint64_t value) +FromBE64(uint64_t value) noexcept { return IsBigEndian() ? value : ByteSwap64(value); } @@ -166,7 +166,7 @@ FromBE64(uint64_t value) * Converts a 16bit value from little endian to the system's byte order */ constexpr uint16_t -FromLE16(uint16_t value) +FromLE16(uint16_t value) noexcept { return IsLittleEndian() ? value : ByteSwap16(value); } @@ -175,7 +175,7 @@ FromLE16(uint16_t value) * Converts a 32bit value from little endian to the system's byte order */ constexpr uint32_t -FromLE32(uint32_t value) +FromLE32(uint32_t value) noexcept { return IsLittleEndian() ? value : ByteSwap32(value); } @@ -184,7 +184,7 @@ FromLE32(uint32_t value) * Converts a 64bit value from little endian to the system's byte order */ constexpr uint64_t -FromLE64(uint64_t value) +FromLE64(uint64_t value) noexcept { return IsLittleEndian() ? value : ByteSwap64(value); } @@ -193,7 +193,7 @@ FromLE64(uint64_t value) * Converts a 16bit value from the system's byte order to big endian */ constexpr uint16_t -ToBE16(uint16_t value) +ToBE16(uint16_t value) noexcept { return IsBigEndian() ? value : ByteSwap16(value); } @@ -202,7 +202,7 @@ ToBE16(uint16_t value) * Converts a 32bit value from the system's byte order to big endian */ constexpr uint32_t -ToBE32(uint32_t value) +ToBE32(uint32_t value) noexcept { return IsBigEndian() ? value : ByteSwap32(value); } @@ -211,7 +211,7 @@ ToBE32(uint32_t value) * Converts a 64bit value from the system's byte order to big endian */ constexpr uint64_t -ToBE64(uint64_t value) +ToBE64(uint64_t value) noexcept { return IsBigEndian() ? value : ByteSwap64(value); } @@ -220,7 +220,7 @@ ToBE64(uint64_t value) * Converts a 16bit value from the system's byte order to little endian */ constexpr uint16_t -ToLE16(uint16_t value) +ToLE16(uint16_t value) noexcept { return IsLittleEndian() ? value : ByteSwap16(value); } @@ -229,7 +229,7 @@ ToLE16(uint16_t value) * Converts a 32bit value from the system's byte order to little endian */ constexpr uint32_t -ToLE32(uint32_t value) +ToLE32(uint32_t value) noexcept { return IsLittleEndian() ? value : ByteSwap32(value); } @@ -238,7 +238,7 @@ ToLE32(uint32_t value) * Converts a 64bit value from the system's byte order to little endian */ constexpr uint64_t -ToLE64(uint64_t value) +ToLE64(uint64_t value) noexcept { return IsLittleEndian() ? value : ByteSwap64(value); } From 8830ea319fccdc4555add4ee16c7cdd62f1c1c57 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 13:33:47 +0200 Subject: [PATCH 15/33] decoder/API: add `noexcept` --- src/decoder/DecoderAPI.cxx | 6 +++--- src/decoder/DecoderAPI.hxx | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/decoder/DecoderAPI.cxx b/src/decoder/DecoderAPI.cxx index a245989de..03f02b311 100644 --- a/src/decoder/DecoderAPI.cxx +++ b/src/decoder/DecoderAPI.cxx @@ -26,7 +26,7 @@ size_t decoder_read(DecoderClient *client, InputStream &is, - void *buffer, size_t length) + void *buffer, size_t length) noexcept { assert(buffer != nullptr); @@ -44,7 +44,7 @@ decoder_read(DecoderClient *client, bool decoder_read_full(DecoderClient *client, InputStream &is, - void *_buffer, size_t size) + void *_buffer, size_t size) noexcept { uint8_t *buffer = (uint8_t *)_buffer; @@ -61,7 +61,7 @@ decoder_read_full(DecoderClient *client, InputStream &is, } bool -decoder_skip(DecoderClient *client, InputStream &is, size_t size) +decoder_skip(DecoderClient *client, InputStream &is, size_t size) noexcept { while (size > 0) { char buffer[1024]; diff --git a/src/decoder/DecoderAPI.hxx b/src/decoder/DecoderAPI.hxx index 537e371cd..20959b456 100644 --- a/src/decoder/DecoderAPI.hxx +++ b/src/decoder/DecoderAPI.hxx @@ -65,11 +65,11 @@ class StopDecoder {}; */ size_t decoder_read(DecoderClient *decoder, InputStream &is, - void *buffer, size_t length); + void *buffer, size_t length) noexcept; static inline size_t decoder_read(DecoderClient &decoder, InputStream &is, - void *buffer, size_t length) + void *buffer, size_t length) noexcept { return decoder_read(&decoder, is, buffer, length); } @@ -83,7 +83,7 @@ decoder_read(DecoderClient &decoder, InputStream &is, */ bool decoder_read_full(DecoderClient *decoder, InputStream &is, - void *buffer, size_t size); + void *buffer, size_t size) noexcept; /** * Skip data on the #InputStream. @@ -91,6 +91,6 @@ decoder_read_full(DecoderClient *decoder, InputStream &is, * @return true on success, false on error or command */ bool -decoder_skip(DecoderClient *decoder, InputStream &is, size_t size); +decoder_skip(DecoderClient *decoder, InputStream &is, size_t size) noexcept; #endif From 33f70931dd2864d2c522a7165404aa89871c7da8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 13:18:37 +0200 Subject: [PATCH 16/33] decoder/API: add decoder_read_much() --- src/decoder/DecoderAPI.cxx | 21 +++++++++++++++++++++ src/decoder/DecoderAPI.hxx | 12 ++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/decoder/DecoderAPI.cxx b/src/decoder/DecoderAPI.cxx index 03f02b311..35e3ebafb 100644 --- a/src/decoder/DecoderAPI.cxx +++ b/src/decoder/DecoderAPI.cxx @@ -42,6 +42,27 @@ decoder_read(DecoderClient *client, } } +size_t +decoder_read_much(DecoderClient *client, InputStream &is, + void *_buffer, size_t size) noexcept +{ + uint8_t *buffer = (uint8_t *)_buffer; + + size_t total = 0; + + while (size > 0 && !is.LockIsEOF()) { + size_t nbytes = decoder_read(client, is, buffer, size); + if (nbytes == 0) + return false; + + total += nbytes; + buffer += nbytes; + size -= nbytes; + } + + return total; +} + bool decoder_read_full(DecoderClient *client, InputStream &is, void *_buffer, size_t size) noexcept diff --git a/src/decoder/DecoderAPI.hxx b/src/decoder/DecoderAPI.hxx index 20959b456..357c4f60a 100644 --- a/src/decoder/DecoderAPI.hxx +++ b/src/decoder/DecoderAPI.hxx @@ -74,6 +74,18 @@ decoder_read(DecoderClient &decoder, InputStream &is, return decoder_read(&decoder, is, buffer, length); } +/** + * Blocking read from the input stream. Attempts to fill the buffer + * as much as possible, until either end-of-file is reached or an + * error occurs. + * + * @return the number of bytes read, or 0 if one of the following + * occurs: end of file; error; command (like SEEK or STOP). + */ +size_t +decoder_read_much(DecoderClient *decoder, InputStream &is, + void *buffer, size_t size) noexcept; + /** * Blocking read from the input stream. Attempts to fill the buffer * completely; there is no partial result. From 0aa0ffb67b225c583dd25a31869dc5b3222cd5fb Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 13:27:27 +0200 Subject: [PATCH 17/33] decoder/sndfile: allow partial reads at end of file While libsndfile doesn't like partial reads in the middle of a file (see commit 95ac6071b9), it allows partial reads at the end of a file. It doesn't pay attention to the file size when issuing a read. Commit ecb67a1ed16e9 (MPD 0.18.12) was a regression: previously, partial reads at the end of a file were possible, but switching to decoder_read_full() made this an error condition. This way, a portion at the end of each file was lost, leading to corruption with gapless playback (https://github.com/MusicPlayerDaemon/MPD/issues/936). This fix switches to the newly introduced function decoder_read_much(), which does the same as the code before commit ecb67a1ed16e93. Closes https://github.com/MusicPlayerDaemon/MPD/issues/936 --- NEWS | 2 ++ src/decoder/plugins/SndfileDecoderPlugin.cxx | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index e23b1d0e5..6ec3b242d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ ver 0.21.26 (not yet released) * output - osx: fix crash bug - sles: support floating point samples +* decoder + - sndfile: fix lost samples at end of file ver 0.21.25 (2020/07/06) * protocol: diff --git a/src/decoder/plugins/SndfileDecoderPlugin.cxx b/src/decoder/plugins/SndfileDecoderPlugin.cxx index efcf49914..804d676b4 100644 --- a/src/decoder/plugins/SndfileDecoderPlugin.cxx +++ b/src/decoder/plugins/SndfileDecoderPlugin.cxx @@ -46,9 +46,7 @@ struct SndfileInputStream { size_t Read(void *buffer, size_t size) { /* libsndfile chokes on partial reads; therefore always force full reads */ - return decoder_read_full(client, is, buffer, size) - ? size - : 0; + return decoder_read_much(client, is, buffer, size); } }; From 3b51c53eca040217936e0ed2ebf8ab0555ffb058 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 14:31:03 +0200 Subject: [PATCH 18/33] win32/build.py: add -D_FORTIFY_SOURCE=0 This fixes the Windows build. Linking failed because some packages (e.g. libFLAC) default to enabling `_FORTIFY_SOURCE`, which is broken in recent mingw versions (https://github.com/msys2/MINGW-packages/issues/5803). --- win32/build.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/win32/build.py b/win32/build.py index fb636ded5..8aa87e288 100755 --- a/win32/build.py +++ b/win32/build.py @@ -66,6 +66,11 @@ class CrossGccToolchain: ' -static-libstdc++ -static-libgcc' self.libs = '' + # Explicitly disable _FORTIFY_SOURCE because it is broken with + # mingw. This prevents some libraries such as libFLAC to + # enable it. + self.cppflags += ' -D_FORTIFY_SOURCE=0' + self.is_arm = arch.startswith('arm') self.is_armv7 = self.is_arm and 'armv7' in self.cflags self.is_aarch64 = arch == 'aarch64' From c53074efc94f0ed99dc8baf302908a6a6ac64886 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 14:16:26 +0200 Subject: [PATCH 19/33] archive/zzip: add `explicit` --- src/archive/plugins/ZzipArchivePlugin.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/archive/plugins/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx index 31698b978..00fcc6056 100644 --- a/src/archive/plugins/ZzipArchivePlugin.cxx +++ b/src/archive/plugins/ZzipArchivePlugin.cxx @@ -54,7 +54,7 @@ class ZzipArchiveFile final : public ArchiveFile { std::shared_ptr dir; public: - ZzipArchiveFile(std::shared_ptr &&_dir) + explicit ZzipArchiveFile(std::shared_ptr &&_dir) noexcept :dir(std::move(_dir)) {} virtual void Visit(ArchiveVisitor &visitor) override; From 9d910320f382a3b96488bd27cd1c83daf161adf2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 14:18:01 +0200 Subject: [PATCH 20/33] archive/zzip: pass std::shared_ptr as template parameter This eliminates a tiny amount of overhead because the compiler can choose how to pass the parameter. --- src/archive/plugins/ZzipArchivePlugin.cxx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/archive/plugins/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx index 00fcc6056..143cd33af 100644 --- a/src/archive/plugins/ZzipArchivePlugin.cxx +++ b/src/archive/plugins/ZzipArchivePlugin.cxx @@ -54,8 +54,9 @@ class ZzipArchiveFile final : public ArchiveFile { std::shared_ptr dir; public: - explicit ZzipArchiveFile(std::shared_ptr &&_dir) noexcept - :dir(std::move(_dir)) {} + template + explicit ZzipArchiveFile(D &&_dir) noexcept + :dir(std::forward(_dir)) {} virtual void Visit(ArchiveVisitor &visitor) override; @@ -91,11 +92,12 @@ class ZzipInputStream final : public InputStream { ZZIP_FILE *const file; public: - ZzipInputStream(const std::shared_ptr _dir, const char *_uri, + template + ZzipInputStream(D &&_dir, const char *_uri, Mutex &_mutex, ZZIP_FILE *_file) :InputStream(_uri, _mutex), - dir(_dir), file(_file) { + dir(std::forward(_dir)), file(_file) { //we are seekable (but its not recommendent to do so) seekable = true; From 6c850206301f5a4c39322fd090af46a3b685b03d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 14:18:30 +0200 Subject: [PATCH 21/33] archive/zzip: add `override` --- src/archive/plugins/ZzipArchivePlugin.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/archive/plugins/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx index 143cd33af..a13df5108 100644 --- a/src/archive/plugins/ZzipArchivePlugin.cxx +++ b/src/archive/plugins/ZzipArchivePlugin.cxx @@ -58,7 +58,7 @@ public: explicit ZzipArchiveFile(D &&_dir) noexcept :dir(std::forward(_dir)) {} - virtual void Visit(ArchiveVisitor &visitor) override; + void Visit(ArchiveVisitor &visitor) override; InputStreamPtr OpenStream(const char *path, Mutex &mutex) override; @@ -108,7 +108,7 @@ public: SetReady(); } - ~ZzipInputStream() { + ~ZzipInputStream() noexcept override { zzip_file_close(file); } From e44b953d9ab0cc0ea9b1ac07315feecc0b3c74d1 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 14:13:44 +0200 Subject: [PATCH 22/33] archive/zzip: use zzip_ssize_t to avoid integer overflows --- src/archive/plugins/ZzipArchivePlugin.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/archive/plugins/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx index a13df5108..c4ebbd582 100644 --- a/src/archive/plugins/ZzipArchivePlugin.cxx +++ b/src/archive/plugins/ZzipArchivePlugin.cxx @@ -147,12 +147,12 @@ ZzipInputStream::Read(void *ptr, size_t read_size) { const ScopeUnlock unlock(mutex); - int ret = zzip_file_read(file, ptr, read_size); - if (ret < 0) + zzip_ssize_t nbytes = zzip_file_read(file, ptr, read_size); + if (nbytes < 0) throw std::runtime_error("zzip_file_read() has failed"); offset = zzip_tell(file); - return ret; + return nbytes; } bool From 1f6a7d64622046f6b56c302c0f9ff34ae8c326c6 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 14:11:33 +0200 Subject: [PATCH 23/33] archive/zzip: fix crash on corrupt ZIP file Sometimes, zzip_file_read() returns 0 even though the end of the file was not reached. This causes assertion failures in DecoderBridge::Read(). Closes https://github.com/MusicPlayerDaemon/MPD/issues/935 --- NEWS | 2 ++ src/archive/plugins/ZzipArchivePlugin.cxx | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/NEWS b/NEWS index 6ec3b242d..96a3c40bf 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ ver 0.21.26 (not yet released) * output - osx: fix crash bug - sles: support floating point samples +* archive + - zzip: fix crash on corrupt ZIP file * decoder - sndfile: fix lost samples at end of file diff --git a/src/archive/plugins/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx index c4ebbd582..75fa81c37 100644 --- a/src/archive/plugins/ZzipArchivePlugin.cxx +++ b/src/archive/plugins/ZzipArchivePlugin.cxx @@ -32,6 +32,8 @@ #include +#include /* for PRIoffset (PRIu64) */ + struct ZzipDir { ZZIP_DIR *const dir; @@ -151,6 +153,11 @@ ZzipInputStream::Read(void *ptr, size_t read_size) if (nbytes < 0) throw std::runtime_error("zzip_file_read() has failed"); + if (nbytes == 0 && !IsEOF()) + throw FormatRuntimeError("Unexpected end of file %s" + " at %" PRIoffset " of %" PRIoffset, + GetURI(), GetOffset(), GetSize()); + offset = zzip_tell(file); return nbytes; } From 64aadcd13f9986818d1f0ecc66c63df6b235de4b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 14:44:49 +0200 Subject: [PATCH 24/33] python/build/libs.py: update CURL to 7.72.0 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index d5403b7a9..a184c5698 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -377,8 +377,8 @@ ffmpeg = FfmpegProject( ) curl = AutotoolsProject( - 'http://curl.haxx.se/download/curl-7.71.1.tar.xz', - '40f83eda27cdbeb25cd4da48cefb639af1b9395d6026d2da1825bf059239658c', + 'http://curl.haxx.se/download/curl-7.72.0.tar.xz', + '0ded0808c4d85f2ee0db86980ae610cc9d165e9ca9da466196cc73c346513713', 'lib/libcurl.a', [ '--disable-shared', '--enable-static', From 5c9d97775f20aa1d7a66bf1e60db1872fe9b9db7 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 14:49:10 +0200 Subject: [PATCH 25/33] python/build/libs.py: update Boost to 1.74.0 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index a184c5698..4886e8e19 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -433,7 +433,7 @@ libnfs = AutotoolsProject( ) boost = BoostProject( - 'https://dl.bintray.com/boostorg/release/1.73.0/source/boost_1_73_0.tar.bz2', - '4eb3b8d442b426dc35346235c8733b5ae35ba431690e38c6a8263dce9fcbb402', + 'https://dl.bintray.com/boostorg/release/1.74.0/source/boost_1_74_0.tar.bz2', + '83bfc1507731a0906e387fc28b7ef5417d591429e51e788417fe9ff025e116b1', 'include/boost/version.hpp', ) From 1a516e774457b0d0b90171b62c357737c84ec62c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 17:50:23 +0200 Subject: [PATCH 26/33] archive/bzip2: add `override` --- src/archive/plugins/Bzip2ArchivePlugin.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx index db0d013ff..3bdaf94e5 100644 --- a/src/archive/plugins/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -68,7 +68,7 @@ public: Bzip2InputStream(const std::shared_ptr &_input, const char *uri, Mutex &mutex); - ~Bzip2InputStream(); + ~Bzip2InputStream() noexcept override; /* virtual methods from InputStream */ bool IsEOF() noexcept override; @@ -119,7 +119,7 @@ Bzip2InputStream::Bzip2InputStream(const std::shared_ptr &_input, Open(); } -Bzip2InputStream::~Bzip2InputStream() +Bzip2InputStream::~Bzip2InputStream() noexcept { BZ2_bzDecompressEnd(&bzstream); } From f63c343f6887e91cf449f8a8fc7f74ec79f96bc2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 17:50:49 +0200 Subject: [PATCH 27/33] archive/bzip2: reorder fields to improve packing --- src/archive/plugins/Bzip2ArchivePlugin.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx index 3bdaf94e5..c3e63c91c 100644 --- a/src/archive/plugins/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -58,10 +58,10 @@ public: class Bzip2InputStream final : public InputStream { std::shared_ptr input; - bool eof = false; - bz_stream bzstream; + bool eof = false; + char buffer[5000]; public: From 15939fd87c2c2195b82d880613f29bd4dcf44374 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 17:50:39 +0200 Subject: [PATCH 28/33] archive/bzip2: fold Open() into constructor --- src/archive/plugins/Bzip2ArchivePlugin.cxx | 32 ++++++++-------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx index c3e63c91c..a9dbbd9a6 100644 --- a/src/archive/plugins/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -79,25 +79,6 @@ private: bool FillBuffer(); }; -/* single archive handling allocation helpers */ - -inline void -Bzip2InputStream::Open() -{ - bzstream.bzalloc = nullptr; - bzstream.bzfree = nullptr; - bzstream.opaque = nullptr; - - bzstream.next_in = (char *)buffer; - bzstream.avail_in = 0; - - int ret = BZ2_bzDecompressInit(&bzstream, 0, 0); - if (ret != BZ_OK) - throw std::runtime_error("BZ2_bzDecompressInit() has failed"); - - SetReady(); -} - /* archive open && listing routine */ static std::unique_ptr @@ -116,7 +97,18 @@ Bzip2InputStream::Bzip2InputStream(const std::shared_ptr &_input, :InputStream(_uri, _mutex), input(_input) { - Open(); + bzstream.bzalloc = nullptr; + bzstream.bzfree = nullptr; + bzstream.opaque = nullptr; + + bzstream.next_in = (char *)buffer; + bzstream.avail_in = 0; + + int ret = BZ2_bzDecompressInit(&bzstream, 0, 0); + if (ret != BZ_OK) + throw std::runtime_error("BZ2_bzDecompressInit() has failed"); + + SetReady(); } Bzip2InputStream::~Bzip2InputStream() noexcept From 41b47f95c56c1ed51e48b91a0a781acba0d1cd95 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 17:51:56 +0200 Subject: [PATCH 29/33] archive/bzip2: simplify bz_stream initializer --- src/archive/plugins/Bzip2ArchivePlugin.cxx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx index a9dbbd9a6..493ffec88 100644 --- a/src/archive/plugins/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -58,7 +58,7 @@ public: class Bzip2InputStream final : public InputStream { std::shared_ptr input; - bz_stream bzstream; + bz_stream bzstream{}; bool eof = false; @@ -97,12 +97,7 @@ Bzip2InputStream::Bzip2InputStream(const std::shared_ptr &_input, :InputStream(_uri, _mutex), input(_input) { - bzstream.bzalloc = nullptr; - bzstream.bzfree = nullptr; - bzstream.opaque = nullptr; - bzstream.next_in = (char *)buffer; - bzstream.avail_in = 0; int ret = BZ2_bzDecompressInit(&bzstream, 0, 0); if (ret != BZ_OK) From 9e6c4f8d80c4c7b0af9b728fe7c710784534026c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 17:53:47 +0200 Subject: [PATCH 30/33] archive/bzip2: throw on unexpected input EOF Don't silently return 0 when there is no more data, because this may crash the caller. And flush output even if input EOF has been reached. --- NEWS | 2 ++ src/archive/plugins/Bzip2ArchivePlugin.cxx | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 96a3c40bf..bbfbb271f 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ ver 0.21.26 (not yet released) - osx: fix crash bug - sles: support floating point samples * archive + - bzip2: fix crash on corrupt bzip2 file + - bzip2: flush output at end of input file - zzip: fix crash on corrupt ZIP file * decoder - sndfile: fix lost samples at end of file diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx index 493ffec88..0228fa743 100644 --- a/src/archive/plugins/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -148,8 +148,7 @@ Bzip2InputStream::Read(void *ptr, size_t length) bzstream.avail_out = length; do { - if (!FillBuffer()) - return 0; + const bool had_input = FillBuffer(); bz_result = BZ2_bzDecompress(&bzstream); @@ -160,6 +159,9 @@ Bzip2InputStream::Read(void *ptr, size_t length) if (bz_result != BZ_OK) throw std::runtime_error("BZ2_bzDecompress() has failed"); + + if (!had_input && bzstream.avail_out == length) + throw std::runtime_error("Unexpected end of bzip2 file"); } while (bzstream.avail_out == length); nbytes = length - bzstream.avail_out; From db46d84458be54fedd89613f881ffe6181bdb03e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 18:01:22 +0200 Subject: [PATCH 31/33] archive/bzip2: move the eof check out of the ScopeUnlock --- src/archive/plugins/Bzip2ArchivePlugin.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx index 0228fa743..8e7ebab2c 100644 --- a/src/archive/plugins/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -136,14 +136,14 @@ Bzip2InputStream::FillBuffer() size_t Bzip2InputStream::Read(void *ptr, size_t length) { + if (eof) + return 0; + const ScopeUnlock unlock(mutex); int bz_result; size_t nbytes = 0; - if (eof) - return 0; - bzstream.next_out = (char *)ptr; bzstream.avail_out = length; From 990f631cbcdab3a611fb4d90fbf8a06f5c5c1183 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 18:02:05 +0200 Subject: [PATCH 32/33] archive/bzip2: make variables more local --- src/archive/plugins/Bzip2ArchivePlugin.cxx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx index 8e7ebab2c..bedb5c54a 100644 --- a/src/archive/plugins/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -141,16 +141,13 @@ Bzip2InputStream::Read(void *ptr, size_t length) const ScopeUnlock unlock(mutex); - int bz_result; - size_t nbytes = 0; - bzstream.next_out = (char *)ptr; bzstream.avail_out = length; do { const bool had_input = FillBuffer(); - bz_result = BZ2_bzDecompress(&bzstream); + const int bz_result = BZ2_bzDecompress(&bzstream); if (bz_result == BZ_STREAM_END) { eof = true; @@ -164,7 +161,7 @@ Bzip2InputStream::Read(void *ptr, size_t length) throw std::runtime_error("Unexpected end of bzip2 file"); } while (bzstream.avail_out == length); - nbytes = length - bzstream.avail_out; + const size_t nbytes = length - bzstream.avail_out; offset += nbytes; return nbytes; From db8b419b8c3aa738efb3fa7b5de7b2894ced6cde Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Sep 2020 18:16:19 +0200 Subject: [PATCH 33/33] archive/iso9660: free iso9660_stat_t as early as possible --- src/archive/plugins/Iso9660ArchivePlugin.cxx | 24 +++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/archive/plugins/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx index 6cb307bd4..6314fb025 100644 --- a/src/archive/plugins/Iso9660ArchivePlugin.cxx +++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx @@ -142,23 +142,21 @@ Iso9660ArchiveFile::Visit(ArchiveVisitor &visitor) class Iso9660InputStream final : public InputStream { std::shared_ptr iso; - iso9660_stat_t *statbuf; + const lsn_t lsn; public: Iso9660InputStream(const std::shared_ptr &_iso, const char *_uri, Mutex &_mutex, - iso9660_stat_t *_statbuf) + lsn_t _lsn, offset_type _size) :InputStream(_uri, _mutex), - iso(_iso), statbuf(_statbuf) { - size = statbuf->size; + iso(_iso), + lsn(_lsn) + { + size = _size; SetReady(); } - ~Iso9660InputStream() { - free(statbuf); - } - /* virtual methods from InputStream */ bool IsEOF() noexcept override; size_t Read(void *ptr, size_t size) override; @@ -173,8 +171,12 @@ Iso9660ArchiveFile::OpenStream(const char *pathname, throw FormatRuntimeError("not found in the ISO file: %s", pathname); + const lsn_t lsn = statbuf->lsn; + const offset_type size = statbuf->size; + free(statbuf); + return std::make_unique(iso, pathname, mutex, - statbuf); + lsn, size); } size_t @@ -184,7 +186,7 @@ Iso9660InputStream::Read(void *ptr, size_t read_size) int readed = 0; int no_blocks, cur_block; - size_t left_bytes = statbuf->size - offset; + size_t left_bytes = size - offset; if (left_bytes < read_size) { no_blocks = CEILING(left_bytes, ISO_BLOCKSIZE); @@ -197,7 +199,7 @@ Iso9660InputStream::Read(void *ptr, size_t read_size) cur_block = offset / ISO_BLOCKSIZE; - readed = iso->SeekRead(ptr, statbuf->lsn + cur_block, no_blocks); + readed = iso->SeekRead(ptr, lsn + cur_block, no_blocks); if (readed != no_blocks * ISO_BLOCKSIZE) throw FormatRuntimeError("error reading ISO file at lsn %lu",