Commit a464dc68 authored by Max Kellermann's avatar Max Kellermann

Merge tag 'v0.18.14'

parents af384d9a eaf675dc
......@@ -64,6 +64,7 @@ tags
/test/tmp
/test/run_inotify
/test/test_queue_priority
/test/test_protocol
/test/run_ntp_server
/test/run_resolver
/test/run_tcp_connect
......
......@@ -1458,6 +1458,7 @@ C_TESTS = \
test/test_rewind \
test/test_mixramp \
test/test_pcm \
test/test_protocol \
test/test_queue_priority
if ENABLE_CURL
......@@ -2035,6 +2036,16 @@ test_test_translate_song_LDADD = \
endif
test_test_protocol_SOURCES = \
src/protocol/ArgParser.cxx \
test/test_protocol.cxx
test_test_protocol_CPPFLAGS = $(AM_CPPFLAGS) $(CPPUNIT_CFLAGS) -DCPPUNIT_HAVE_RTTI=0
test_test_protocol_CXXFLAGS = $(AM_CXXFLAGS) -Wno-error=deprecated-declarations
test_test_protocol_LDADD = \
libsystem.a \
libutil.a \
$(CPPUNIT_LIBS)
test_test_queue_priority_SOURCES = \
src/queue/Queue.cxx \
src/DetachedSong.cxx \
......
......@@ -69,6 +69,14 @@ ver 0.19 (not yet released)
* install systemd unit for socket activation
* Android port
ver 0.18.14 (2014/09/11)
* protocol
- fix range parser bug on certain 32 bit architectures
* decoder
- audiofile: fix crash after seeking
- ffmpeg: fix crash with ffmpeg/libav version 11
- fix assertion failure after seeking
ver 0.18.13 (2014/08/31)
* protocol
- don't change song on "seekcur" in random mode
......
......@@ -48,6 +48,7 @@ decoder_initialized(Decoder &decoder,
assert(dc.state == DecoderState::START);
assert(dc.pipe != nullptr);
assert(dc.pipe->IsEmpty());
assert(decoder.convert == nullptr);
assert(decoder.stream_tag == nullptr);
assert(decoder.decoder_tag == nullptr);
......@@ -461,6 +462,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)) {
......
......@@ -85,6 +85,9 @@ Decoder::GetChunk()
void
Decoder::FlushChunk()
{
assert(!seeking);
assert(!initial_seek_running);
assert(!initial_seek_pending);
assert(chunk != nullptr);
if (chunk->IsEmpty())
......
......@@ -25,6 +25,7 @@
#include "DecoderPlugin.hxx"
#include "DetachedSong.hxx"
#include "system/FatalError.hxx"
#include "MusicPipe.hxx"
#include "fs/Traits.hxx"
#include "fs/AllocatedPath.hxx"
#include "DecoderAPI.hxx"
......@@ -449,9 +450,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;
......
......@@ -412,10 +412,23 @@ 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.GetURI();
#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<char *>(is.GetMimeType());
#endif
return av_probe_input_format(&avpd, true);
}
......
......@@ -82,7 +82,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<unsigned>::max();
*value_r2 = std::numeric_limits<int>::max();
return true;
}
......@@ -109,7 +109,7 @@ check_range(Client &client, unsigned *value_r1, unsigned *value_r2,
}
if (test == test2)
value = std::numeric_limits<unsigned>::max();
value = std::numeric_limits<int>::max();
if (value < 0) {
command_error(client, ACK_ERROR_ARG,
......
#include "config.h"
#include "protocol/ArgParser.hxx"
#include "protocol/Result.hxx"
#include "Compiler.h"
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
static enum ack last_error = ack(-1);
void
command_error(gcc_unused Client &client, enum ack error,
gcc_unused const char *fmt, ...)
{
last_error = error;
}
class ArgParserTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ArgParserTest);
CPPUNIT_TEST(TestRange);
CPPUNIT_TEST_SUITE_END();
public:
void TestRange();
};
void
ArgParserTest::TestRange()
{
Client &client = *(Client *)nullptr;
unsigned a, b;
CPPUNIT_ASSERT(check_range(client, &a, &b, "1"));
CPPUNIT_ASSERT_EQUAL(1u, a);
CPPUNIT_ASSERT_EQUAL(2u, b);
CPPUNIT_ASSERT(check_range(client, &a, &b, "1:5"));
CPPUNIT_ASSERT_EQUAL(1u, a);
CPPUNIT_ASSERT_EQUAL(5u, b);
CPPUNIT_ASSERT(check_range(client, &a, &b, "1:"));
CPPUNIT_ASSERT_EQUAL(1u, a);
CPPUNIT_ASSERT(b >= 999999u);
CPPUNIT_ASSERT(!check_range(client, &a, &b, "-2"));
CPPUNIT_ASSERT_EQUAL(ACK_ERROR_ARG, last_error);
}
CPPUNIT_TEST_SUITE_REGISTRATION(ArgParserTest);
int
main(gcc_unused int argc, gcc_unused char **argv)
{
CppUnit::TextUi::TestRunner runner;
auto &registry = CppUnit::TestFactoryRegistry::getRegistry();
runner.addTest(registry.makeTest());
return runner.run() ? EXIT_SUCCESS : EXIT_FAILURE;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment