diff options
author | Max Kellermann <max@musicpd.org> | 2018-07-21 07:20:59 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2018-07-21 07:24:42 +0200 |
commit | 821f77325ce8e060247424bb4bd17a5e3db1abb8 (patch) | |
tree | cb163e24c66ff0dc137dfb53f7805c250b7729be /src | |
parent | bd8cf7c53d80140f8208d1f6997e5d8d0576524c (diff) |
SongFilter: Parse() throws exception on error
Diffstat (limited to 'src')
-rw-r--r-- | src/SongFilter.cxx | 39 | ||||
-rw-r--r-- | src/SongFilter.hxx | 7 | ||||
-rw-r--r-- | src/command/DatabaseCommands.cxx | 40 | ||||
-rw-r--r-- | src/command/QueueCommands.cxx | 8 |
4 files changed, 52 insertions, 42 deletions
diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx index de43b2fad..dd201d959 100644 --- a/src/SongFilter.cxx +++ b/src/SongFilter.cxx @@ -177,7 +177,6 @@ SongFilter::~SongFilter() /* this destructor exists here just so it won't get inlined */ } -gcc_pure static std::chrono::system_clock::time_point ParseTimeStamp(const char *s) { @@ -189,53 +188,39 @@ ParseTimeStamp(const char *s) /* it's an integral UNIX time stamp */ return std::chrono::system_clock::from_time_t((time_t)value); - try { - /* try ISO 8601 */ - return ParseTimePoint(s, "%FT%TZ"); - } catch (...) { - return std::chrono::system_clock::time_point::min(); - } + /* try ISO 8601 */ + return ParseTimePoint(s, "%FT%TZ"); } -bool +void SongFilter::Parse(const char *tag_string, const char *value, bool fold_case) { unsigned tag = locate_parse_type(tag_string); if (tag == TAG_NUM_OF_ITEM_TYPES) - return false; + throw std::runtime_error("Unknown filter type"); if (tag == LOCATE_TAG_BASE_TYPE) { if (!uri_safe_local(value)) - return false; + throw std::runtime_error("Bad URI"); /* case folding doesn't work with "base" */ fold_case = false; } - if (tag == LOCATE_TAG_MODIFIED_SINCE) { - const auto t = ParseTimeStamp(value); - if (IsNegative(t)) - return false; - - items.push_back(Item(tag, t)); - return true; - } - - items.push_back(Item(tag, value, fold_case)); - return true; + if (tag == LOCATE_TAG_MODIFIED_SINCE) + items.push_back(Item(tag, ParseTimeStamp(value))); + else + items.push_back(Item(tag, value, fold_case)); } -bool +void SongFilter::Parse(ConstBuffer<const char *> args, bool fold_case) { if (args.size == 0 || args.size % 2 != 0) - return false; + throw std::runtime_error("Incorrect number of filter arguments"); for (unsigned i = 0; i < args.size; i += 2) - if (!Parse(args[i], args[i + 1], fold_case)) - return false; - - return true; + Parse(args[i], args[i + 1], fold_case); } bool diff --git a/src/SongFilter.hxx b/src/SongFilter.hxx index 7303d90e3..3f2abcd14 100644 --- a/src/SongFilter.hxx +++ b/src/SongFilter.hxx @@ -112,10 +112,13 @@ public: private: gcc_nonnull(2,3) - bool Parse(const char *tag, const char *value, bool fold_case=false); + void Parse(const char *tag, const char *value, bool fold_case=false); public: - bool Parse(ConstBuffer<const char *> args, bool fold_case=false); + /** + * Throws on error. + */ + void Parse(ConstBuffer<const char *> args, bool fold_case=false); gcc_pure bool Match(const DetachedSong &song) const noexcept; diff --git a/src/command/DatabaseCommands.cxx b/src/command/DatabaseCommands.cxx index 9ab41958b..1b6e59769 100644 --- a/src/command/DatabaseCommands.cxx +++ b/src/command/DatabaseCommands.cxx @@ -31,6 +31,7 @@ #include "tag/ParseName.hxx" #include "tag/Mask.hxx" #include "util/ConstBuffer.hxx" +#include "util/Exception.hxx" #include "util/StringAPI.hxx" #include "SongFilter.hxx" #include "BulkEdit.hxx" @@ -96,8 +97,11 @@ handle_match(Client &client, Request args, Response &r, bool fold_case) } SongFilter filter; - if (!filter.Parse(args, fold_case)) { - r.Error(ACK_ERROR_ARG, "incorrect arguments"); + try { + filter.Parse(args, fold_case); + } catch (...) { + r.Error(ACK_ERROR_ARG, + GetFullMessage(std::current_exception()).c_str()); return CommandResult::ERROR; } @@ -126,8 +130,11 @@ static CommandResult handle_match_add(Client &client, Request args, Response &r, bool fold_case) { SongFilter filter; - if (!filter.Parse(args, fold_case)) { - r.Error(ACK_ERROR_ARG, "incorrect arguments"); + try { + filter.Parse(args, fold_case); + } catch (...) { + r.Error(ACK_ERROR_ARG, + GetFullMessage(std::current_exception()).c_str()); return CommandResult::ERROR; } @@ -157,8 +164,11 @@ handle_searchaddpl(Client &client, Request args, Response &r) const char *playlist = args.shift(); SongFilter filter; - if (!filter.Parse(args, true)) { - r.Error(ACK_ERROR_ARG, "incorrect arguments"); + try { + filter.Parse(args, true); + } catch (...) { + r.Error(ACK_ERROR_ARG, + GetFullMessage(std::current_exception()).c_str()); return CommandResult::ERROR; } @@ -187,9 +197,14 @@ handle_count(Client &client, Request args, Response &r) } SongFilter filter; - if (!args.empty() && !filter.Parse(args, false)) { - r.Error(ACK_ERROR_ARG, "incorrect arguments"); - return CommandResult::ERROR; + if (!args.empty()) { + try { + filter.Parse(args, false); + } catch (...) { + r.Error(ACK_ERROR_ARG, + GetFullMessage(std::current_exception()).c_str()); + return CommandResult::ERROR; + } } PrintSongCount(r, client.GetPartition(), "", &filter, group); @@ -255,8 +270,11 @@ handle_list(Client &client, Request args, Response &r) if (!args.empty()) { filter.reset(new SongFilter()); - if (!filter->Parse(args, false)) { - r.Error(ACK_ERROR_ARG, "not able to parse args"); + try { + filter->Parse(args, false); + } catch (...) { + r.Error(ACK_ERROR_ARG, + GetFullMessage(std::current_exception()).c_str()); return CommandResult::ERROR; } } diff --git a/src/command/QueueCommands.cxx b/src/command/QueueCommands.cxx index 3457842c7..89dd885f3 100644 --- a/src/command/QueueCommands.cxx +++ b/src/command/QueueCommands.cxx @@ -35,6 +35,7 @@ #include "Instance.hxx" #include "BulkEdit.hxx" #include "util/ConstBuffer.hxx" +#include "util/Exception.hxx" #include "util/StringAPI.hxx" #include "util/NumberParser.hxx" @@ -264,8 +265,11 @@ handle_playlist_match(Client &client, Request args, Response &r, bool fold_case) { SongFilter filter; - if (!filter.Parse(args, fold_case)) { - r.Error(ACK_ERROR_ARG, "incorrect arguments"); + try { + filter.Parse(args, fold_case); + } catch (...) { + r.Error(ACK_ERROR_ARG, + GetFullMessage(std::current_exception()).c_str()); return CommandResult::ERROR; } |