Fix 500 if list servers called with empty regex pattern

If nova list API is called with empty regex pattern like below:
    http://<host-ip>/compute/v2.1/servers?name=""

it fails at db layer and returns 500 InternalServerError.

Empty string('') is a valid regex for re.compile [1] so nova-api fails
to catch it at schema layer and it is passed to databse for searching.
Database fails to search it with "REGEXP %(display_name_1)s)" and
'display_name_1' as u'' in sql query which leads to below error:

InternalError: (1139, u"Got error 'empty (sub)expression' from regexp")

This issue is there for every query parameter which is using below
regex parameter types defined in parameter_types.py:
    common_query_regex_param

This patch fixes this issue by rejecting the request with 400 if the
provided filter regex is empty string. If user is intending to filter
something, user must pass something to the filter, it cannot be a empty
string.

[1] https://github.com/openstack/nova/blob/16.0.0/nova/api/validation/validators.py#L40

Closes-Bug: #1718877
Change-Id: I3f6fa04dc7267279964e8e5dd2a790b997a40e4e
This commit is contained in:
Dinesh Bhor 2017-09-19 14:56:01 +05:30 committed by Matt Riedemann
parent 902a374012
commit 0cc94bfd59
2 changed files with 15 additions and 1 deletions

View File

@ -34,7 +34,7 @@ from nova.i18n import _
@jsonschema.FormatChecker.cls_checks('regex')
def _validate_regex_format(instance):
if not isinstance(instance, six.text_type):
if not instance or not isinstance(instance, six.text_type):
return False
try:
re.compile(instance)

View File

@ -702,6 +702,20 @@ class ServersControllerTest(ControllerTest):
self.assertRaises(exception.ValidationError,
self.controller.index, req)
def test_get_servers_with_empty_regex_filter_param(self):
empty_string = ''
req = self.req('/fake/servers?flavor=%s' % empty_string,
use_admin_context=True)
self.assertRaises(exception.ValidationError,
self.controller.index, req)
def test_get_servers_detail_with_empty_regex_filter_param(self):
empty_string = ''
req = self.req('/fake/servers/detail?flavor=%s' % empty_string,
use_admin_context=True)
self.assertRaises(exception.ValidationError,
self.controller.detail, req)
def test_get_servers_invalid_sort_key(self):
req = self.req('/fake/servers?sort_key=foo&sort_dir=desc')
self.assertRaises(exception.ValidationError,