From 205fba74cffffb9df985cdf928101633ffc41772 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 16 Oct 2015 14:40:46 +0200 Subject: tag/ApeLoader: fix buffer overflow after unterminated key --- src/tag/ApeLoader.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/tag/ApeLoader.cxx b/src/tag/ApeLoader.cxx index f473c910e..f51cb5c0b 100644 --- a/src/tag/ApeLoader.cxx +++ b/src/tag/ApeLoader.cxx @@ -78,12 +78,12 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback) /* get the key */ const char *key = p; - while (remaining > size && *p != '\0') { - p++; - remaining--; - } - p++; - remaining--; + const char *key_end = (const char *)memchr(p, '\0', remaining); + if (key_end == nullptr) + break; + + p = key_end + 1; + remaining -= p - key; /* get the value */ if (remaining < size) -- cgit v1.2.3 From 4e3d1821895c92d060fc3a9059e83ac58c8c79a3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 16 Oct 2015 18:05:34 +0200 Subject: encoder/flac: fix crash with 32 bit playback Copy to encoder->audio_format *after* adjusting the sample format to S24_P32. Fixes http://bugs.musicpd.org/view.php?id=4433 --- src/encoder/plugins/FlacEncoderPlugin.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/encoder/plugins/FlacEncoderPlugin.cxx b/src/encoder/plugins/FlacEncoderPlugin.cxx index 26987fe99..9317b02ea 100644 --- a/src/encoder/plugins/FlacEncoderPlugin.cxx +++ b/src/encoder/plugins/FlacEncoderPlugin.cxx @@ -157,8 +157,6 @@ flac_encoder_open(Encoder *_encoder, AudioFormat &audio_format, Error &error) struct flac_encoder *encoder = (struct flac_encoder *)_encoder; unsigned bits_per_sample; - encoder->audio_format = audio_format; - /* FIXME: flac should support 32bit as well */ switch (audio_format.format) { case SampleFormat::S8: @@ -178,6 +176,8 @@ flac_encoder_open(Encoder *_encoder, AudioFormat &audio_format, Error &error) audio_format.format = SampleFormat::S24_P32; } + encoder->audio_format = audio_format; + /* allocate the encoder */ encoder->fse = FLAC__stream_encoder_new(); if (encoder->fse == nullptr) { -- cgit v1.2.3 From f066bb7716200a83e209d27f6b4f87f012033266 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 17 Sep 2015 23:13:53 +0200 Subject: unix/Daemon, playlist/...: remove unused Domain variables --- src/Main.cxx | 3 --- src/encoder/plugins/ShineEncoderPlugin.cxx | 3 --- src/filter/plugins/VolumeFilterPlugin.cxx | 3 --- src/mixer/MixerAll.cxx | 3 --- src/output/plugins/PipeOutputPlugin.cxx | 3 --- src/playlist/plugins/XspfPlaylistPlugin.cxx | 3 --- src/unix/Daemon.cxx | 3 --- 7 files changed, 21 deletions(-) (limited to 'src') diff --git a/src/Main.cxx b/src/Main.cxx index 26d4e7ae4..a3a1b0021 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -54,7 +54,6 @@ #include "system/FatalError.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" -#include "util/Domain.hxx" #include "thread/Id.hxx" #include "thread/Slack.hxx" #include "lib/icu/Init.hxx" @@ -123,8 +122,6 @@ static constexpr unsigned DEFAULT_BUFFER_SIZE = 4096; static constexpr unsigned DEFAULT_BUFFER_BEFORE_PLAY = 10; -static constexpr Domain main_domain("main"); - #ifdef ANDROID Context *context; #endif diff --git a/src/encoder/plugins/ShineEncoderPlugin.cxx b/src/encoder/plugins/ShineEncoderPlugin.cxx index 61cb8609e..1b00f7d53 100644 --- a/src/encoder/plugins/ShineEncoderPlugin.cxx +++ b/src/encoder/plugins/ShineEncoderPlugin.cxx @@ -26,7 +26,6 @@ #include "util/NumberParser.hxx" #include "util/DynamicFifoBuffer.hxx" #include "util/Error.hxx" -#include "util/Domain.hxx" extern "C" { @@ -60,8 +59,6 @@ struct ShineEncoder { bool WriteChunk(bool flush); }; -static constexpr Domain shine_encoder_domain("shine_encoder"); - inline bool ShineEncoder::Configure(const config_param ¶m, gcc_unused Error &error) diff --git a/src/filter/plugins/VolumeFilterPlugin.cxx b/src/filter/plugins/VolumeFilterPlugin.cxx index 17e061476..39188da00 100644 --- a/src/filter/plugins/VolumeFilterPlugin.cxx +++ b/src/filter/plugins/VolumeFilterPlugin.cxx @@ -26,7 +26,6 @@ #include "AudioFormat.hxx" #include "util/ConstBuffer.hxx" #include "util/Error.hxx" -#include "util/Domain.hxx" #include #include @@ -50,8 +49,6 @@ public: Error &error) override; }; -static constexpr Domain volume_domain("pcm_volume"); - static Filter * volume_filter_init(gcc_unused const config_param ¶m, gcc_unused Error &error) diff --git a/src/mixer/MixerAll.cxx b/src/mixer/MixerAll.cxx index 5fef6a92f..91891e870 100644 --- a/src/mixer/MixerAll.cxx +++ b/src/mixer/MixerAll.cxx @@ -25,13 +25,10 @@ #include "output/Internal.hxx" #include "pcm/Volume.hxx" #include "util/Error.hxx" -#include "util/Domain.hxx" #include "Log.hxx" #include -static constexpr Domain mixer_domain("mixer"); - static int output_mixer_get_volume(const AudioOutput &ao) { diff --git a/src/output/plugins/PipeOutputPlugin.cxx b/src/output/plugins/PipeOutputPlugin.cxx index 7a1f32258..d8075d505 100644 --- a/src/output/plugins/PipeOutputPlugin.cxx +++ b/src/output/plugins/PipeOutputPlugin.cxx @@ -22,7 +22,6 @@ #include "../OutputAPI.hxx" #include "config/ConfigError.hxx" #include "util/Error.hxx" -#include "util/Domain.hxx" #include @@ -44,8 +43,6 @@ struct PipeOutput { bool Configure(const config_param ¶m, Error &error); }; -static constexpr Domain pipe_output_domain("pipe_output"); - inline bool PipeOutput::Configure(const config_param ¶m, Error &error) { diff --git a/src/playlist/plugins/XspfPlaylistPlugin.cxx b/src/playlist/plugins/XspfPlaylistPlugin.cxx index 5b6010b53..d25d6dc28 100644 --- a/src/playlist/plugins/XspfPlaylistPlugin.cxx +++ b/src/playlist/plugins/XspfPlaylistPlugin.cxx @@ -25,14 +25,11 @@ #include "input/InputStream.hxx" #include "tag/TagBuilder.hxx" #include "util/Error.hxx" -#include "util/Domain.hxx" #include "lib/expat/ExpatParser.hxx" #include "Log.hxx" #include -static constexpr Domain xspf_domain("xspf"); - /** * This is the state object for the GLib XML parser. */ diff --git a/src/unix/Daemon.cxx b/src/unix/Daemon.cxx index 490b2def5..d283108ed 100644 --- a/src/unix/Daemon.cxx +++ b/src/unix/Daemon.cxx @@ -22,7 +22,6 @@ #include "system/FatalError.hxx" #include "fs/AllocatedPath.hxx" #include "fs/FileSystem.hxx" -#include "util/Domain.hxx" #include "PidFile.hxx" #include "Log.hxx" @@ -37,8 +36,6 @@ #include #endif -static constexpr Domain daemon_domain("daemon"); - #ifndef WIN32 /** the Unix user name which MPD runs as */ -- cgit v1.2.3 From 2a58f2264936787ddd96b40c7626046592c2d1a0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 5 Aug 2015 23:19:22 +0200 Subject: decoder/mpcdec: use Clamp() --- src/decoder/plugins/MpcdecDecoderPlugin.cxx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/decoder/plugins/MpcdecDecoderPlugin.cxx b/src/decoder/plugins/MpcdecDecoderPlugin.cxx index befed0f3b..91b5b55b9 100644 --- a/src/decoder/plugins/MpcdecDecoderPlugin.cxx +++ b/src/decoder/plugins/MpcdecDecoderPlugin.cxx @@ -26,6 +26,7 @@ #include "util/Error.hxx" #include "util/Domain.hxx" #include "util/Macros.hxx" +#include "util/Clamp.hxx" #include "Log.hxx" #include @@ -117,12 +118,7 @@ mpc_to_mpd_sample(MPC_SAMPLE_FORMAT sample) val = sample * float_scale; #endif - if (val < clip_min) - val = clip_min; - else if (val > clip_max) - val = clip_max; - - return val; + return Clamp(val, clip_min, clip_max); } static void -- cgit v1.2.3 From a7ee64a25b7ffe0ccd499341916070c7b6d02f7a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 5 Aug 2015 23:18:21 +0200 Subject: decoder/mpcdec: use SampleTraits Eliminates some duplicate code, and as a side effect, this works around clang 3.8 compiler warning because a negative value was shifted. --- src/decoder/plugins/MpcdecDecoderPlugin.cxx | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/decoder/plugins/MpcdecDecoderPlugin.cxx b/src/decoder/plugins/MpcdecDecoderPlugin.cxx index 91b5b55b9..391b5d691 100644 --- a/src/decoder/plugins/MpcdecDecoderPlugin.cxx +++ b/src/decoder/plugins/MpcdecDecoderPlugin.cxx @@ -22,6 +22,7 @@ #include "../DecoderAPI.hxx" #include "input/InputStream.hxx" #include "CheckAudioFormat.hxx" +#include "pcm/Traits.hxx" #include "tag/TagHandler.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -43,6 +44,9 @@ struct mpc_decoder_data { static constexpr Domain mpcdec_domain("mpcdec"); +static constexpr SampleFormat mpcdec_sample_format = SampleFormat::S24_P32; +typedef SampleTraits MpcdecSampleTraits; + static mpc_int32_t mpc_read_cb(mpc_reader *reader, void *ptr, mpc_int32_t size) { @@ -92,18 +96,15 @@ mpc_getsize_cb(mpc_reader *reader) } /* this _looks_ performance-critical, don't de-inline -- eric */ -static inline int32_t +static inline MpcdecSampleTraits::value_type mpc_to_mpd_sample(MPC_SAMPLE_FORMAT sample) { /* only doing 16-bit audio for now */ - int32_t val; - - enum { - bits = 24, - }; + MpcdecSampleTraits::value_type val; - const int clip_min = -1 << (bits - 1); - const int clip_max = (1 << (bits - 1)) - 1; + constexpr int bits = MpcdecSampleTraits::BITS; + constexpr auto clip_min = MpcdecSampleTraits::MIN; + constexpr auto clip_max = MpcdecSampleTraits::MAX; #ifdef MPC_FIXED_POINT const int shift = bits - MPC_FIXED_POINT_SCALE_SHIFT; @@ -122,7 +123,8 @@ mpc_to_mpd_sample(MPC_SAMPLE_FORMAT sample) } static void -mpc_to_mpd_buffer(int32_t *dest, const MPC_SAMPLE_FORMAT *src, +mpc_to_mpd_buffer(MpcdecSampleTraits::pointer_type dest, + const MPC_SAMPLE_FORMAT *src, unsigned num_samples) { while (num_samples-- > 0) @@ -158,7 +160,7 @@ mpcdec_decode(Decoder &mpd_decoder, InputStream &is) Error error; AudioFormat audio_format; if (!audio_format_init_checked(audio_format, info.sample_freq, - SampleFormat::S24_P32, + mpcdec_sample_format, info.channels, error)) { LogError(error); mpc_demux_exit(demux); @@ -210,7 +212,7 @@ mpcdec_decode(Decoder &mpd_decoder, InputStream &is) mpc_uint32_t ret = frame.samples; ret *= info.channels; - int32_t chunk[ARRAY_SIZE(sample_buffer)]; + MpcdecSampleTraits::value_type chunk[ARRAY_SIZE(sample_buffer)]; mpc_to_mpd_buffer(chunk, sample_buffer, ret); long bit_rate = vbr_update_bits * audio_format.sample_rate -- cgit v1.2.3 From 1958f78cc1bd47ce1c9b57db41194f85aed942ab Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 26 Oct 2015 13:06:29 +0100 Subject: decoder/ffmpeg: fix crash due to wrong avio_alloc_context() call Allocate the buffer dynamically using av_malloc(), and free AVIOContext.buffer in the destructor, as mandated by the libavformat documentation. Fixes http://bugs.musicpd.org/view.php?id=4446 --- src/decoder/plugins/FfmpegDecoderPlugin.cxx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index d5191a3c3..689089107 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -92,14 +92,14 @@ struct AvioStream { AVIOContext *io; - unsigned char buffer[8192]; - AvioStream(Decoder *_decoder, InputStream &_input) :decoder(_decoder), input(_input), io(nullptr) {} ~AvioStream() { - if (io != nullptr) + if (io != nullptr) { + av_free(io->buffer); av_free(io); + } } bool Open(); @@ -153,11 +153,20 @@ mpd_ffmpeg_stream_seek(void *opaque, int64_t pos, int whence) bool AvioStream::Open() { - io = avio_alloc_context(buffer, sizeof(buffer), + constexpr size_t BUFFER_SIZE = 8192; + auto buffer = (unsigned char *)av_malloc(BUFFER_SIZE); + if (buffer == nullptr) + return false; + + io = avio_alloc_context(buffer, BUFFER_SIZE, false, this, mpd_ffmpeg_stream_read, nullptr, input.IsSeekable() ? mpd_ffmpeg_stream_seek : nullptr); + /* If avio_alloc_context() fails, who frees the buffer? The + libavformat API documentation does not specify this, it + only says that AVIOContext.buffer must be freed in the end, + however no AVIOContext exists in that failure code path. */ return io != nullptr; } -- cgit v1.2.3 From ac61d43720393803cb3f6bc5c74aea588e1ca68d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 26 Oct 2015 16:29:07 +0100 Subject: output/Command: flush the mixer cache when enabling/disabling output Fixes mixer lag (http://bugs.musicpd.org/view.php?id=4425). --- src/output/OutputCommand.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/output/OutputCommand.cxx b/src/output/OutputCommand.cxx index 6afb70cf1..e6b8a8e7f 100644 --- a/src/output/OutputCommand.cxx +++ b/src/output/OutputCommand.cxx @@ -30,6 +30,7 @@ #include "Internal.hxx" #include "PlayerControl.hxx" #include "mixer/MixerControl.hxx" +#include "mixer/Volume.hxx" #include "Idle.hxx" extern unsigned audio_output_state_version; @@ -47,6 +48,11 @@ audio_output_enable_index(MultipleOutputs &outputs, unsigned idx) ao.enabled = true; idle_add(IDLE_OUTPUT); + if (ao.mixer != nullptr) { + InvalidateHardwareVolume(); + idle_add(IDLE_MIXER); + } + ao.player_control->UpdateAudio(); ++audio_output_state_version; @@ -70,6 +76,7 @@ audio_output_disable_index(MultipleOutputs &outputs, unsigned idx) Mixer *mixer = ao.mixer; if (mixer != nullptr) { mixer_close(mixer); + InvalidateHardwareVolume(); idle_add(IDLE_MIXER); } @@ -94,6 +101,7 @@ audio_output_toggle_index(MultipleOutputs &outputs, unsigned idx) Mixer *mixer = ao.mixer; if (mixer != nullptr) { mixer_close(mixer); + InvalidateHardwareVolume(); idle_add(IDLE_MIXER); } } -- cgit v1.2.3 From 93c97972b9cb41284f8af8b653e056484bbf4717 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 26 Oct 2015 16:32:39 +0100 Subject: decoder/gme: call decoder_seek_error() on seek error --- src/decoder/plugins/GmeDecoderPlugin.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx index cc6ce5e5d..eab655c91 100644 --- a/src/decoder/plugins/GmeDecoderPlugin.cxx +++ b/src/decoder/plugins/GmeDecoderPlugin.cxx @@ -196,9 +196,11 @@ gme_file_decode(Decoder &decoder, Path path_fs) if (cmd == DecoderCommand::SEEK) { unsigned where = decoder_seek_time(decoder).ToMS(); gme_err = gme_seek(emu, where); - if (gme_err != nullptr) + if (gme_err != nullptr) { LogWarning(gme_domain, gme_err); - decoder_command_finished(decoder); + decoder_seek_error(decoder); + } else + decoder_command_finished(decoder); } if (gme_track_ended(emu)) -- cgit v1.2.3 From a84fbbe32716ecee9c8a02b50251097fc35709ec Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 26 Oct 2015 17:15:24 +0100 Subject: decoder/gme: free the gme_info_t as early as possible --- src/decoder/plugins/GmeDecoderPlugin.cxx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx index eab655c91..bbe2596c9 100644 --- a/src/decoder/plugins/GmeDecoderPlugin.cxx +++ b/src/decoder/plugins/GmeDecoderPlugin.cxx @@ -156,8 +156,11 @@ gme_file_decode(Decoder &decoder, Path path_fs) return; } - const SignedSongTime song_len = ti->length > 0 - ? SignedSongTime::FromMS(ti->length) + const int length = ti->length; + gme_free_info(ti); + + const SignedSongTime song_len = length > 0 + ? SignedSongTime::FromMS(length) : SignedSongTime::Negative(); /* initialize the MPD decoder */ @@ -168,7 +171,6 @@ gme_file_decode(Decoder &decoder, Path path_fs) SampleFormat::S16, GME_CHANNELS, error)) { LogError(error); - gme_free_info(ti); gme_delete(emu); return; } @@ -179,8 +181,8 @@ gme_file_decode(Decoder &decoder, Path path_fs) if (gme_err != nullptr) LogWarning(gme_domain, gme_err); - if (ti->length > 0) - gme_set_fade(emu, ti->length); + if (length > 0) + gme_set_fade(emu, length); /* play */ DecoderCommand cmd; @@ -207,7 +209,6 @@ gme_file_decode(Decoder &decoder, Path path_fs) break; } while (cmd != DecoderCommand::STOP); - gme_free_info(ti); gme_delete(emu); } -- cgit v1.2.3 From 5719207dfa14cfed63e0446f7f7a8343575a465f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 26 Oct 2015 17:16:20 +0100 Subject: gme: don't loop forever, fall back to GME's default play length Fixes http://bugs.musicpd.org/view.php?id=4432 --- src/decoder/plugins/GmeDecoderPlugin.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx index bbe2596c9..b47e9ea66 100644 --- a/src/decoder/plugins/GmeDecoderPlugin.cxx +++ b/src/decoder/plugins/GmeDecoderPlugin.cxx @@ -156,7 +156,7 @@ gme_file_decode(Decoder &decoder, Path path_fs) return; } - const int length = ti->length; + const int length = ti->play_length; gme_free_info(ti); const SignedSongTime song_len = length > 0 @@ -239,9 +239,9 @@ gme_scan_file(Path path_fs, assert(ti != nullptr); - if (ti->length > 0) + if (ti->play_length > 0) tag_handler_invoke_duration(handler, handler_ctx, - SongTime::FromMS(ti->length)); + SongTime::FromMS(ti->play_length)); if (ti->song != nullptr) { if (gme_track_count(emu) > 1) { -- cgit v1.2.3