diff --git a/nova/api/openstack/placement/util.py b/nova/api/openstack/placement/util.py index 30961cd10a89..cae3f0ecb313 100644 --- a/nova/api/openstack/placement/util.py +++ b/nova/api/openstack/placement/util.py @@ -201,9 +201,11 @@ def trait_url(environ, trait): def validate_query_params(req, schema): try: + # NOTE(Kevin_Zheng): The webob package throws UnicodeError when + # param cannot be decoded. Catch this and raise HTTP 400. jsonschema.validate(dict(req.GET), schema, format_checker=jsonschema.FormatChecker()) - except jsonschema.ValidationError as exc: + except (jsonschema.ValidationError, UnicodeDecodeError) as exc: raise webob.exc.HTTPBadRequest( _('Invalid query string parameters: %(exc)s') % {'exc': exc}) diff --git a/nova/tests/unit/api/openstack/placement/test_util.py b/nova/tests/unit/api/openstack/placement/test_util.py index c7b7cb4e5948..0dea037bb231 100644 --- a/nova/tests/unit/api/openstack/placement/test_util.py +++ b/nova/tests/unit/api/openstack/placement/test_util.py @@ -21,6 +21,7 @@ from oslo_middleware import request_id from oslo_utils import timeutils import webob +import six import six.moves.urllib.parse as urlparse from nova.api.openstack.placement import lib as pl @@ -146,6 +147,22 @@ class TestExtractJSON(test.NoDBTestCase): self.assertEqual(uuidsentinel.rp_uuid, data['uuid']) +class QueryParamsSchemaTestCase(test.NoDBTestCase): + + def test_validate_request(self): + schema = { + 'type': 'object', + 'properties': { + 'foo': {'type': 'string'} + }, + 'additionalProperties': False} + req = webob.Request.blank('/test?foo=%88') + error = self.assertRaises(webob.exc.HTTPBadRequest, + util.validate_query_params, + req, schema) + self.assertIn('Invalid query string parameters', six.text_type(error)) + + class TestJSONErrorFormatter(test.NoDBTestCase): def setUp(self):