diff --git a/NEWS b/NEWS index b0fb7a816..f4cb15cbd 100644 --- a/NEWS +++ b/NEWS @@ -35,17 +35,18 @@ ver 0.22 (not yet released) * switch to C++17 - GCC 7 or clang 4 (or newer) recommended -ver 0.21.21 (not yet released) +ver 0.21.21 (2020/03/19) * configuration - fix bug in "metadata_to_use" setting * playlist - - xspf: fix corrupt tags in the presence of XML entities + - 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 diff --git a/doc/user.rst b/doc/user.rst index 707165618..1b64b3fe9 100644 --- a/doc/user.rst +++ b/doc/user.rst @@ -692,7 +692,7 @@ These settings are various limitations to prevent :program:`MPD` from using too * - **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 --git a/src/Main.cxx b/src/Main.cxx index 40e839b01..b43fb14c8 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -399,7 +399,7 @@ MainConfigured(const struct options &options, const ConfigData &raw_config) #endif const unsigned max_clients = - raw_config.GetPositive(ConfigOption::MAX_CONN, 10); + raw_config.GetPositive(ConfigOption::MAX_CONN, 100); instance.client_list = std::make_unique<ClientList>(max_clients); const auto *input_cache_config = raw_config.GetBlock(ConfigBlockOption::INPUT_CACHE); diff --git a/src/playlist/plugins/AsxPlaylistPlugin.cxx b/src/playlist/plugins/AsxPlaylistPlugin.cxx index 55fb8e262..a96f63f10 100644 --- a/src/playlist/plugins/AsxPlaylistPlugin.cxx +++ b/src/playlist/plugins/AsxPlaylistPlugin.cxx @@ -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" @@ -40,6 +41,7 @@ struct AsxParser { */ enum { ROOT, ENTRY, + TAG, } state{ROOT}; /** @@ -56,8 +58,15 @@ struct AsxParser { TagBuilder tag_builder; - AsxParser() = default; + std::string value; +}; +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 @@ -65,13 +74,13 @@ asx_start_element(void *user_data, const XML_Char *element_name, const XML_Char **atts) { auto *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; @@ -82,14 +91,17 @@ asx_start_element(void *user_data, const XML_Char *element_name, 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; } } @@ -109,11 +121,20 @@ asx_end_element(void *user_data, const XML_Char *element_name) 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 @@ -123,13 +144,11 @@ asx_char_data(void *user_data, const XML_Char *s, int len) switch (parser->state) { case AsxParser::ROOT: + case AsxParser::ENTRY: break; - case AsxParser::ENTRY: - if (parser->tag_type != TAG_NUM_OF_ITEM_TYPES) - parser->tag_builder.AddItem(parser->tag_type, - StringView(s, len)); - + case AsxParser::TAG: + parser->value.append(s, len); break; } }