Summary
FinancialMutation.search() validates query_string against a regex and, when it does not match, silently discards the filter and runs the search unfiltered for the whole period. The regex also rejects the method's own documented example, so following the docstring produces an unfiltered result set with no error or warning.
Details
moneysnake/financial_mutation.py:119-121:
if query_string and re.match(
r"^[\w]+:[\w\s\-\.]+(?:,[\w]+:[\w\s\-\.]+)*$", query_string
):
filter_parts.insert(0, query_string)
Two problems:
-
Silent discard. A malformed query_string is simply not added to filter_parts — the caller gets all mutations for the period instead of the filtered subset, with no indication anything went wrong. Depending on the account this can also be a much larger response than intended.
-
The regex rejects valid filters, including the docstring's own example. The character class [\w\s\-\.] does not allow >, <, %, or : in values — so the documented example 'state:open,amount:>100' fails validation and is dropped. Verified:
>>> re.match(r"^[\w]+:[\w\s\-\.]+(?:,[\w]+:[\w\s\-\.]+)*$", "amount:>100")
None
Suggested fix
Pick one, in order of preference:
- Drop the regex gatekeeping entirely and pass the filter through — the Moneybird API already rejects malformed filters with a clear error, and the client-side regex is both stricter and wronger than the server's rules.
- Or, if client-side validation is kept:
raise ValueError(f"Invalid filter: {query_string!r}") instead of silently ignoring it, and fix the character class to cover the operators Moneybird supports.
Related
Acceptance criteria
- A malformed
query_string either reaches the API or raises — it is never silently dropped.
- The docstring example works as documented.
- A test covers the previously-rejected
amount:>100 style filter.
Summary
FinancialMutation.search()validatesquery_stringagainst a regex and, when it does not match, silently discards the filter and runs the search unfiltered for the whole period. The regex also rejects the method's own documented example, so following the docstring produces an unfiltered result set with no error or warning.Details
moneysnake/financial_mutation.py:119-121:Two problems:
Silent discard. A malformed
query_stringis simply not added tofilter_parts— the caller gets all mutations for the period instead of the filtered subset, with no indication anything went wrong. Depending on the account this can also be a much larger response than intended.The regex rejects valid filters, including the docstring's own example. The character class
[\w\s\-\.]does not allow>,<,%, or:in values — so the documented example'state:open,amount:>100'fails validation and is dropped. Verified:Suggested fix
Pick one, in order of preference:
raise ValueError(f"Invalid filter: {query_string!r}")instead of silently ignoring it, and fix the character class to cover the operators Moneybird supports.Related
perioddefault is evaluated at import time). The two fixes are independent but touch the same function; they can reasonably land in one change.Acceptance criteria
query_stringeither reaches the API or raises — it is never silently dropped.amount:>100style filter.