Commit ac0852b4 authored by Max Kellermann's avatar Max Kellermann

song/Filter: operator "==" never searches substrings in filter expressions

The protocol documentation says that the difference between `find` and `search` is that `search` is case insensitive, but that's only half the truth: `search` also searches for sub strings instead of matching the whole string. This part is undocumented and unfortunate, but at this point, we can't change it. However leaking this surprising behavior to the new filter expressions was a bad idea; the "==" operator should never match substrings. For people who need that, we should add a new operator.
parent 6fe43ed9
ver 0.21.1 (not yet released)
* protocol
- allow escaping quotes in filter expressions
- operator "==" never searches substrings in filter expressions
* decoder
- ffmpeg: fix build failure with non-standard FFmpeg installation path
- flac: fix linker failure when building without FLAC support
......
......@@ -91,8 +91,11 @@ locate_parse_type(const char *str) noexcept
SongFilter::SongFilter(TagType tag, const char *value, bool fold_case)
{
/* for compatibility with MPD 0.20 and older, "fold_case" also
switches on "substring" */
and_filter.AddItem(std::make_unique<TagSongFilter>(tag, value,
fold_case, false));
fold_case, fold_case,
false));
}
SongFilter::~SongFilter()
......@@ -296,11 +299,13 @@ SongFilter::ParseExpression(const char *&s, bool fold_case)
if (type == LOCATE_TAG_FILE_TYPE)
return std::make_unique<UriSongFilter>(std::move(value),
fold_case,
false,
negated);
return std::make_unique<TagSongFilter>(TagType(type),
std::move(value),
fold_case, negated);
fold_case, false,
negated);
}
}
......@@ -325,8 +330,11 @@ SongFilter::Parse(const char *tag_string, const char *value, bool fold_case)
break;
case LOCATE_TAG_FILE_TYPE:
/* for compatibility with MPD 0.20 and older,
"fold_case" also switches on "substring" */
and_filter.AddItem(std::make_unique<UriSongFilter>(value,
fold_case,
fold_case,
false));
break;
......@@ -334,9 +342,12 @@ SongFilter::Parse(const char *tag_string, const char *value, bool fold_case)
if (tag == LOCATE_TAG_ANY_TYPE)
tag = TAG_NUM_OF_ITEM_TYPES;
/* for compatibility with MPD 0.20 and older,
"fold_case" also switches on "substring" */
and_filter.AddItem(std::make_unique<TagSongFilter>(TagType(tag),
value,
fold_case,
fold_case,
false));
break;
}
......
......@@ -40,12 +40,12 @@ class StringFilter {
public:
template<typename V>
StringFilter(V &&_value, bool _fold_case)
StringFilter(V &&_value, bool _fold_case, bool _substring)
:value(std::forward<V>(_value)),
fold_case(_fold_case
? IcuCompare(value.c_str())
: IcuCompare()),
substring(_fold_case) {}
substring(_substring) {}
bool empty() const noexcept {
return value.empty();
......
......@@ -42,9 +42,10 @@ class TagSongFilter final : public ISongFilter {
public:
template<typename V>
TagSongFilter(TagType _type, V &&_value, bool fold_case, bool _negated)
TagSongFilter(TagType _type, V &&_value, bool fold_case, bool substring,
bool _negated)
:type(_type), negated(_negated),
filter(std::forward<V>(_value), fold_case) {}
filter(std::forward<V>(_value), fold_case, substring) {}
TagType GetTagType() const {
return type;
......
......@@ -32,8 +32,9 @@ class UriSongFilter final : public ISongFilter {
public:
template<typename V>
UriSongFilter(V &&_value, bool fold_case, bool _negated)
:filter(std::forward<V>(_value), fold_case),
UriSongFilter(V &&_value, bool fold_case, bool substring,
bool _negated)
:filter(std::forward<V>(_value), fold_case, substring),
negated(_negated) {}
const auto &GetValue() const noexcept {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment