mirror of
https://github.com/simonw/datasette.git
synced 2026-10-18 15:26:57 +02:00
Return 400 for unknown ?_search* parameters (#2994)
SearchFilters collected every key starting with _search but resolved the column with split("_search_", 1)[1], so ?_searchfoo= raised IndexError and the table view answered 500. Accept only _search and _search_* and raise BadRequest for any other _search key, matching the Invalid _fts_table or _fts_pk and Cannot search by that column errors already in this function.
This commit is contained in:
parent
cf113a5985
commit
4e2f9b3175
2 changed files with 36 additions and 5 deletions
|
|
@ -66,11 +66,12 @@ def search_filters(request, database, table, datasette):
|
|||
requested_fts_pk and requested_fts_pk != fts_pk
|
||||
):
|
||||
raise BadRequest("Invalid _fts_table or _fts_pk")
|
||||
search_args = {
|
||||
key: request.args[key]
|
||||
for key in request.args
|
||||
if key.startswith("_search") and key != "_searchmode"
|
||||
}
|
||||
search_args = {}
|
||||
for key in request.args:
|
||||
if key == "_search" or key.startswith("_search_"):
|
||||
search_args[key] = request.args[key]
|
||||
elif key != "_searchmode" and key.startswith("_search"):
|
||||
raise BadRequest(f"Invalid _search parameter: {key}")
|
||||
search = ""
|
||||
search_mode_raw = table_metadata.get("searchmode") == "raw"
|
||||
# Or set search mode from the querystring
|
||||
|
|
|
|||
|
|
@ -165,3 +165,33 @@ async def test_search_filters_from_request(ds_client):
|
|||
assert filter_args.params == {"search": "bobcat"}
|
||||
assert filter_args.human_descriptions == ['search matches "bobcat"']
|
||||
assert filter_args.extra_context == {"supports_search": True, "search": "bobcat"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("key", ("_searchfoo", "_search2"))
|
||||
async def test_search_invalid_parameter(ds_client, key):
|
||||
# ?_searchfoo= used to crash with an IndexError from
|
||||
# key.split("_search_", 1)[1] - it should return a 400 like every other
|
||||
# invalid search parameter
|
||||
response = await ds_client.get(f"/fixtures/searchable.json?{key}=bobcat")
|
||||
assert response.status_code == 400
|
||||
assert response.json() == {
|
||||
"ok": False,
|
||||
"error": f"Invalid _search parameter: {key}",
|
||||
"errors": [f"Invalid _search parameter: {key}"],
|
||||
"status": 400,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_search_valid_parameters_still_work(ds_client):
|
||||
# The three documented search parameters keep working
|
||||
response = await ds_client.get(
|
||||
"/fixtures/searchable.json?_shape=arrays&_search=weasel&_searchmode=raw"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["rows"] == [[2, "terry dog", "sara weasel", "puma"]]
|
||||
response = await ds_client.get(
|
||||
"/fixtures/searchable.json?_shape=arrays&_search_text2=dog"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue