Don't crash if JSON is valid but of wrong schema
This commit is contained in:
parent
bffbb051f2
commit
9c3310a8b6
@ -14,6 +14,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import jsonschema
|
||||||
import select
|
import select
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
@ -177,7 +178,8 @@ class WebServer:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
params = json.loads(req.body.decode('utf-8'))
|
params = json.loads(req.body.decode('utf-8'))
|
||||||
except ValueError as e:
|
jsonschema.validate(params, request_schema)
|
||||||
|
except (ValueError, jsonschema.ValidationError) as e:
|
||||||
if allowed:
|
if allowed:
|
||||||
if len(req.body) == 0:
|
if len(req.body) == 0:
|
||||||
body = f"AnkiConnect v.{util.setting('apiVersion')}".encode()
|
body = f"AnkiConnect v.{util.setting('apiVersion')}".encode()
|
||||||
@ -286,3 +288,14 @@ def format_success_reply(api_version, result):
|
|||||||
|
|
||||||
def format_exception_reply(_api_version, exception):
|
def format_exception_reply(_api_version, exception):
|
||||||
return {"result": None, "error": str(exception)}
|
return {"result": None, "error": str(exception)}
|
||||||
|
|
||||||
|
|
||||||
|
request_schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"action": {"type": "string", "minLength": 1},
|
||||||
|
"version": {"type": "integer"},
|
||||||
|
"params": {"type": "object"},
|
||||||
|
},
|
||||||
|
"required": ["action"],
|
||||||
|
}
|
@ -169,6 +169,24 @@ def test_failing_request_due_to_bad_json(external_anki):
|
|||||||
assert "in double quotes" in response["error"]
|
assert "in double quotes" in response["error"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_failing_request_due_to_json_root_not_being_an_object(external_anki):
|
||||||
|
response = json.loads(external_anki.send_bytes(b"1.2"))
|
||||||
|
assert response["result"] is None
|
||||||
|
assert "is not of type 'object'" in response["error"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_failing_request_due_to_json_missing_wanted_properties(external_anki):
|
||||||
|
response = json.loads(external_anki.send_bytes(b"{}"))
|
||||||
|
assert response["result"] is None
|
||||||
|
assert "'action' is a required property" in response["error"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_failing_request_due_to_json_properties_being_of_wrong_types(external_anki):
|
||||||
|
response = json.loads(external_anki.send_bytes(b'{"action": 1}'))
|
||||||
|
assert response["result"] is None
|
||||||
|
assert "1 is not of type 'string'" in response["error"]
|
||||||
|
|
||||||
|
|
||||||
def test_403_in_case_of_disallowed_origin(external_anki):
|
def test_403_in_case_of_disallowed_origin(external_anki):
|
||||||
with pytest.raises(urllib.error.HTTPError, match="403"): # good request/json
|
with pytest.raises(urllib.error.HTTPError, match="403"): # good request/json
|
||||||
json_bytes = json.dumps(Client.make_request("version")).encode("utf-8")
|
json_bytes = json.dumps(Client.make_request("version")).encode("utf-8")
|
||||||
|
Loading…
Reference in New Issue
Block a user