Compare commits

...

28 Commits

Author SHA1 Message Date
Max Kellermann
9866adff95 release v0.23.11 2022-11-28 16:55:46 +01:00
Max Kellermann
a8b0c55818 input/curl: make proxy verify setting optional
These settings do not work if CURL was compiled with
CURL_DISABLE_PROXY, and cause error "An unknown option was passed in
to libcurl".

Fixes regression by commit 7ab0dfc8ce
2022-11-28 16:14:01 +01:00
Max Kellermann
cac88e8be5 python/build/libs.py: re-enable verbose error strings
This compile-time option is not about debug logging, but about
curl_easy_strerror().

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1670
2022-11-28 16:12:17 +01:00
Max Kellermann
e9f6a3482c db/Configured: add default "cache_directory" setting 2022-11-28 14:24:52 +01:00
Max Kellermann
5d2e80f188 db/Configured: use GetAppCacheDir() instead of GetUserCacheDir() 2022-11-28 14:20:15 +01:00
Max Kellermann
cfd4d5b13e StateFileConfig: use GetAppCacheDir() instead of GetUserCacheDir() 2022-11-28 14:20:14 +01:00
Max Kellermann
06514aec63 fs/StandardDirectory: add GetAppCacheDir() 2022-11-28 14:19:30 +01:00
Max Kellermann
4ded1ae67b fs/FileSystem: add CreateDirectoryNoThrow() 2022-11-28 14:19:08 +01:00
Max Kellermann
1da974e3fa fs/StandardDirectory: use PACKAGE_NAME from version.h 2022-11-28 14:05:34 +01:00
Max Kellermann
94f06f0946 fs/StandardDirectory: use mode=0777 in mkdir() call
Of course, mode=0700 is more secure, but allowing other users access
to new directories is a choice the user should make via umask().  If
the user-chosen umask allows everybody access, MPD should probably
respect that.
2022-11-28 14:04:47 +01:00
Max Kellermann
d9eec8a455 fs/StandardDirectory: do not use $RUNTIME_DIRECTORY on Android
This is systemd specific, and Android doesn't have systemd.
2022-11-28 10:44:50 +01:00
Max Kellermann
eaecbcafb2 PlaylistFile: disallow backslash in playlist names on Windows
The function spl_valid_name() should verify playlist names and prevent
path traversal, but it failed to do so on Windows, because it forgot
to check for backslashes.

This buggy piece of code was already present when stored playlists
were initially implemented in 2006 by commit 08003904d7, and
even during the many rounds of code refactoring, nobody ever bothered
to verify it.  D'oh!

(Thanks, Paul Arzelier)
2022-11-28 09:53:49 +01:00
Max Kellermann
73b5d0a9b9 system/Error: truncate the snprintf() return value
snprintf() does not return the (truncated) length actually written,
but the length that would be needed if the buffer were large enough.
This API usage mistake in FormatLastError() can lead to overflow of
the stack buffer, crashing the process (Windows only).

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1676
2022-11-28 09:42:37 +01:00
Max Kellermann
c2d0f35e7a storage/meson.build: move StorageState.cxx to "mpd" executable
Fixes spurious linker errors.
2022-11-12 12:24:48 +01:00
Max Kellermann
ab99a57997 test/meson.build: reduce test_translate_song. dependencies 2022-11-12 12:17:35 +01:00
Max Kellermann
c8ebaf3521 python/build/meson.py: use "meson setup" instead of the deprecated syntax 2022-11-12 12:10:06 +01:00
Max Kellermann
52d00f7e30 subprojects: update fmt to 9.1.0 2022-11-11 19:22:39 +01:00
Max Kellermann
309491a6d8 subprojects: update expat to 2.5.0 2022-11-11 19:22:30 +01:00
gd
e7bfd32ccc doc/index.rst: added man pages links to suppress warnings: document isn't included in any toctree 2022-11-08 14:32:40 +01:00
gd
6f283b52ab doc/conf.py: set language = 'en' to suppress warning: Invalid configuration value found 2022-11-08 14:32:32 +01:00
Max Kellermann
32bddfabea archive/plugins/meson.build: do not generate empty library
If no archive library was found, return from the "plugins" directory
without creating "libarchive_plugins.a".  Empty static libraries are
unsupported on some operating systems such as macOS.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1650
2022-11-03 20:36:00 +01:00
Max Kellermann
1944c826bc doc/conf.py: fix version regular expression
Commit 44ef34db88 was broken.
2022-11-03 20:33:08 +01:00
Max Kellermann
619bb60b26 python/build/libs.py: update FLAC to 1.4.2 2022-11-03 10:28:13 +01:00
Max Kellermann
c549e16ed1 python/build/libs.py: update CURL to 7.86.0 2022-11-03 10:28:13 +01:00
Max Kellermann
01c9c4507f python/build/libs.py: update OpenSSL to 3.0.7
Punycode hooray!
2022-11-03 10:28:13 +01:00
Max Kellermann
8c9d7bf07e increment version number to 0.23.11 2022-10-20 19:09:03 +02:00
Max Kellermann
44ef34db88 doc/conf.py: read version number from meson.build 2022-10-20 19:08:27 +02:00
jcorporation
5781f223f6 Document curl plugin .netrc and .curlrc behavior 2022-10-18 22:39:01 +02:00
22 changed files with 144 additions and 44 deletions

12
NEWS

@@ -1,3 +1,15 @@
ver 0.23.11 (2022/11/28)
* database
- simple: move default database to ~/.cache/mpd/db from ~/.cache/mpd.db
- simple: default "cache_directory" to ~/.cache/mpd/mounts
* macOS: fix build failure "no archive members specified"
* Windows
- fix crash bug (stack buffer overflow) after I/O errors
- fix path traversal bug because backslash was allowed in playlist names
* Android/Windows
- update OpenSSL to 3.0.7
- re-enable CURL's verbose error strings
ver 0.23.10 (2022/10/14)
* storage
- curl: fix file time stamps

@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.musicpd"
android:installLocation="auto"
android:versionCode="69"
android:versionName="0.23.10">
android:versionCode="70"
android:versionName="0.23.11">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>

@@ -38,7 +38,10 @@ author = 'Max Kellermann'
# built documents.
#
# The short X.Y version.
version = '0.23.10'
with open('../meson.build') as f:
import re
version = re.match(r"project\([^\)]*\bversion:\s*'([^']+)'",
f.read(4096)).group(1)
# The full version, including alpha/beta/rc tags.
#release = version + '~git'
@@ -47,7 +50,7 @@ version = '0.23.10'
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = "en"
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:

@@ -11,6 +11,12 @@ Music Player Daemon
client
protocol
.. toctree::
:maxdepth: 1
:caption: man pages:
mpd.1
mpd.conf.5
Indices and tables
==================

@@ -219,8 +219,9 @@ Opens remote files or streams over HTTP using libcurl.
Note that unless overridden by the below settings (e.g. by setting
them to a blank value), general curl configuration from environment
variables such as ``http_proxy`` or specified in :file:`~/.curlrc`
will be in effect.
variables such as ``http_proxy`` will be in effect.
User name and password are read from an optional :file:`~/.netrc`, :file:`~/.curlrc` is not read.
.. list-table::
:widths: 20 80

@@ -1,7 +1,7 @@
project(
'mpd',
['c', 'cpp'],
version: '0.23.10',
version: '0.23.11',
meson_version: '>= 0.56.0',
default_options: [
'c_std=c11',
@@ -390,6 +390,7 @@ endif
if enable_database
sources += [
'src/storage/StorageState.cxx',
'src/queue/PlaylistUpdate.cxx',
'src/command/StorageCommands.cxx',
'src/command/DatabaseCommands.cxx',

@@ -43,8 +43,8 @@ opus = AutotoolsProject(
)
flac = AutotoolsProject(
'http://downloads.xiph.org/releases/flac/flac-1.4.0.tar.xz',
'af41c0733c93c237c3e52f64dd87e3b0d9af38259f1c7d11e8cbf583c48c2506',
'http://downloads.xiph.org/releases/flac/flac-1.4.2.tar.xz',
'e322d58a1f48d23d9dd38f432672865f6f79e73a6f9cc5a5f57fcaa83eb5a8e4',
'lib/libFLAC.a',
[
'--disable-shared', '--enable-static',
@@ -387,19 +387,18 @@ ffmpeg = FfmpegProject(
)
openssl = OpenSSLProject(
'https://www.openssl.org/source/openssl-3.0.5.tar.gz',
'aa7d8d9bef71ad6525c55ba11e5f4397889ce49c2c9349dcea6d3e4f0b024a7a',
'https://www.openssl.org/source/openssl-3.0.7.tar.gz',
'83049d042a260e696f62406ac5c08bf706fd84383f945cf21bd61e9ed95c396e',
'include/openssl/ossl_typ.h',
)
curl = CmakeProject(
'https://curl.se/download/curl-7.85.0.tar.xz',
'88b54a6d4b9a48cb4d873c7056dcba997ddd5b7be5a2d537a4acb55c20b04be6',
'https://curl.se/download/curl-7.86.0.tar.xz',
'2d61116e5f485581f6d59865377df4463f2e788677ac43222b496d4e49fb627b',
'lib/libcurl.a',
[
'-DBUILD_CURL_EXE=OFF',
'-DBUILD_SHARED_LIBS=OFF',
'-DCURL_DISABLE_VERBOSE_STRINGS=ON',
'-DCURL_DISABLE_LDAP=ON',
'-DCURL_DISABLE_TELNET=ON',
'-DCURL_DISABLE_DICT=ON',

@@ -82,8 +82,8 @@ endian = '{endian}'
def configure(toolchain, src, build, args=()):
cross_file = make_cross_file(toolchain)
configure = [
'meson',
src, build,
'meson', 'setup',
build, src,
'--prefix', toolchain.install_prefix,

@@ -81,6 +81,9 @@ spl_valid_name(const char *name_utf8)
*/
return std::strchr(name_utf8, '/') == nullptr &&
#ifdef _WIN32
std::strchr(name_utf8, '\\') == nullptr &&
#endif
std::strchr(name_utf8, '\n') == nullptr &&
std::strchr(name_utf8, '\r') == nullptr;
}

@@ -32,7 +32,7 @@ StateFileConfig::StateFileConfig(const ConfigData &config)
{
#ifdef ANDROID
if (path.IsNull()) {
const auto cache_dir = GetUserCacheDir();
const auto cache_dir = GetAppCacheDir();
if (cache_dir.IsNull())
return;

@@ -22,6 +22,10 @@ if libzzip_dep.found()
found_archive_plugin = true
endif
if not found_archive_plugin
subdir_done()
endif
archive_plugins = static_library(
'archive_plugins',
archive_plugins_sources,

@@ -24,6 +24,7 @@
#include "config/Param.hxx"
#include "config/Block.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/FileSystem.hxx"
#include "fs/StandardDirectory.hxx"
#include "util/RuntimeError.hxx"
@@ -51,17 +52,30 @@ CreateConfiguredDatabase(const ConfigData &config,
} else {
/* if there is no override, use the cache directory */
const AllocatedPath cache_dir = GetUserCacheDir();
const AllocatedPath cache_dir = GetAppCacheDir();
if (cache_dir.IsNull())
return nullptr;
const auto db_file = cache_dir / Path::FromFS(PATH_LITERAL("mpd.db"));
const auto db_file = cache_dir / Path::FromFS(PATH_LITERAL("db"));
auto db_file_utf8 = db_file.ToUTF8();
if (db_file_utf8.empty())
return nullptr;
ConfigBlock block;
block.AddBlockParam("path", std::move(db_file_utf8), -1);
{
const auto mounts_dir = cache_dir
/ Path::FromFS(PATH_LITERAL("mounts"));
CreateDirectoryNoThrow(mounts_dir);
if (auto mounts_dir_utf8 = mounts_dir.ToUTF8();
!mounts_dir_utf8.empty())
block.AddBlockParam("cache_directory",
std::move(mounts_dir_utf8),
-1);
}
return DatabaseGlobalInit(main_event_loop, io_event_loop,
listener, block);
}

@@ -67,6 +67,16 @@ StatFile(Path file, struct stat &buf, bool follow_symlinks = true)
#endif
static inline bool
CreateDirectoryNoThrow(Path path) noexcept
{
#ifdef _WIN32
return CreateDirectory(path.c_str(), nullptr);
#else
return mkdir(path.c_str(), 0777);
#endif
}
/**
* Truncate a file that exists already. Throws std::system_error on
* error.

@@ -53,6 +53,12 @@
#include "Main.hxx"
#endif
#ifdef USE_XDG
#include "Version.h" // for PACKAGE_NAME
#define APP_FILENAME PATH_LITERAL(PACKAGE_NAME)
static constexpr Path app_filename = Path::FromFS(APP_FILENAME);
#endif
#if !defined(_WIN32) && !defined(ANDROID)
class PasswdEntry
{
@@ -284,6 +290,24 @@ GetUserCacheDir() noexcept
#endif
}
AllocatedPath
GetAppCacheDir() noexcept
{
#ifdef USE_XDG
if (const auto user_dir = GetUserCacheDir(); !user_dir.IsNull()) {
auto dir = user_dir / app_filename;
CreateDirectoryNoThrow(dir);
return dir;
}
return nullptr;
#elif defined(ANDROID)
return context->GetCacheDir(Java::GetEnv());
#else
return nullptr;
#endif
}
AllocatedPath
GetUserRuntimeDir() noexcept
{
@@ -297,7 +321,7 @@ GetUserRuntimeDir() noexcept
AllocatedPath
GetAppRuntimeDir() noexcept
{
#ifdef __linux__
#if defined(__linux__) && !defined(ANDROID)
/* systemd specific; see systemd.exec(5) */
if (const char *runtime_directory = getenv("RUNTIME_DIRECTORY"))
if (auto dir = StringView{runtime_directory}.Split(':').first;
@@ -307,8 +331,8 @@ GetAppRuntimeDir() noexcept
#ifdef USE_XDG
if (const auto user_dir = GetUserRuntimeDir(); !user_dir.IsNull()) {
auto dir = user_dir / Path::FromFS("mpd");
mkdir(dir.c_str(), 0700);
auto dir = user_dir / app_filename;
CreateDirectoryNoThrow(dir);
return dir;
}
#endif

@@ -43,6 +43,13 @@ GetUserMusicDir() noexcept;
AllocatedPath
GetUserCacheDir() noexcept;
/**
* Obtains cache directory for this application.
*/
[[gnu::const]]
AllocatedPath
GetAppCacheDir() noexcept;
/**
* Obtains the runtime directory for the current user.
*/

@@ -439,8 +439,14 @@ CurlInputStream::InitEasy()
request->SetVerifyPeer(verify_peer);
request->SetVerifyHost(verify_host);
request->SetOption(CURLOPT_HTTPHEADER, request_headers.Get());
request->SetProxyVerifyPeer(verify_peer);
request->SetProxyVerifyHost(verify_host);
try {
request->SetProxyVerifyPeer(verify_peer);
request->SetProxyVerifyHost(verify_host);
} catch (...) {
/* these methods fail if libCURL was compiled with
CURL_DISABLE_PROXY; ignore silently */
}
}
void

@@ -17,7 +17,6 @@ storage_glue = static_library(
'CompositeStorage.cxx',
'MemoryDirectoryReader.cxx',
'Configured.cxx',
'StorageState.cxx',
include_directories: inc,
dependencies: [
boost_dep,
@@ -31,4 +30,3 @@ storage_glue_dep = declare_dependency(
storage_plugins_dep,
],
)

@@ -70,8 +70,11 @@ FormatLastError(DWORD code, const char *fmt, Args&&... args) noexcept
{
char buffer[512];
const auto end = buffer + sizeof(buffer);
size_t length = snprintf(buffer, sizeof(buffer) - 128,
constexpr std::size_t max_prefix = sizeof(buffer) - 128;
size_t length = snprintf(buffer, max_prefix,
fmt, std::forward<Args>(args)...);
if (length >= max_prefix)
length = max_prefix - 1;
char *p = buffer + length;
*p++ = ':';
*p++ = ' ';

@@ -1,12 +1,12 @@
[wrap-file]
directory = expat-2.4.9
source_url = https://github.com/libexpat/libexpat/releases/download/R_2_4_9/expat-2.4.9.tar.xz
source_filename = expat-2.4.9.tar.bz2
source_hash = 6e8c0728fe5c7cd3f93a6acce43046c5e4736c7b4b68e032e9350daa0efc0354
patch_filename = expat_2.4.9-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/expat_2.4.9-1/get_patch
patch_hash = 51b42d935008552f9d6c4d3e7511b84690a2a0c9d90165d1d192fc892f0a4787
wrapdb_version = 2.4.9-1
directory = expat-2.5.0
source_url = https://github.com/libexpat/libexpat/releases/download/R_2_5_0/expat-2.5.0.tar.xz
source_filename = expat-2.5.0.tar.bz2
source_hash = ef2420f0232c087801abf705e89ae65f6257df6b7931d37846a193ef2e8cdcbe
patch_filename = expat_2.5.0-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/expat_2.5.0-1/get_patch
patch_hash = 0d0d6e07ed21cf4892126a8270f5fd182012ab34b3ebe24932a2bef5ca608a61
wrapdb_version = 2.5.0-1
[provide]
expat = expat_dep

@@ -1,12 +1,12 @@
[wrap-file]
directory = fmt-9.0.0
source_url = https://github.com/fmtlib/fmt/archive/9.0.0.tar.gz
source_filename = fmt-9.0.0.tar.gz
source_hash = 9a1e0e9e843a356d65c7604e2c8bf9402b50fe294c355de0095ebd42fb9bd2c5
patch_filename = fmt_9.0.0-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/fmt_9.0.0-1/get_patch
patch_hash = 5f12924065e0fe7ccae40593d256a082955c273cb2880b3e3de05df9d8d10697
wrapdb_version = 9.0.0-1
directory = fmt-9.1.0
source_url = https://github.com/fmtlib/fmt/archive/9.1.0.tar.gz
source_filename = fmt-9.1.0.tar.gz
source_hash = 5dea48d1fcddc3ec571ce2058e13910a0d4a6bab4cc09a809d8b1dd1c88ae6f2
patch_filename = fmt_9.1.0-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/fmt_9.1.0-1/get_patch
patch_hash = 4557b9ba87b3eb63694ed9b21d1a2117d4a97ca56b91085b10288e9a5294adf8
wrapdb_version = 9.1.0-1
[provide]
fmt = fmt_dep

@@ -288,7 +288,8 @@ if enable_database
dependencies: [
log_dep,
tag_dep,
storage_glue_dep,
fs_dep,
storage_plugins_dep,
gtest_dep,
],
),

@@ -14,6 +14,7 @@
#include "ls.hxx"
#include "Log.hxx"
#include "db/DatabaseSong.hxx"
#include "storage/Registry.hxx"
#include "storage/StorageInterface.hxx"
#include "storage/plugins/LocalStorage.hxx"
#include "Mapper.hxx"
@@ -36,6 +37,13 @@ uri_supported_scheme(const char *uri) noexcept
return strncmp(uri, "http://", 7) == 0;
}
const StoragePlugin *
GetStoragePluginByUri(const char *) noexcept
{
// dummy symbol
return nullptr;
}
static constexpr auto music_directory = PATH_LITERAL("/music");
static Storage *storage;