Validate search query values before sending to solr#2161
Conversation
We found that scrapers/attackers construct search urls incorrectly (they double-escape spaces) so we end up with filters like `samplerate:22050+tag:"x"` which parse as `samplerate:22050+tag` and causes solr to raise an error. Validate filter strings and values before sending the result to solr. If it looks invalid then directly return an error page instead of trying the search. Check for errors on search, tag, map bytearray, and clustering views
get_clusters_for_query returns the {"clusters": None} sentinel
when the clustering task fails or times out, so don't try and load
results["graph"] unconditionally
4dfef66 to
c8ef2a5
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds validation for malformed/abuse-style f= filter querystrings so invalid filter values are detected early and do not reach Solr (avoiding Solr parse exceptions and reducing wasted query load).
Changes:
- Introduce
utils.search.filter_validationto parse filters and validate that typed filter fields (e.g.,samplerate,bitrate) have values castable to the expected type. - Integrate filter-type validation into
SearchQueryProcessor, and prevent query param generation when filter errors exist. - Short-circuit clustering and map-bytearray endpoints when
SearchQueryProcessorreports filter errors, with accompanying test coverage.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| utils/tests/test_filter_validation.py | Adds unit tests covering malformed filter encodings, dropped filters, and SQP behavior when errors are present. |
| utils/search/search_query_processor.py | Uses shared filter parsing + type validation and raises when attempting to build query params while errors exist. |
| utils/search/filter_validation.py | New module implementing filter parsing, typed-field validation, and detection of silently dropped +-prefixed filters. |
| search/views.py | Avoids clustering work / returns error JSON when SQP has invalid filters and fixes missing return on error response. |
| search/tests/test_views.py | Adds regression tests ensuring clustering endpoints short-circuit on invalid filters and timeout-like results. |
| geotags/views.py | Avoids Solr querying for map bytearray endpoint when SQP has invalid filters. |
| geotags/tests.py | Adds test ensuring invalid filters yield an empty bytearray response. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ffont
left a comment
There was a problem hiding this comment.
I made a comment with potential changes but maybe for another PR. Also, wouldn't this be useful to avoid using our rather hacky code that compensates for the AND/OR filter terms default change that happened in solr some time ago? Remember we wrote some ugly code to add the + signs? Or did we already get rid of that? :S
| import luqum.tree | ||
| from luqum.parser import parser | ||
|
|
||
| FIELD_TYPES_MAP = { |
There was a problem hiding this comment.
We are starting to "hardcode" search fields information in several places (see
freesound/freesound/settings.py
Line 546 in 176ce1e
There was a problem hiding this comment.
hmm, yeah. we could have a dict of dataclasses or something - with field name, type, default weights, facet values, etc. it should end up consolidating all search field settings into a single location
Description
We found that scrapers/attackers construct search urls incorrectly
(they double-escape spaces) so we end up with filters like
samplerate:22050+tag:"x"which parse assamplerate:22050+tagand causes solr to raise an error.
Validate filter strings and values before sending the result to solr.
If it looks invalid then directly return an error page instead of
trying the search.
Check for errors on search, tag, map bytearray, and clustering views
Deployment steps:
This should have a "real" effect on search results, I expect at least the following: