From 2f46d83834002c05cda42e543f457c5130984228 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@toke.dk>
Date: Thu, 30 Aug 2018 14:01:44 +0200
Subject: [PATCH] subsonic: Catch ValueError when casting input parameters
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

A failed cast to int will raise ValueError, which is not currently caught
by the error checking code, leading to a crash. Fix this so a proper error
message can be returned.

Also add test for getting artist with non-numeric ID.

Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
---
 api/funkwhale_api/subsonic/views.py |  2 +-
 api/tests/subsonic/test_views.py    | 11 +++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/api/funkwhale_api/subsonic/views.py b/api/funkwhale_api/subsonic/views.py
index bb5f441668..de7284cd62 100644
--- a/api/funkwhale_api/subsonic/views.py
+++ b/api/funkwhale_api/subsonic/views.py
@@ -38,7 +38,7 @@ def find_object(queryset, model_field="pk", field="id", cast=int):
                 )
             try:
                 value = cast(raw_value)
-            except (TypeError, ValidationError):
+            except (ValueError, TypeError, ValidationError):
                 return response.Response(
                     {
                         "error": {
diff --git a/api/tests/subsonic/test_views.py b/api/tests/subsonic/test_views.py
index b7431efab4..d9b50d3eb2 100644
--- a/api/tests/subsonic/test_views.py
+++ b/api/tests/subsonic/test_views.py
@@ -102,6 +102,17 @@ def test_get_artist(f, db, logged_in_api_client, factories):
     assert response.data == expected
 
 
+@pytest.mark.parametrize("f", ["xml", "json"])
+def test_get_invalid_artist(f, db, logged_in_api_client, factories):
+    url = reverse("api:subsonic-get-artist")
+    assert url.endswith("getArtist") is True
+    expected = {"error": {"code": 0, "message": 'For input string "asdf"'}}
+    response = logged_in_api_client.get(url, {"id": "asdf"})
+
+    assert response.status_code == 200
+    assert response.data == expected
+
+
 @pytest.mark.parametrize("f", ["xml", "json"])
 def test_get_artist_info2(f, db, logged_in_api_client, factories):
     url = reverse("api:subsonic-get-artist-info2")
-- 
GitLab