From 421c4ae907e27661902f28c07c1c470c3dba3cf7 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 4 Sep 2014 14:38:55 +0200 Subject: protocol/ArgParser: fix integer overflow in parse_range() Casting std::numeric_limits::max() to "long" leads to an overflow if sizeof(unsigned)==sizeof(long), and the result will be -1. This happens on some 32 bit architectures, for example ARM and WIN32. Workaround: use std::numeric_limits::max(), which is the largest signed integer. Since sizeof(long)>=sizeof(int), this will never overflow. Fixes Mantis ticket 0004080. --- src/protocol/ArgParser.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/protocol/ArgParser.cxx b/src/protocol/ArgParser.cxx index b13ea3f4e..86527c751 100644 --- a/src/protocol/ArgParser.cxx +++ b/src/protocol/ArgParser.cxx @@ -81,7 +81,7 @@ check_range(Client &client, unsigned *value_r1, unsigned *value_r2, /* compatibility with older MPD versions: specifying "-1" makes MPD display the whole list */ *value_r1 = 0; - *value_r2 = std::numeric_limits::max(); + *value_r2 = std::numeric_limits::max(); return true; } @@ -108,7 +108,7 @@ check_range(Client &client, unsigned *value_r1, unsigned *value_r2, } if (test == test2) - value = std::numeric_limits::max(); + value = std::numeric_limits::max(); if (value < 0) { command_error(client, ACK_ERROR_ARG, -- cgit v1.2.3 From 7ada7def9e797deb7a34ba8da1e33e207d4ed55f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 6 Sep 2014 19:32:10 +0200 Subject: decoder/audiofile: fix crash after seeking Log call was added to the wrong branch. Fixes regression by commit ca1a1149 --- src/decoder/AudiofileDecoderPlugin.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/decoder/AudiofileDecoderPlugin.cxx b/src/decoder/AudiofileDecoderPlugin.cxx index 9f097f90b..b1b8bf613 100644 --- a/src/decoder/AudiofileDecoderPlugin.cxx +++ b/src/decoder/AudiofileDecoderPlugin.cxx @@ -110,9 +110,9 @@ audiofile_file_seek(AFvirtualfile *vfile, AFfileoffset offset, int is_relative) Error error; if (is.LockSeek(offset, whence, error)) { - LogError(error, "Seek failed"); return is.GetOffset(); } else { + LogError(error, "Seek failed"); return -1; } } -- cgit v1.2.3 From a6bb27483b30f81145c19d1048a342c0aa5401d0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 7 Sep 2014 21:31:10 +0200 Subject: DecoderThread: clear the pipe when handling late SEEK See code comment. Fixes assertion failure in decoder_command_finished(). --- src/DecoderThread.cxx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/DecoderThread.cxx b/src/DecoderThread.cxx index 72fc3cfb4..cf21534f0 100644 --- a/src/DecoderThread.cxx +++ b/src/DecoderThread.cxx @@ -26,6 +26,7 @@ #include "Song.hxx" #include "system/FatalError.hxx" #include "Mapper.hxx" +#include "MusicPipe.hxx" #include "fs/Traits.hxx" #include "fs/AllocatedPath.hxx" #include "DecoderAPI.hxx" @@ -418,9 +419,18 @@ decoder_task(void *arg) dc.replay_gain_prev_db = dc.replay_gain_db; dc.replay_gain_db = 0; - /* fall through */ + decoder_run(dc); + break; case DecoderCommand::SEEK: + /* this seek was too late, and the decoder had + already finished; start a new decoder */ + + /* we need to clear the pipe here; usually the + PlayerThread is responsible, but it is not + aware that the decoder has finished */ + dc.pipe->Clear(*dc.buffer); + decoder_run(dc); break; -- cgit v1.2.3 From e3a0f158376a38abb2eb9aa4a67b155ff9da6ffe Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 7 Sep 2014 21:50:27 +0200 Subject: Decoder*: add more assertions --- src/DecoderAPI.cxx | 4 ++++ src/DecoderInternal.cxx | 3 +++ 2 files changed, 7 insertions(+) (limited to 'src') diff --git a/src/DecoderAPI.cxx b/src/DecoderAPI.cxx index e4122d60e..334d069bf 100644 --- a/src/DecoderAPI.cxx +++ b/src/DecoderAPI.cxx @@ -47,6 +47,7 @@ decoder_initialized(Decoder &decoder, assert(dc.state == DecoderState::START); assert(dc.pipe != nullptr); + assert(dc.pipe->IsEmpty()); assert(decoder.stream_tag == nullptr); assert(decoder.decoder_tag == nullptr); assert(!decoder.seeking); @@ -405,6 +406,9 @@ decoder_data(Decoder &decoder, length == 0) return cmd; + assert(!decoder.initial_seek_pending); + assert(!decoder.initial_seek_running); + /* send stream tags */ if (update_stream_tag(decoder, is)) { diff --git a/src/DecoderInternal.cxx b/src/DecoderInternal.cxx index d5f40ad48..b5e6c9d57 100644 --- a/src/DecoderInternal.cxx +++ b/src/DecoderInternal.cxx @@ -83,6 +83,9 @@ void decoder_flush_chunk(Decoder &decoder) { DecoderControl &dc = decoder.dc; + assert(!decoder.seeking); + assert(!decoder.initial_seek_running); + assert(!decoder.initial_seek_pending); assert(decoder.chunk != nullptr); -- cgit v1.2.3 From 219c42522f938c5fff08d962a1a54c0872322f00 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 7 Sep 2014 22:05:33 +0200 Subject: decoder/ffmpeg: pass MIME type to ffmpeg/libav version 11 That attribute was uninitialized before, which could crash libavformat. See Debian bug 760669 --- src/decoder/FfmpegDecoderPlugin.cxx | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/decoder/FfmpegDecoderPlugin.cxx b/src/decoder/FfmpegDecoderPlugin.cxx index 5133f91ac..1409a3c47 100644 --- a/src/decoder/FfmpegDecoderPlugin.cxx +++ b/src/decoder/FfmpegDecoderPlugin.cxx @@ -387,6 +387,13 @@ ffmpeg_probe(Decoder *decoder, InputStream &is) avpd.buf_size = nbytes; avpd.filename = is.uri.c_str(); +#ifdef AVPROBE_SCORE_MIME + /* this attribute was added in libav/ffmpeg version 11, but + unfortunately it's "uint8_t" instead of "char", and it's + not "const" - wtf? */ + avpd.mime_type = (uint8_t *)const_cast(is.GetMimeType()); +#endif + return av_probe_input_format(&avpd, true); } -- cgit v1.2.3 From c14a00eec92074536591c05f0ac5486bf74980f9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 9 Sep 2014 19:07:46 +0200 Subject: decoder/ffmpeg: use memset() to initialize AVProbeData --- src/decoder/FfmpegDecoderPlugin.cxx | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/decoder/FfmpegDecoderPlugin.cxx b/src/decoder/FfmpegDecoderPlugin.cxx index 1409a3c47..9cd26c4fa 100644 --- a/src/decoder/FfmpegDecoderPlugin.cxx +++ b/src/decoder/FfmpegDecoderPlugin.cxx @@ -383,6 +383,12 @@ ffmpeg_probe(Decoder *decoder, InputStream &is) nbytes -= PADDING; AVProbeData avpd; + + /* new versions of ffmpeg may add new attributes, and leaving + them uninitialized may crash; hopefully, zero-initializing + everything we don't know is ok */ + memset(&avpd, 0, sizeof(avpd)); + avpd.buf = buffer; avpd.buf_size = nbytes; avpd.filename = is.uri.c_str(); -- cgit v1.2.3