Hello community, here is the log from the commit of package mpd for openSUSE:Factory checked in at 2020-03-27 22:02:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mpd (Old) and /work/SRC/openSUSE:Factory/.mpd.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "mpd" Fri Mar 27 22:02:26 2020 rev:18 rq:789099 version:0.21.21 Changes: -------- --- /work/SRC/openSUSE:Factory/mpd/mpd.changes 2020-02-27 14:39:47.318335654 +0100 +++ /work/SRC/openSUSE:Factory/.mpd.new.3160/mpd.changes 2020-03-27 22:02:38.914979512 +0100 @@ -1,0 +2,12 @@ +Fri Mar 27 15:53:58 UTC 2020 - Илья Индиго <i...@ilya.pp.ua> + +- Update to 0.21.21 + * https://raw.githubusercontent.com/MusicPlayerDaemon/MPD/v0.21.21/NEWS + * configuration: fix bug in "metadata_to_use" setting + * playlist: asx, xspf: fix corrupt tags in the presence of XML entities + * archive: iso9660: skip empty file names to work around libcdio bug + * decoder: gme: ignore empty tags + * output: solaris: port to NetBSD + * raise default "max_connections" value to 100 + +------------------------------------------------------------------- Old: ---- mpd-0.21.20.tar.xz New: ---- mpd-0.21.21.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mpd.spec ++++++ --- /var/tmp/diff_new_pack.3t1Gj2/_old 2020-03-27 22:02:39.802980028 +0100 +++ /var/tmp/diff_new_pack.3t1Gj2/_new 2020-03-27 22:02:39.806980030 +0100 @@ -20,7 +20,7 @@ %bcond_with faad %bcond_without mpd_iso9660 Name: mpd -Version: 0.21.20 +Version: 0.21.21 Release: 0 Summary: Music Player Daemon License: GPL-2.0-or-later ++++++ mpd-0.21.20.tar.xz -> mpd-0.21.21.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/.travis.yml new/mpd-0.21.21/.travis.yml --- old/mpd-0.21.20/.travis.yml 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/.travis.yml 2020-03-19 15:22:28.000000000 +0100 @@ -1,6 +1,6 @@ language: cpp -matrix: +jobs: include: # Ubuntu Bionic (18.04) with GCC 7 - os: linux @@ -126,6 +126,7 @@ packages: - ccache - meson + update: true env: - MATRIX_EVAL="export PATH=/usr/local/opt/ccache/libexec:$PATH HOMEBREW_NO_ANALYTICS=1" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/NEWS new/mpd-0.21.21/NEWS --- old/mpd-0.21.20/NEWS 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/NEWS 2020-03-19 15:22:28.000000000 +0100 @@ -1,3 +1,16 @@ +ver 0.21.21 (2020/03/19) +* configuration + - fix bug in "metadata_to_use" setting +* playlist + - asx, xspf: fix corrupt tags in the presence of XML entities +* archive + - iso9660: skip empty file names to work around libcdio bug +* decoder + - gme: ignore empty tags +* output + - solaris: port to NetBSD +* raise default "max_connections" value to 100 + ver 0.21.20 (2020/02/16) * decoder - audiofile, ffmpeg, sndfile: handle MIME type "audio/wav" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/android/AndroidManifest.xml new/mpd-0.21.21/android/AndroidManifest.xml --- old/mpd-0.21.20/android/AndroidManifest.xml 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/android/AndroidManifest.xml 2020-03-19 15:22:28.000000000 +0100 @@ -2,8 +2,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.musicpd" android:installLocation="auto" - android:versionCode="43" - android:versionName="0.21.20"> + android:versionCode="44" + android:versionName="0.21.21"> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/doc/conf.py new/mpd-0.21.21/doc/conf.py --- old/mpd-0.21.20/doc/conf.py 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/doc/conf.py 2020-03-19 15:22:28.000000000 +0100 @@ -38,7 +38,7 @@ # built documents. # # The short X.Y version. -version = '0.21.20' +version = '0.21.21' # The full version, including alpha/beta/rc tags. release = version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/doc/user.rst new/mpd-0.21.21/doc/user.rst --- old/mpd-0.21.20/doc/user.rst 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/doc/user.rst 2020-03-19 15:22:28.000000000 +0100 @@ -695,7 +695,7 @@ * - **connection_timeout SECONDS** - If a client does not send any new data in this time period, the connection is closed. Clients waiting in "idle" mode are excluded from this. Default is 60. * - **max_connections NUMBER** - - This specifies the maximum number of clients that can be connected to :program:`MPD` at the same time. Default is 5. + - This specifies the maximum number of clients that can be connected to :program:`MPD` at the same time. Default is 100. * - **max_playlist_length NUMBER** - The maximum number of songs that can be in the playlist. Default is 16384. * - **max_command_list_size KBYTES** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/meson.build new/mpd-0.21.21/meson.build --- old/mpd-0.21.20/meson.build 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/meson.build 2020-03-19 15:22:28.000000000 +0100 @@ -1,7 +1,7 @@ project( 'mpd', ['c', 'cpp'], - version: '0.21.20', + version: '0.21.21', meson_version: '>= 0.49.0', default_options: [ 'c_std=c99', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/Main.cxx new/mpd-0.21.21/src/Main.cxx --- old/mpd-0.21.20/src/Main.cxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/Main.cxx 2020-03-19 15:22:28.000000000 +0100 @@ -460,7 +460,7 @@ #endif const unsigned max_clients = - raw_config.GetPositive(ConfigOption::MAX_CONN, 10); + raw_config.GetPositive(ConfigOption::MAX_CONN, 100); instance->client_list = new ClientList(max_clients); initialize_decoder_and_player(raw_config, config.replay_gain); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/archive/plugins/Iso9660ArchivePlugin.cxx new/mpd-0.21.21/src/archive/plugins/Iso9660ArchivePlugin.cxx --- old/mpd-0.21.20/src/archive/plugins/Iso9660ArchivePlugin.cxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/archive/plugins/Iso9660ArchivePlugin.cxx 2020-03-19 15:22:28.000000000 +0100 @@ -28,6 +28,7 @@ #include "input/InputStream.hxx" #include "fs/Path.hxx" #include "util/RuntimeError.hxx" +#include "util/StringCompare.hxx" #include <cdio/iso9660.h> @@ -93,7 +94,10 @@ auto *statbuf = (iso9660_stat_t *) _cdio_list_node_data(entnode); const char *filename = statbuf->filename; - if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) + if (StringIsEmpty(filename) || + PathTraitsUTF8::IsSpecialFilename(filename)) + /* skip empty names (libcdio bug?) */ + /* skip special names like "." and ".." */ continue; size_t filename_length = strlen(filename); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/db/update/InotifyUpdate.cxx new/mpd-0.21.21/src/db/update/InotifyUpdate.cxx --- old/mpd-0.21.20/src/db/update/InotifyUpdate.cxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/db/update/InotifyUpdate.cxx 2020-03-19 15:22:28.000000000 +0100 @@ -24,6 +24,7 @@ #include "storage/StorageInterface.hxx" #include "fs/AllocatedPath.hxx" #include "fs/FileInfo.hxx" +#include "fs/Traits.hxx" #include "Log.hxx" #include <string> @@ -146,8 +147,7 @@ /* we don't look at "." / ".." nor files with newlines in their name */ static bool skip_path(const char *path) { - return (path[0] == '.' && path[1] == 0) || - (path[0] == '.' && path[1] == '.' && path[2] == 0) || + return PathTraitsFS::IsSpecialFilename(path) || strchr(path, '\n') != nullptr; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/db/update/Walk.cxx new/mpd-0.21.21/src/db/update/Walk.cxx --- old/mpd-0.21.20/src/db/update/Walk.cxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/db/update/Walk.cxx 2020-03-19 15:22:28.000000000 +0100 @@ -237,7 +237,7 @@ LogError(std::current_exception()); } -/* we don't look at "." / ".." nor files with newlines in their name */ +/* we don't look at files with newlines in their name */ gcc_pure static bool skip_path(const char *name_utf8) noexcept diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/decoder/plugins/GmeDecoderPlugin.cxx new/mpd-0.21.21/src/decoder/plugins/GmeDecoderPlugin.cxx --- old/mpd-0.21.20/src/decoder/plugins/GmeDecoderPlugin.cxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/decoder/plugins/GmeDecoderPlugin.cxx 2020-03-19 15:22:28.000000000 +0100 @@ -28,6 +28,7 @@ #include "fs/AllocatedPath.hxx" #include "fs/FileSystem.hxx" #include "util/ScopeExit.hxx" +#include "util/StringCompare.hxx" #include "util/StringFormat.hxx" #include "util/UriUtil.hxx" #include "util/Domain.hxx" @@ -222,7 +223,7 @@ if (track_count > 1) handler.OnTag(TAG_TRACK, StringFormat<16>("%u", song_num + 1)); - if (info.song != nullptr) { + if (!StringIsEmpty(info.song)) { if (track_count > 1) { /* start numbering subtunes from 1 */ const auto tag_title = @@ -234,16 +235,16 @@ handler.OnTag(TAG_TITLE, info.song); } - if (info.author != nullptr) + if (!StringIsEmpty(info.author)) handler.OnTag(TAG_ARTIST, info.author); - if (info.game != nullptr) + if (!StringIsEmpty(info.game)) handler.OnTag(TAG_ALBUM, info.game); - if (info.comment != nullptr) + if (!StringIsEmpty(info.comment)) handler.OnTag(TAG_COMMENT, info.comment); - if (info.copyright != nullptr) + if (!StringIsEmpty(info.copyright)) handler.OnTag(TAG_DATE, info.copyright); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/fs/Traits.hxx new/mpd-0.21.21/src/fs/Traits.hxx --- old/mpd-0.21.20/src/fs/Traits.hxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/fs/Traits.hxx 2020-03-19 15:22:28.000000000 +0100 @@ -109,6 +109,12 @@ } gcc_pure gcc_nonnull_all + static bool IsSpecialFilename(const_pointer_type name) noexcept { + return (name[0] == '.' && name[1] == 0) || + (name[0] == '.' && name[1] == '.' && name[2] == 0); + } + + gcc_pure gcc_nonnull_all static size_t GetLength(const_pointer_type p) noexcept { return StringLength(p); } @@ -217,6 +223,12 @@ } gcc_pure gcc_nonnull_all + static bool IsSpecialFilename(const_pointer_type name) noexcept { + return (name[0] == '.' && name[1] == 0) || + (name[0] == '.' && name[1] == '.' && name[2] == 0); + } + + gcc_pure gcc_nonnull_all static size_t GetLength(const_pointer_type p) noexcept { return StringLength(p); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/output/plugins/SolarisOutputPlugin.cxx new/mpd-0.21.21/src/output/plugins/SolarisOutputPlugin.cxx --- old/mpd-0.21.20/src/output/plugins/SolarisOutputPlugin.cxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/output/plugins/SolarisOutputPlugin.cxx 2020-03-19 15:22:28.000000000 +0100 @@ -22,22 +22,23 @@ #include "system/FileDescriptor.hxx" #include "system/Error.hxx" +#include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> -#ifdef __sun +#if defined(__sun) #include <sys/audio.h> #include <sys/stropts.h> +#elif defined(__NetBSD__) +#include <sys/audioio.h> #else /* some fake declarations that allow build this plugin on systems other than Solaris, just to see if it compiles */ -#include <sys/ioctl.h> - #ifndef I_FLUSH #define I_FLUSH 0 #endif @@ -147,7 +148,11 @@ void SolarisOutput::Cancel() noexcept { +#if defined(AUDIO_FLUSH) + ioctl(fd.Get(), AUDIO_FLUSH); +#elif defined(I_FLUSH) ioctl(fd.Get(), I_FLUSH); +#endif } const struct AudioOutputPlugin solaris_output_plugin = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/playlist/plugins/AsxPlaylistPlugin.cxx new/mpd-0.21.21/src/playlist/plugins/AsxPlaylistPlugin.cxx --- old/mpd-0.21.20/src/playlist/plugins/AsxPlaylistPlugin.cxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/playlist/plugins/AsxPlaylistPlugin.cxx 2020-03-19 15:22:28.000000000 +0100 @@ -21,6 +21,7 @@ #include "../PlaylistPlugin.hxx" #include "../MemorySongEnumerator.hxx" #include "tag/Builder.hxx" +#include "tag/Table.hxx" #include "util/ASCII.hxx" #include "util/StringView.hxx" #include "lib/expat/ExpatParser.hxx" @@ -41,6 +42,7 @@ */ enum { ROOT, ENTRY, + TAG, } state; /** @@ -57,23 +59,33 @@ TagBuilder tag_builder; + std::string value; + AsxParser() :state(ROOT) {} }; +static constexpr struct tag_table asx_tag_elements[] = { + /* is that correct? or should it be COMPOSER or PERFORMER? */ + { "author", TAG_ARTIST }, + + { "title", TAG_TITLE }, + { nullptr, TAG_NUM_OF_ITEM_TYPES } +}; + static void XMLCALL asx_start_element(void *user_data, const XML_Char *element_name, const XML_Char **atts) { AsxParser *parser = (AsxParser *)user_data; + parser->value.clear(); switch (parser->state) { case AsxParser::ROOT: if (StringEqualsCaseASCII(element_name, "entry")) { parser->state = AsxParser::ENTRY; parser->location.clear(); - parser->tag_type = TAG_NUM_OF_ITEM_TYPES; } break; @@ -84,13 +96,16 @@ ExpatParser::GetAttributeCase(atts, "href"); if (href != nullptr) parser->location = href; - } else if (StringEqualsCaseASCII(element_name, "author")) - /* is that correct? or should it be COMPOSER - or PERFORMER? */ - parser->tag_type = TAG_ARTIST; - else if (StringEqualsCaseASCII(element_name, "title")) - parser->tag_type = TAG_TITLE; + } else { + parser->tag_type = tag_table_lookup_i(asx_tag_elements, + element_name); + if (parser->tag_type != TAG_NUM_OF_ITEM_TYPES) + parser->state = AsxParser::TAG; + } + + break; + case AsxParser::TAG: break; } } @@ -111,11 +126,20 @@ parser->tag_builder.Commit()); parser->state = AsxParser::ROOT; - } else - parser->tag_type = TAG_NUM_OF_ITEM_TYPES; + } break; + + case AsxParser::TAG: + if (!parser->value.empty()) + parser->tag_builder.AddItem(parser->tag_type, + StringView(parser->value.data(), + parser->value.length())); + parser->state = AsxParser::ENTRY; + break; } + + parser->value.clear(); } static void XMLCALL @@ -125,13 +149,11 @@ switch (parser->state) { case AsxParser::ROOT: - break; - case AsxParser::ENTRY: - if (parser->tag_type != TAG_NUM_OF_ITEM_TYPES) - parser->tag_builder.AddItem(parser->tag_type, - StringView(s, len)); + break; + case AsxParser::TAG: + parser->value.append(s, len); break; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/playlist/plugins/XspfPlaylistPlugin.cxx new/mpd-0.21.21/src/playlist/plugins/XspfPlaylistPlugin.cxx --- old/mpd-0.21.20/src/playlist/plugins/XspfPlaylistPlugin.cxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/playlist/plugins/XspfPlaylistPlugin.cxx 2020-03-19 15:22:28.000000000 +0100 @@ -23,6 +23,7 @@ #include "song/DetachedSong.hxx" #include "input/InputStream.hxx" #include "tag/Builder.hxx" +#include "tag/Table.hxx" #include "util/StringView.hxx" #include "lib/expat/ExpatParser.hxx" #include "Log.hxx" @@ -44,8 +45,8 @@ */ enum { ROOT, PLAYLIST, TRACKLIST, TRACK, - LOCATION, - } state; + TAG, LOCATION, + } state = ROOT; /** * The current tag within the "track" element. This is only @@ -61,8 +62,20 @@ TagBuilder tag_builder; - XspfParser() - :state(ROOT) {} + std::string value; +}; + +static constexpr struct tag_table xspf_tag_elements[] = { + { "title", TAG_TITLE }, + + /* TAG_COMPOSER would be more correct according to the XSPF + spec */ + { "creator", TAG_ARTIST }, + + { "annotation", TAG_COMMENT }, + { "album", TAG_ALBUM }, + { "trackNum", TAG_TRACK }, + { nullptr, TAG_NUM_OF_ITEM_TYPES } }; static void XMLCALL @@ -70,6 +83,7 @@ gcc_unused const XML_Char **atts) { XspfParser *parser = (XspfParser *)user_data; + parser->value.clear(); switch (parser->state) { case XspfParser::ROOT: @@ -88,7 +102,6 @@ if (strcmp(element_name, "track") == 0) { parser->state = XspfParser::TRACK; parser->location.clear(); - parser->tag_type = TAG_NUM_OF_ITEM_TYPES; } break; @@ -96,21 +109,16 @@ case XspfParser::TRACK: if (strcmp(element_name, "location") == 0) parser->state = XspfParser::LOCATION; - else if (strcmp(element_name, "title") == 0) - parser->tag_type = TAG_TITLE; - else if (strcmp(element_name, "creator") == 0) - /* TAG_COMPOSER would be more correct - according to the XSPF spec */ - parser->tag_type = TAG_ARTIST; - else if (strcmp(element_name, "annotation") == 0) - parser->tag_type = TAG_COMMENT; - else if (strcmp(element_name, "album") == 0) - parser->tag_type = TAG_ALBUM; - else if (strcmp(element_name, "trackNum") == 0) - parser->tag_type = TAG_TRACK; + else if (!parser->location.empty()) { + parser->tag_type = tag_table_lookup(xspf_tag_elements, + element_name); + if (parser->tag_type != TAG_NUM_OF_ITEM_TYPES) + parser->state = XspfParser::TAG; + } break; + case XspfParser::TAG: case XspfParser::LOCATION: break; } @@ -144,15 +152,26 @@ parser->tag_builder.Commit()); parser->state = XspfParser::TRACKLIST; - } else - parser->tag_type = TAG_NUM_OF_ITEM_TYPES; + } + + break; + + case XspfParser::TAG: + if (!parser->value.empty()) + parser->tag_builder.AddItem(parser->tag_type, + StringView(parser->value.data(), + parser->value.length())); + parser->state = XspfParser::TRACK; break; case XspfParser::LOCATION: + parser->location = std::move(parser->value); parser->state = XspfParser::TRACK; break; } + + parser->value.clear(); } static void XMLCALL @@ -164,19 +183,12 @@ case XspfParser::ROOT: case XspfParser::PLAYLIST: case XspfParser::TRACKLIST: - break; - case XspfParser::TRACK: - if (!parser->location.empty() && - parser->tag_type != TAG_NUM_OF_ITEM_TYPES) - parser->tag_builder.AddItem(parser->tag_type, - StringView(s, len)); - break; + case XspfParser::TAG: case XspfParser::LOCATION: - parser->location.assign(s, len); - + parser->value.append(s, len); break; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/storage/plugins/LocalStorage.cxx new/mpd-0.21.21/src/storage/plugins/LocalStorage.cxx --- old/mpd-0.21.20/src/storage/plugins/LocalStorage.cxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/storage/plugins/LocalStorage.cxx 2020-03-19 15:22:28.000000000 +0100 @@ -144,21 +144,12 @@ return std::make_unique<LocalDirectoryReader>(MapFSOrThrow(uri_utf8)); } -gcc_pure -static bool -SkipNameFS(PathTraitsFS::const_pointer_type name_fs) noexcept -{ - return name_fs[0] == '.' && - (name_fs[1] == 0 || - (name_fs[1] == '.' && name_fs[2] == 0)); -} - const char * LocalDirectoryReader::Read() noexcept { while (reader.ReadEntry()) { const Path name_fs = reader.GetEntry(); - if (SkipNameFS(name_fs.c_str())) + if (PathTraitsFS::IsSpecialFilename(name_fs.c_str())) continue; try { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/tag/Mask.hxx new/mpd-0.21.21/src/tag/Mask.hxx --- old/mpd-0.21.20/src/tag/Mask.hxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/tag/Mask.hxx 2020-03-19 15:22:28.000000000 +0100 @@ -89,7 +89,7 @@ } void Unset(TagType tag) { - *this |= ~TagMask(tag); + *this &= ~TagMask(tag); } }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mpd-0.21.20/src/time/ISO8601.cxx new/mpd-0.21.21/src/time/ISO8601.cxx --- old/mpd-0.21.20/src/time/ISO8601.cxx 2020-02-16 20:43:35.000000000 +0100 +++ new/mpd-0.21.21/src/time/ISO8601.cxx 2020-03-19 15:22:28.000000000 +0100 @@ -37,6 +37,7 @@ #include <stdexcept> #include <assert.h> +#include <stdlib.h> StringBuffer<64> FormatISO8601(const struct tm &tm) noexcept