SongFilter: Parse() throws exception on error
This commit is contained in:
parent
bd8cf7c53d
commit
821f77325c
@ -177,7 +177,6 @@ SongFilter::~SongFilter()
|
|||||||
/* this destructor exists here just so it won't get inlined */
|
/* this destructor exists here just so it won't get inlined */
|
||||||
}
|
}
|
||||||
|
|
||||||
gcc_pure
|
|
||||||
static std::chrono::system_clock::time_point
|
static std::chrono::system_clock::time_point
|
||||||
ParseTimeStamp(const char *s)
|
ParseTimeStamp(const char *s)
|
||||||
{
|
{
|
||||||
@ -189,53 +188,39 @@ ParseTimeStamp(const char *s)
|
|||||||
/* it's an integral UNIX time stamp */
|
/* it's an integral UNIX time stamp */
|
||||||
return std::chrono::system_clock::from_time_t((time_t)value);
|
return std::chrono::system_clock::from_time_t((time_t)value);
|
||||||
|
|
||||||
try {
|
/* try ISO 8601 */
|
||||||
/* try ISO 8601 */
|
return ParseTimePoint(s, "%FT%TZ");
|
||||||
return ParseTimePoint(s, "%FT%TZ");
|
|
||||||
} catch (...) {
|
|
||||||
return std::chrono::system_clock::time_point::min();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
SongFilter::Parse(const char *tag_string, const char *value, bool fold_case)
|
SongFilter::Parse(const char *tag_string, const char *value, bool fold_case)
|
||||||
{
|
{
|
||||||
unsigned tag = locate_parse_type(tag_string);
|
unsigned tag = locate_parse_type(tag_string);
|
||||||
if (tag == TAG_NUM_OF_ITEM_TYPES)
|
if (tag == TAG_NUM_OF_ITEM_TYPES)
|
||||||
return false;
|
throw std::runtime_error("Unknown filter type");
|
||||||
|
|
||||||
if (tag == LOCATE_TAG_BASE_TYPE) {
|
if (tag == LOCATE_TAG_BASE_TYPE) {
|
||||||
if (!uri_safe_local(value))
|
if (!uri_safe_local(value))
|
||||||
return false;
|
throw std::runtime_error("Bad URI");
|
||||||
|
|
||||||
/* case folding doesn't work with "base" */
|
/* case folding doesn't work with "base" */
|
||||||
fold_case = false;
|
fold_case = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag == LOCATE_TAG_MODIFIED_SINCE) {
|
if (tag == LOCATE_TAG_MODIFIED_SINCE)
|
||||||
const auto t = ParseTimeStamp(value);
|
items.push_back(Item(tag, ParseTimeStamp(value)));
|
||||||
if (IsNegative(t))
|
else
|
||||||
return false;
|
items.push_back(Item(tag, value, fold_case));
|
||||||
|
|
||||||
items.push_back(Item(tag, t));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
items.push_back(Item(tag, value, fold_case));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
SongFilter::Parse(ConstBuffer<const char *> args, bool fold_case)
|
SongFilter::Parse(ConstBuffer<const char *> args, bool fold_case)
|
||||||
{
|
{
|
||||||
if (args.size == 0 || args.size % 2 != 0)
|
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)
|
for (unsigned i = 0; i < args.size; i += 2)
|
||||||
if (!Parse(args[i], args[i + 1], fold_case))
|
Parse(args[i], args[i + 1], fold_case);
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -112,10 +112,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
gcc_nonnull(2,3)
|
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:
|
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
|
gcc_pure
|
||||||
bool Match(const DetachedSong &song) const noexcept;
|
bool Match(const DetachedSong &song) const noexcept;
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "tag/ParseName.hxx"
|
#include "tag/ParseName.hxx"
|
||||||
#include "tag/Mask.hxx"
|
#include "tag/Mask.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
#include "util/ConstBuffer.hxx"
|
||||||
|
#include "util/Exception.hxx"
|
||||||
#include "util/StringAPI.hxx"
|
#include "util/StringAPI.hxx"
|
||||||
#include "SongFilter.hxx"
|
#include "SongFilter.hxx"
|
||||||
#include "BulkEdit.hxx"
|
#include "BulkEdit.hxx"
|
||||||
@ -96,8 +97,11 @@ handle_match(Client &client, Request args, Response &r, bool fold_case)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SongFilter filter;
|
SongFilter filter;
|
||||||
if (!filter.Parse(args, fold_case)) {
|
try {
|
||||||
r.Error(ACK_ERROR_ARG, "incorrect arguments");
|
filter.Parse(args, fold_case);
|
||||||
|
} catch (...) {
|
||||||
|
r.Error(ACK_ERROR_ARG,
|
||||||
|
GetFullMessage(std::current_exception()).c_str());
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,8 +130,11 @@ static CommandResult
|
|||||||
handle_match_add(Client &client, Request args, Response &r, bool fold_case)
|
handle_match_add(Client &client, Request args, Response &r, bool fold_case)
|
||||||
{
|
{
|
||||||
SongFilter filter;
|
SongFilter filter;
|
||||||
if (!filter.Parse(args, fold_case)) {
|
try {
|
||||||
r.Error(ACK_ERROR_ARG, "incorrect arguments");
|
filter.Parse(args, fold_case);
|
||||||
|
} catch (...) {
|
||||||
|
r.Error(ACK_ERROR_ARG,
|
||||||
|
GetFullMessage(std::current_exception()).c_str());
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,8 +164,11 @@ handle_searchaddpl(Client &client, Request args, Response &r)
|
|||||||
const char *playlist = args.shift();
|
const char *playlist = args.shift();
|
||||||
|
|
||||||
SongFilter filter;
|
SongFilter filter;
|
||||||
if (!filter.Parse(args, true)) {
|
try {
|
||||||
r.Error(ACK_ERROR_ARG, "incorrect arguments");
|
filter.Parse(args, true);
|
||||||
|
} catch (...) {
|
||||||
|
r.Error(ACK_ERROR_ARG,
|
||||||
|
GetFullMessage(std::current_exception()).c_str());
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,9 +197,14 @@ handle_count(Client &client, Request args, Response &r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SongFilter filter;
|
SongFilter filter;
|
||||||
if (!args.empty() && !filter.Parse(args, false)) {
|
if (!args.empty()) {
|
||||||
r.Error(ACK_ERROR_ARG, "incorrect arguments");
|
try {
|
||||||
return CommandResult::ERROR;
|
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);
|
PrintSongCount(r, client.GetPartition(), "", &filter, group);
|
||||||
@ -255,8 +270,11 @@ handle_list(Client &client, Request args, Response &r)
|
|||||||
|
|
||||||
if (!args.empty()) {
|
if (!args.empty()) {
|
||||||
filter.reset(new SongFilter());
|
filter.reset(new SongFilter());
|
||||||
if (!filter->Parse(args, false)) {
|
try {
|
||||||
r.Error(ACK_ERROR_ARG, "not able to parse args");
|
filter->Parse(args, false);
|
||||||
|
} catch (...) {
|
||||||
|
r.Error(ACK_ERROR_ARG,
|
||||||
|
GetFullMessage(std::current_exception()).c_str());
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "Instance.hxx"
|
#include "Instance.hxx"
|
||||||
#include "BulkEdit.hxx"
|
#include "BulkEdit.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
#include "util/ConstBuffer.hxx"
|
||||||
|
#include "util/Exception.hxx"
|
||||||
#include "util/StringAPI.hxx"
|
#include "util/StringAPI.hxx"
|
||||||
#include "util/NumberParser.hxx"
|
#include "util/NumberParser.hxx"
|
||||||
|
|
||||||
@ -264,8 +265,11 @@ handle_playlist_match(Client &client, Request args, Response &r,
|
|||||||
bool fold_case)
|
bool fold_case)
|
||||||
{
|
{
|
||||||
SongFilter filter;
|
SongFilter filter;
|
||||||
if (!filter.Parse(args, fold_case)) {
|
try {
|
||||||
r.Error(ACK_ERROR_ARG, "incorrect arguments");
|
filter.Parse(args, fold_case);
|
||||||
|
} catch (...) {
|
||||||
|
r.Error(ACK_ERROR_ARG,
|
||||||
|
GetFullMessage(std::current_exception()).c_str());
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user