From 4a1e9164a1767e4c54664e705cb160442c255ec3 Mon Sep 17 00:00:00 2001 From: TowyTowy Date: Wed, 15 Jul 2026 21:55:46 +0200 Subject: [PATCH] Fix uncaught KeyError on date queries containing a stray pipe The relative-date regex used character classes [+|-] and [y|m|w|d], which mistakenly treat | as a literal member rather than alternation. As a result a value like added:2000|2001 (as a user might type expecting | to mean "or") captured | as the relative-date unit and crashed with an uncaught KeyError in Period.parse instead of raising the documented InvalidQueryArgumentValueError. Remove the stray | from both character classes so malformed date strings fall through to the normal invalid-date error path. Co-Authored-By: Claude --- beets/dbcore/query.py | 2 +- docs/changelog.rst | 5 +++++ test/dbcore/test_datequery.py | 8 ++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index 7a5fecfc3..acb6ce301 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -704,7 +704,7 @@ class Period: "w": 7, "d": 1, } - relative_re = "(?P[+|-]?)(?P[0-9]+)(?P[y|m|w|d])" + relative_re = "(?P[+-]?)(?P[0-9]+)(?P[ymwd])" def __init__(self, date: datetime, precision: str) -> None: """Create a period with the given date (a `datetime` object) and diff --git a/docs/changelog.rst b/docs/changelog.rst index e8bc4f653..401c1ccbb 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -88,6 +88,11 @@ Bug fixes - :doc:`plugins/smartplaylist`: ``splupdate`` no longer crashes with ``TypeError: unhashable type: 'list'`` when a playlist configuration includes a ``playlist:`` query. :bug:`5354` +- A date query containing a stray ``|`` (for example ``added:2000|2001``, as + might be typed by a user expecting ``|`` to mean "or") now raises a clean "a + valid date/time string" error instead of crashing with an uncaught + ``KeyError``. A ``|`` was being accepted as a relative-date unit due to a + regular expression character-class typo. .. For plugin developers diff --git a/test/dbcore/test_datequery.py b/test/dbcore/test_datequery.py index 171080938..282e0e956 100644 --- a/test/dbcore/test_datequery.py +++ b/test/dbcore/test_datequery.py @@ -231,6 +231,14 @@ class DateQueryConstructTest(unittest.TestCase): with pytest.raises(InvalidQueryArgumentValueError): DateQuery("added", q) + def test_pipe_in_relative_date_query(self): + # A stray "|" (e.g. a user expecting OR syntax like "added:2000|2001") + # must raise a clean InvalidQueryArgumentValueError rather than an + # uncaught KeyError from the relative-date parser. + for q in ["2000|2001", "1|", "5|3d"]: + with pytest.raises(InvalidQueryArgumentValueError): + DateQuery("added", q) + def test_datetime_uppercase_t_separator(self): date_query = DateQuery("added", "2000-01-01T12") assert date_query.interval.start == datetime(2000, 1, 1, 12)