Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8534f2d1e2 | ||
![]() |
665031467a | ||
![]() |
df33171107 | ||
![]() |
53f4044890 | ||
![]() |
a5049136ff | ||
![]() |
705b3c6b63 | ||
![]() |
6b4ac66962 | ||
![]() |
0964b06240 | ||
![]() |
92eeca3ba7 | ||
![]() |
2a86554ac4 | ||
![]() |
805caa30ce | ||
![]() |
acb798e544 | ||
![]() |
773de38bd9 | ||
![]() |
fa4beeee75 | ||
![]() |
d8351772d3 | ||
![]() |
1b5f33a435 | ||
![]() |
41b4a63f2b | ||
![]() |
d8fc2db910 | ||
![]() |
dc11dea7cc | ||
![]() |
04f627c2af | ||
![]() |
a254f5a3a8 | ||
![]() |
143c735f96 | ||
![]() |
7aa2104596 | ||
![]() |
c8b93d6573 | ||
![]() |
3f5f96ac91 | ||
![]() |
7e7b403043 | ||
![]() |
c64ad78c7b | ||
![]() |
4a043a915f | ||
![]() |
38a0d15190 | ||
![]() |
ec3191f502 | ||
![]() |
32b5654a6e | ||
![]() |
674091424e | ||
![]() |
6ad336743d | ||
![]() |
c882568ccd | ||
![]() |
f6b2899dd2 | ||
![]() |
bccd4ef2f7 | ||
![]() |
94c240a026 | ||
![]() |
c50a0cf7bf | ||
![]() |
c37f7abb79 | ||
![]() |
432ce9b1de |
NEWSconfigure.ac
m4
src
Client.hxxClientFile.cxxCompiler.hDatabaseGlue.cxxDecoderPlugin.cxxDecoderThread.cxxDirectory.cxxInputStream.cxxPlaylistFile.cxxPlaylistRegistry.cxxSongFilter.cxx
archive
db
decoder
event
filter
ChainFilterPlugin.cxxNormalizeFilterPlugin.cxxReplayGainFilterPlugin.cxxRouteFilterPlugin.cxxVolumeFilterPlugin.cxx
fs
input
output
playlist
tag
thread
util
test
33
NEWS
33
NEWS
@@ -1,3 +1,36 @@
|
||||
ver 0.18.22 (2014/01/14)
|
||||
* fix clang 3.6 warnings
|
||||
|
||||
ver 0.18.21 (2014/12/17)
|
||||
* playlist
|
||||
- embcue: fix filename suffix detection
|
||||
* decoder
|
||||
- ffmpeg: fix time stamp underflow
|
||||
|
||||
ver 0.18.20 (2014/12/08)
|
||||
* decoder
|
||||
- ffmpeg: support FFmpeg 2.5
|
||||
* fix build failure with musl
|
||||
|
||||
ver 0.18.19 (2014/11/26)
|
||||
* archive
|
||||
- zzip: fix crash after seeking
|
||||
|
||||
ver 0.18.18 (2014/11/18)
|
||||
* decoder
|
||||
- ffmpeg: support opus
|
||||
* fix crash on failed filename charset conversion
|
||||
* fix local socket detection from uid=0 (root)
|
||||
|
||||
ver 0.18.17 (2014/11/02)
|
||||
* playlist
|
||||
- don't allow empty playlist name
|
||||
- m3u: recognize the file suffix ".m3u8"
|
||||
* decoder
|
||||
- ignore URI query string for plugin detection
|
||||
- faad: remove workaround for ancient libfaad2 ABI bug
|
||||
- ffmpeg: recognize MIME type audio/aacp
|
||||
|
||||
ver 0.18.16 (2014/09/26)
|
||||
* fix DSD breakage due to typo in configure.ac
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
AC_PREREQ(2.60)
|
||||
|
||||
AC_INIT(mpd, 0.18.16, mpd-devel@musicpd.org)
|
||||
AC_INIT(mpd, 0.18.22, mpd-devel@musicpd.org)
|
||||
|
||||
VERSION_MAJOR=0
|
||||
VERSION_MINOR=18
|
||||
VERSION_REVISION=0
|
||||
VERSION_REVISION=22
|
||||
VERSION_EXTRA=0
|
||||
|
||||
AC_CONFIG_SRCDIR([src/Main.cxx])
|
||||
@@ -1523,6 +1523,7 @@ results(un,[UNIX Domain Sockets])
|
||||
printf '\nFile format support:\n\t'
|
||||
results(aac, [AAC])
|
||||
results(adplug, [AdPlug])
|
||||
results(dsd, [DSD])
|
||||
results(sidplay, [C64 SID])
|
||||
results(ffmpeg, [FFMPEG])
|
||||
results(flac, [FLAC])
|
||||
|
31
m4/faad.m4
31
m4/faad.m4
@@ -62,36 +62,7 @@ int main() {
|
||||
CPPFLAGS=$oldcppflags
|
||||
fi
|
||||
|
||||
if test x$enable_aac = xyes; then
|
||||
oldcflags=$CFLAGS
|
||||
oldlibs=$LIBS
|
||||
oldcppflags=$CPPFLAGS
|
||||
CFLAGS="$CFLAGS $FAAD_CFLAGS -Werror"
|
||||
LIBS="$LIBS $FAAD_LIBS"
|
||||
CPPFLAGS=$CFLAGS
|
||||
|
||||
AC_MSG_CHECKING(for broken libfaad headers)
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
#include <faad.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int main() {
|
||||
unsigned char channels;
|
||||
uint32_t sample_rate;
|
||||
|
||||
NeAACDecInit2(NULL, NULL, 0, &sample_rate, &channels);
|
||||
return 0;
|
||||
}
|
||||
])],
|
||||
[AC_MSG_RESULT(correct)],
|
||||
[AC_MSG_RESULT(broken);
|
||||
AC_DEFINE(HAVE_FAAD_LONG, 1, [Define if faad.h uses the broken "unsigned long" pointers])])
|
||||
|
||||
CFLAGS=$oldcflags
|
||||
LIBS=$oldlibs
|
||||
CPPFLAGS=$oldcppflags
|
||||
else
|
||||
if test x$enable_aac = xno; then
|
||||
FAAD_LIBS=""
|
||||
FAAD_CFLAGS=""
|
||||
fi
|
||||
|
@@ -109,7 +109,7 @@ public:
|
||||
* a local (UNIX domain) socket?
|
||||
*/
|
||||
bool IsLocal() const {
|
||||
return uid > 0;
|
||||
return uid >= 0;
|
||||
}
|
||||
|
||||
unsigned GetPermission() const {
|
||||
|
@@ -47,7 +47,7 @@ client_allow_file(const Client &client, Path path_fs, Error &error)
|
||||
instance */
|
||||
return true;
|
||||
|
||||
if (uid <= 0) {
|
||||
if (uid < 0) {
|
||||
/* unauthenticated client */
|
||||
error.Set(ack_domain, ACK_ERROR_PERMISSION, "Access denied");
|
||||
return false;
|
||||
|
@@ -20,33 +20,45 @@
|
||||
#ifndef COMPILER_H
|
||||
#define COMPILER_H
|
||||
|
||||
#define GCC_CHECK_VERSION(major, minor) \
|
||||
(defined(__GNUC__) && \
|
||||
(__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
|
||||
#define GCC_MAKE_VERSION(major, minor, patchlevel) ((major) * 10000 + (minor) * 100 + patchlevel)
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define GCC_VERSION (__GNUC__ * 10000 \
|
||||
+ __GNUC_MINOR__ * 100 \
|
||||
+ __GNUC_PATCHLEVEL__)
|
||||
#define GCC_VERSION GCC_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
|
||||
#else
|
||||
#define GCC_VERSION 0
|
||||
#endif
|
||||
|
||||
#define GCC_CHECK_VERSION(major, minor) \
|
||||
(defined(__GNUC__) && GCC_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
|
||||
|
||||
/**
|
||||
* Are we building with gcc (not clang or any other compiler) and a
|
||||
* version older than the specified one?
|
||||
*/
|
||||
#define GCC_OLDER_THAN(major, minor) \
|
||||
(defined(__GNUC__) && !defined(__clang__) && \
|
||||
GCC_VERSION < GCC_MAKE_VERSION(major, minor, 0))
|
||||
|
||||
#ifdef __clang__
|
||||
# define CLANG_VERSION (__clang_major__ * 10000 \
|
||||
+ __clang_minor__ * 100 \
|
||||
+ __clang_patchlevel__)
|
||||
# define CLANG_VERSION GCC_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
|
||||
# if __clang_major__ < 3
|
||||
# error Sorry, your clang version is too old. You need at least version 3.1.
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
# if !GCC_CHECK_VERSION(4,6)
|
||||
# if GCC_OLDER_THAN(4,6)
|
||||
# error Sorry, your gcc version is too old. You need at least version 4.6.
|
||||
# endif
|
||||
#else
|
||||
# warning Untested compiler. Use at your own risk!
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Are we building with the specified version of clang or newer?
|
||||
*/
|
||||
#define CLANG_CHECK_VERSION(major, minor) \
|
||||
(defined(__clang__) && \
|
||||
CLANG_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
|
||||
|
||||
#if GCC_CHECK_VERSION(4,0)
|
||||
|
||||
/* GCC 4.x */
|
||||
@@ -141,7 +153,7 @@
|
||||
#if defined(__cplusplus)
|
||||
|
||||
/* support for C++11 "override" was added in gcc 4.7 */
|
||||
#if !defined(__clang__) && !GCC_CHECK_VERSION(4,7)
|
||||
#if GCC_OLDER_THAN(4,7)
|
||||
#define override
|
||||
#define final
|
||||
#endif
|
||||
|
@@ -112,13 +112,15 @@ db_get_root(void)
|
||||
Directory *
|
||||
db_get_directory(const char *name)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(name != nullptr);
|
||||
#endif
|
||||
|
||||
if (db == nullptr)
|
||||
return nullptr;
|
||||
|
||||
Directory *music_root = db_get_root();
|
||||
if (name == nullptr)
|
||||
return music_root;
|
||||
|
||||
return music_root->LookupDirectory(name);
|
||||
}
|
||||
|
||||
|
@@ -26,7 +26,10 @@
|
||||
bool
|
||||
DecoderPlugin::SupportsSuffix(const char *suffix) const
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(suffix != nullptr);
|
||||
#endif
|
||||
|
||||
return suffixes != nullptr && string_array_contains(suffixes, suffix);
|
||||
|
||||
@@ -35,7 +38,10 @@ DecoderPlugin::SupportsSuffix(const char *suffix) const
|
||||
bool
|
||||
DecoderPlugin::SupportsMimeType(const char *mime_type) const
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(mime_type != nullptr);
|
||||
#endif
|
||||
|
||||
return mime_types != nullptr &&
|
||||
string_array_contains(mime_types, mime_type);
|
||||
|
@@ -212,7 +212,8 @@ static bool
|
||||
decoder_run_stream_locked(Decoder &decoder, InputStream &is,
|
||||
const char *uri, bool &tried_r)
|
||||
{
|
||||
const char *const suffix = uri_get_suffix(uri);
|
||||
UriSuffixBuffer suffix_buffer;
|
||||
const char *const suffix = uri_get_suffix(uri, suffix_buffer);
|
||||
|
||||
using namespace std::placeholders;
|
||||
const auto f = std::bind(decoder_run_stream_plugin,
|
||||
|
@@ -40,7 +40,10 @@ extern "C" {
|
||||
inline Directory *
|
||||
Directory::Allocate(const char *path)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(path != nullptr);
|
||||
#endif
|
||||
|
||||
const size_t path_size = strlen(path) + 1;
|
||||
Directory *directory =
|
||||
|
@@ -155,7 +155,10 @@ InputStream::IsAvailable()
|
||||
size_t
|
||||
InputStream::Read(void *ptr, size_t _size, Error &error)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(ptr != nullptr);
|
||||
#endif
|
||||
assert(_size > 0);
|
||||
|
||||
return plugin.read(this, ptr, _size, error);
|
||||
@@ -164,7 +167,10 @@ InputStream::Read(void *ptr, size_t _size, Error &error)
|
||||
size_t
|
||||
InputStream::LockRead(void *ptr, size_t _size, Error &error)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(ptr != nullptr);
|
||||
#endif
|
||||
assert(_size > 0);
|
||||
|
||||
const ScopeLock protect(mutex);
|
||||
|
@@ -69,6 +69,10 @@ spl_global_init(void)
|
||||
bool
|
||||
spl_valid_name(const char *name_utf8)
|
||||
{
|
||||
if (*name_utf8 == 0)
|
||||
/* empty name not allowed */
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Not supporting '/' was done out of laziness, and we should
|
||||
* really strive to support it in the future.
|
||||
|
@@ -164,12 +164,12 @@ static SongEnumerator *
|
||||
playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond,
|
||||
const bool *tried)
|
||||
{
|
||||
const char *suffix;
|
||||
SongEnumerator *playlist = nullptr;
|
||||
|
||||
assert(uri != nullptr);
|
||||
|
||||
suffix = uri_get_suffix(uri);
|
||||
UriSuffixBuffer suffix_buffer;
|
||||
const char *const suffix = uri_get_suffix(uri, suffix_buffer);
|
||||
if (suffix == nullptr)
|
||||
return nullptr;
|
||||
|
||||
@@ -273,8 +273,6 @@ playlist_list_open_stream_suffix(InputStream &is, const char *suffix)
|
||||
SongEnumerator *
|
||||
playlist_list_open_stream(InputStream &is, const char *uri)
|
||||
{
|
||||
const char *suffix;
|
||||
|
||||
is.LockWaitReady();
|
||||
|
||||
const char *const mime = is.GetMimeType();
|
||||
@@ -284,7 +282,10 @@ playlist_list_open_stream(InputStream &is, const char *uri)
|
||||
return playlist;
|
||||
}
|
||||
|
||||
suffix = uri != nullptr ? uri_get_suffix(uri) : nullptr;
|
||||
UriSuffixBuffer suffix_buffer;
|
||||
const char *suffix = uri != nullptr
|
||||
? uri_get_suffix(uri, suffix_buffer)
|
||||
: nullptr;
|
||||
if (suffix != nullptr) {
|
||||
auto playlist = playlist_list_open_stream_suffix(is, suffix);
|
||||
if (playlist != nullptr)
|
||||
|
@@ -78,7 +78,10 @@ SongFilter::Item::Item(unsigned _tag, const char *_value, bool _fold_case)
|
||||
bool
|
||||
SongFilter::Item::StringMatch(const char *s) const
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(s != nullptr);
|
||||
#endif
|
||||
|
||||
if (fold_case) {
|
||||
char *p = g_utf8_casefold(s, -1);
|
||||
|
@@ -186,12 +186,13 @@ zzip_input_seek(InputStream *is, InputPlugin::offset_type offset,
|
||||
{
|
||||
ZzipInputStream *zis = (ZzipInputStream *)is;
|
||||
zzip_off_t ofs = zzip_seek(zis->file, offset, whence);
|
||||
if (ofs != -1) {
|
||||
if (ofs < 0) {
|
||||
error.Set(zzip_domain, "zzip_seek() has failed");
|
||||
is->offset = ofs;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
is->offset = ofs;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* exported structures */
|
||||
|
@@ -57,7 +57,7 @@ public:
|
||||
virtual void Close() override;
|
||||
virtual Song *GetSong(const char *uri_utf8,
|
||||
Error &error) const override;
|
||||
virtual void ReturnSong(Song *song) const;
|
||||
void ReturnSong(Song *song) const override;
|
||||
|
||||
virtual bool Visit(const DatabaseSelection &selection,
|
||||
VisitDirectory visit_directory,
|
||||
@@ -592,7 +592,7 @@ ProxyDatabase::Visit(const DatabaseSelection &selection,
|
||||
{
|
||||
// TODO: eliminate the const_cast
|
||||
if (!const_cast<ProxyDatabase *>(this)->EnsureConnected(error))
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
if (!visit_directory && !visit_playlist && selection.recursive &&
|
||||
(ServerSupportsSearchBase(connection)
|
||||
@@ -617,7 +617,7 @@ ProxyDatabase::VisitUniqueTags(const DatabaseSelection &selection,
|
||||
{
|
||||
// TODO: eliminate the const_cast
|
||||
if (!const_cast<ProxyDatabase *>(this)->EnsureConnected(error))
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
enum mpd_tag_type tag_type2 = Convert(tag_type);
|
||||
if (tag_type2 == MPD_TAG_COUNT) {
|
||||
@@ -657,7 +657,7 @@ ProxyDatabase::GetStats(const DatabaseSelection &selection,
|
||||
|
||||
// TODO: eliminate the const_cast
|
||||
if (!const_cast<ProxyDatabase *>(this)->EnsureConnected(error))
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
struct mpd_stats *stats2 =
|
||||
mpd_run_stats(connection);
|
||||
|
@@ -61,7 +61,7 @@ public:
|
||||
|
||||
virtual Song *GetSong(const char *uri_utf8,
|
||||
Error &error) const override;
|
||||
virtual void ReturnSong(Song *song) const;
|
||||
void ReturnSong(Song *song) const override;
|
||||
|
||||
virtual bool Visit(const DatabaseSelection &selection,
|
||||
VisitDirectory visit_directory,
|
||||
|
@@ -277,20 +277,12 @@ faad_decoder_init(NeAACDecHandle decoder, DecoderBuffer *buffer,
|
||||
}
|
||||
|
||||
uint8_t channels;
|
||||
uint32_t sample_rate;
|
||||
#ifdef HAVE_FAAD_LONG
|
||||
/* neaacdec.h declares all arguments as "unsigned long", but
|
||||
internally expects uint32_t pointers. To avoid gcc
|
||||
warnings, use this workaround. */
|
||||
unsigned long *sample_rate_p = (unsigned long *)(void *)&sample_rate;
|
||||
#else
|
||||
uint32_t *sample_rate_p = &sample_rate;
|
||||
#endif
|
||||
unsigned long sample_rate;
|
||||
long nbytes = NeAACDecInit(decoder,
|
||||
/* deconst hack, libfaad requires this */
|
||||
const_cast<unsigned char *>(data),
|
||||
length,
|
||||
sample_rate_p, &channels);
|
||||
&sample_rate, &channels);
|
||||
if (nbytes < 0) {
|
||||
error.Set(faad_decoder_domain, "Not an AAC stream");
|
||||
return false;
|
||||
|
@@ -284,10 +284,13 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is,
|
||||
AVFrame *frame,
|
||||
uint8_t **buffer, int *buffer_size)
|
||||
{
|
||||
if (packet->pts >= 0 && packet->pts != (int64_t)AV_NOPTS_VALUE)
|
||||
decoder_timestamp(decoder,
|
||||
time_from_ffmpeg(packet->pts - start_time_fallback(*stream),
|
||||
stream->time_base));
|
||||
if (packet->pts >= 0 && packet->pts != (int64_t)AV_NOPTS_VALUE) {
|
||||
auto start = start_time_fallback(*stream);
|
||||
if (packet->pts >= start)
|
||||
decoder_timestamp(decoder,
|
||||
time_from_ffmpeg(packet->pts - start,
|
||||
stream->time_base));
|
||||
}
|
||||
|
||||
AVPacket packet2 = *packet;
|
||||
|
||||
@@ -394,10 +397,15 @@ ffmpeg_probe(Decoder *decoder, InputStream &is)
|
||||
avpd.filename = is.uri.c_str();
|
||||
|
||||
#ifdef AVPROBE_SCORE_MIME
|
||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(56, 5, 1)
|
||||
/* 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());
|
||||
#else
|
||||
/* API problem fixed in FFmpeg 2.5 */
|
||||
avpd.mime_type = is.GetMimeType();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return av_probe_input_format(&avpd, true);
|
||||
@@ -620,7 +628,7 @@ static const char *const ffmpeg_suffixes[] = {
|
||||
"mj2", "mjpeg", "mjpg", "mka", "mkv", "mlp", "mm", "mmf", "mov", "mp+",
|
||||
"mp1", "mp2", "mp3", "mp4", "mpc", "mpeg", "mpg", "mpga", "mpp", "mpu",
|
||||
"mve", "mvi", "mxf", "nc", "nsv", "nut", "nuv", "oga", "ogm", "ogv",
|
||||
"ogx", "oma", "ogg", "omg", "psp", "pva", "qcp", "qt", "r3d", "ra",
|
||||
"ogx", "oma", "ogg", "omg", "opus", "psp", "pva", "qcp", "qt", "r3d", "ra",
|
||||
"ram", "rl2", "rm", "rmvb", "roq", "rpl", "rvc", "shn", "smk", "snd",
|
||||
"sol", "son", "spx", "str", "swf", "tgi", "tgq", "tgv", "thp", "ts",
|
||||
"tsp", "tta", "xa", "xvid", "uv", "uv2", "vb", "vid", "vob", "voc",
|
||||
@@ -643,6 +651,7 @@ static const char *const ffmpeg_mime_types[] = {
|
||||
"audio/8svx",
|
||||
"audio/16sv",
|
||||
"audio/aac",
|
||||
"audio/aacp",
|
||||
"audio/ac3",
|
||||
"audio/aiff"
|
||||
"audio/amr",
|
||||
@@ -653,6 +662,7 @@ static const char *const ffmpeg_mime_types[] = {
|
||||
"audio/mpeg",
|
||||
"audio/musepack",
|
||||
"audio/ogg",
|
||||
"audio/opus",
|
||||
"audio/qcelp",
|
||||
"audio/vorbis",
|
||||
"audio/vorbis+ogg",
|
||||
|
@@ -141,7 +141,7 @@ get_remote_uid(int fd)
|
||||
socklen_t len = sizeof (cred);
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
return cred.uid;
|
||||
#else
|
||||
|
@@ -52,10 +52,11 @@ public:
|
||||
children.emplace_back(name, filter);
|
||||
}
|
||||
|
||||
virtual AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
virtual void Close();
|
||||
virtual const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r, Error &error);
|
||||
/* virtual methods from class Filter */
|
||||
AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
void Close() override;
|
||||
const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r, Error &error) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@@ -34,10 +34,11 @@ class NormalizeFilter final : public Filter {
|
||||
PcmBuffer buffer;
|
||||
|
||||
public:
|
||||
virtual AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
virtual void Close();
|
||||
virtual const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r, Error &error);
|
||||
/* virtual methods from class Filter */
|
||||
AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
void Close() override;
|
||||
const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r, Error &error) override;
|
||||
};
|
||||
|
||||
static Filter *
|
||||
|
@@ -116,10 +116,11 @@ public:
|
||||
*/
|
||||
void Update();
|
||||
|
||||
virtual AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
virtual void Close();
|
||||
virtual const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r, Error &error);
|
||||
/* virtual methods from class Filter */
|
||||
AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
void Close() override;
|
||||
const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r, Error &error) override;
|
||||
};
|
||||
|
||||
void
|
||||
|
@@ -120,10 +120,11 @@ public:
|
||||
*/
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
|
||||
virtual AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
virtual void Close();
|
||||
virtual const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r, Error &error);
|
||||
/* virtual methods from class Filter */
|
||||
AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
void Close() override;
|
||||
const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r, Error &error) override;
|
||||
};
|
||||
|
||||
bool
|
||||
|
@@ -57,10 +57,10 @@ public:
|
||||
volume = _volume;
|
||||
}
|
||||
|
||||
virtual AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
virtual void Close();
|
||||
virtual const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r, Error &error);
|
||||
AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
void Close() override;
|
||||
const void *FilterPCM(const void *src, size_t src_size,
|
||||
size_t *dest_size_r, Error &error) override;
|
||||
};
|
||||
|
||||
static constexpr Domain volume_domain("pcm_volume");
|
||||
|
@@ -46,7 +46,11 @@ AllocatedPath::Build(const_pointer a, const_pointer b)
|
||||
AllocatedPath
|
||||
AllocatedPath::FromUTF8(const char *path_utf8)
|
||||
{
|
||||
return AllocatedPath(Donate(), ::PathFromUTF8(path_utf8));
|
||||
char *path = ::PathFromUTF8(path_utf8);
|
||||
if (path == nullptr)
|
||||
return AllocatedPath::Null();
|
||||
|
||||
return AllocatedPath(Donate(), path);
|
||||
}
|
||||
|
||||
AllocatedPath
|
||||
|
@@ -79,7 +79,10 @@ GetFSCharset()
|
||||
std::string
|
||||
PathToUTF8(const char *path_fs)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(path_fs != nullptr);
|
||||
#endif
|
||||
|
||||
if (fs_charset.empty())
|
||||
return std::string(path_fs);
|
||||
@@ -109,7 +112,10 @@ PathToUTF8(const char *path_fs)
|
||||
char *
|
||||
PathFromUTF8(const char *path_utf8)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(path_utf8 != nullptr);
|
||||
#endif
|
||||
|
||||
if (fs_charset.empty())
|
||||
return g_strdup(path_utf8);
|
||||
|
@@ -25,7 +25,10 @@
|
||||
const char *
|
||||
PathTraits::GetBaseUTF8(const char *p)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(p != nullptr);
|
||||
#endif
|
||||
|
||||
const char *slash = strrchr(p, SEPARATOR_UTF8);
|
||||
return slash != nullptr
|
||||
@@ -36,7 +39,10 @@ PathTraits::GetBaseUTF8(const char *p)
|
||||
std::string
|
||||
PathTraits::GetParentUTF8(const char *p)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(p != nullptr);
|
||||
#endif
|
||||
|
||||
const char *slash = strrchr(p, SEPARATOR_UTF8);
|
||||
return slash != nullptr
|
||||
|
@@ -983,10 +983,10 @@ input_curl_easy_init(struct input_curl *c, Error &error)
|
||||
input_curl_writefunction);
|
||||
curl_easy_setopt(c->easy, CURLOPT_WRITEDATA, c);
|
||||
curl_easy_setopt(c->easy, CURLOPT_HTTP200ALIASES, http_200_aliases);
|
||||
curl_easy_setopt(c->easy, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(c->easy, CURLOPT_NETRC, 1);
|
||||
curl_easy_setopt(c->easy, CURLOPT_MAXREDIRS, 5);
|
||||
curl_easy_setopt(c->easy, CURLOPT_FAILONERROR, true);
|
||||
curl_easy_setopt(c->easy, CURLOPT_FOLLOWLOCATION, 1l);
|
||||
curl_easy_setopt(c->easy, CURLOPT_NETRC, 1l);
|
||||
curl_easy_setopt(c->easy, CURLOPT_MAXREDIRS, 5l);
|
||||
curl_easy_setopt(c->easy, CURLOPT_FAILONERROR, 1l);
|
||||
curl_easy_setopt(c->easy, CURLOPT_ERRORBUFFER, c->error);
|
||||
curl_easy_setopt(c->easy, CURLOPT_NOPROGRESS, 1l);
|
||||
curl_easy_setopt(c->easy, CURLOPT_NOSIGNAL, 1l);
|
||||
|
@@ -46,7 +46,7 @@ class RoarOutput {
|
||||
struct roar_connection con;
|
||||
struct roar_audio_info info;
|
||||
mutable Mutex mutex;
|
||||
volatile bool alive;
|
||||
bool alive;
|
||||
|
||||
public:
|
||||
RoarOutput()
|
||||
|
@@ -114,7 +114,7 @@ ShoutOutput::Configure(const config_param ¶m, Error &error)
|
||||
if (!audio_format.IsFullyDefined()) {
|
||||
error.Set(config_domain,
|
||||
"Need full audio format specification");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *host = require_block_string(param, "host");
|
||||
|
@@ -178,7 +178,7 @@ const struct playlist_plugin embcue_playlist_plugin = {
|
||||
embcue_playlist_open_uri,
|
||||
nullptr,
|
||||
|
||||
nullptr,
|
||||
embcue_playlist_suffixes,
|
||||
nullptr,
|
||||
nullptr,
|
||||
};
|
||||
|
@@ -135,7 +135,8 @@ ExtM3uPlaylist::NextSong()
|
||||
|
||||
static const char *const extm3u_suffixes[] = {
|
||||
"m3u",
|
||||
NULL
|
||||
"m3u8",
|
||||
nullptr
|
||||
};
|
||||
|
||||
static const char *const extm3u_mime_types[] = {
|
||||
|
@@ -61,6 +61,7 @@ M3uPlaylist::NextSong()
|
||||
|
||||
static const char *const m3u_suffixes[] = {
|
||||
"m3u",
|
||||
"m3u8",
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
@@ -77,7 +77,10 @@ TagBuilder::Commit()
|
||||
inline void
|
||||
TagBuilder::AddItemInternal(TagType type, const char *value, size_t length)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(value != nullptr);
|
||||
#endif
|
||||
assert(length > 0);
|
||||
|
||||
char *p = FixTagString(value, length);
|
||||
@@ -98,7 +101,10 @@ TagBuilder::AddItemInternal(TagType type, const char *value, size_t length)
|
||||
void
|
||||
TagBuilder::AddItem(TagType type, const char *value, size_t length)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(value != nullptr);
|
||||
#endif
|
||||
|
||||
if (length == 0 || ignore_tag_items[type])
|
||||
return;
|
||||
@@ -109,7 +115,10 @@ TagBuilder::AddItem(TagType type, const char *value, size_t length)
|
||||
void
|
||||
TagBuilder::AddItem(TagType type, const char *value)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(value != nullptr);
|
||||
#endif
|
||||
|
||||
AddItem(type, value, strlen(value));
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ patch_utf8(const char *src, size_t length, const gchar *end)
|
||||
{
|
||||
/* duplicate the string, and replace invalid bytes in that
|
||||
buffer */
|
||||
char *dest = g_strdup(src);
|
||||
char *dest = g_strndup(src, length);
|
||||
|
||||
do {
|
||||
dest[end - src] = '?';
|
||||
|
@@ -75,7 +75,7 @@ public:
|
||||
#ifdef WIN32
|
||||
return ::GetCurrentThreadId();
|
||||
#else
|
||||
return ::pthread_self();
|
||||
return pthread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
#ifdef WIN32
|
||||
return id == other.id;
|
||||
#else
|
||||
return ::pthread_equal(id, other.id);
|
||||
return pthread_equal(id, other.id);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -43,24 +43,30 @@ gcc_pure gcc_nonnull_all
|
||||
static inline bool
|
||||
StringEqualsCaseASCII(const char *a, const char *b)
|
||||
{
|
||||
assert(a != nullptr);
|
||||
assert(b != nullptr);
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(a != nullptr);
|
||||
assert(b != nullptr);
|
||||
#endif
|
||||
|
||||
/* note: strcasecmp() depends on the locale, but for ASCII-only
|
||||
strings, it's safe to use */
|
||||
return strcasecmp(a, b) == 0;
|
||||
/* note: strcasecmp() depends on the locale, but for ASCII-only
|
||||
strings, it's safe to use */
|
||||
return strcasecmp(a, b) == 0;
|
||||
}
|
||||
|
||||
gcc_pure gcc_nonnull_all
|
||||
static inline bool
|
||||
StringEqualsCaseASCII(const char *a, const char *b, size_t n)
|
||||
{
|
||||
assert(a != nullptr);
|
||||
assert(b != nullptr);
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(a != nullptr);
|
||||
assert(b != nullptr);
|
||||
#endif
|
||||
|
||||
/* note: strcasecmp() depends on the locale, but for ASCII-only
|
||||
strings, it's safe to use */
|
||||
return strncasecmp(a, b, n) == 0;
|
||||
/* note: strcasecmp() depends on the locale, but for ASCII-only
|
||||
strings, it's safe to use */
|
||||
return strncasecmp(a, b, n) == 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -35,7 +35,7 @@
|
||||
#include <new>
|
||||
#include <utility>
|
||||
|
||||
#if !defined(__clang__) && __GNUC__ && !GCC_CHECK_VERSION(4,8)
|
||||
#if GCC_OLDER_THAN(4,8)
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
*/
|
||||
template<class T>
|
||||
class Manual {
|
||||
#if !defined(__clang__) && __GNUC__ && !GCC_CHECK_VERSION(4,8)
|
||||
#if GCC_OLDER_THAN(4,8)
|
||||
/* no alignas() on gcc < 4.8: apply worst-case fallback */
|
||||
__attribute__((aligned(8)))
|
||||
#else
|
||||
|
@@ -44,6 +44,23 @@ uri_get_suffix(const char *uri)
|
||||
return suffix;
|
||||
}
|
||||
|
||||
const char *
|
||||
uri_get_suffix(const char *uri, UriSuffixBuffer &buffer)
|
||||
{
|
||||
const char *suffix = uri_get_suffix(uri);
|
||||
if (suffix == nullptr)
|
||||
return nullptr;
|
||||
|
||||
const char *q = strchr(suffix, '?');
|
||||
if (q != nullptr && size_t(q - suffix) < sizeof(buffer.data)) {
|
||||
memcpy(buffer.data, suffix, q - suffix);
|
||||
buffer.data[q - suffix] = 0;
|
||||
suffix = buffer.data;
|
||||
}
|
||||
|
||||
return suffix;
|
||||
}
|
||||
|
||||
static const char *
|
||||
verify_uri_segment(const char *p)
|
||||
{
|
||||
@@ -111,8 +128,11 @@ uri_remove_auth(const char *uri)
|
||||
bool
|
||||
uri_is_child(const char *parent, const char *child)
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(parent != nullptr);
|
||||
assert(child != nullptr);
|
||||
#endif
|
||||
|
||||
const size_t parent_length = strlen(parent);
|
||||
return memcmp(parent, child, parent_length) == 0 &&
|
||||
|
@@ -35,6 +35,17 @@ gcc_pure
|
||||
const char *
|
||||
uri_get_suffix(const char *uri);
|
||||
|
||||
struct UriSuffixBuffer {
|
||||
char data[8];
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the file name suffix, ignoring the query string.
|
||||
*/
|
||||
gcc_pure
|
||||
const char *
|
||||
uri_get_suffix(const char *uri, UriSuffixBuffer &buffer);
|
||||
|
||||
/**
|
||||
* Returns true if this is a safe "local" URI:
|
||||
*
|
||||
|
@@ -33,6 +33,25 @@ public:
|
||||
uri_get_suffix(".jpg"));
|
||||
CPPUNIT_ASSERT_EQUAL((const char *)nullptr,
|
||||
uri_get_suffix("/foo/.jpg"));
|
||||
|
||||
/* the first overload does not eliminate the query
|
||||
string */
|
||||
CPPUNIT_ASSERT_EQUAL(0, strcmp(uri_get_suffix("/foo/bar.jpg?query_string"),
|
||||
"jpg?query_string"));
|
||||
|
||||
/* ... but the second one does */
|
||||
UriSuffixBuffer buffer;
|
||||
CPPUNIT_ASSERT_EQUAL(0, strcmp(uri_get_suffix("/foo/bar.jpg?query_string",
|
||||
buffer),
|
||||
"jpg"));
|
||||
|
||||
/* repeat some of the above tests with the second overload */
|
||||
CPPUNIT_ASSERT_EQUAL((const char *)nullptr,
|
||||
uri_get_suffix("/foo/bar", buffer));
|
||||
CPPUNIT_ASSERT_EQUAL((const char *)nullptr,
|
||||
uri_get_suffix("/foo.jpg/bar", buffer));
|
||||
CPPUNIT_ASSERT_EQUAL(0, strcmp(uri_get_suffix("/foo/bar.jpg", buffer),
|
||||
"jpg"));
|
||||
}
|
||||
|
||||
void TestRemoveAuth() {
|
||||
|
Reference in New Issue
Block a user