mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 16:14:02 +00:00
widgets: Add range checks on backend for indexes.
This commit is contained in:
@@ -141,6 +141,19 @@ def check_int_in(possible_values: List[int]) -> Validator[int]:
|
||||
return validator
|
||||
|
||||
|
||||
def check_int_range(low: int, high: int) -> Validator[int]:
|
||||
# low and high are both treated as valid values
|
||||
def validator(var_name: str, val: object) -> int:
|
||||
n = check_int(var_name, val)
|
||||
if n < low:
|
||||
raise ValidationError(_("{var_name} is too small").format(var_name=var_name))
|
||||
if n > high:
|
||||
raise ValidationError(_("{var_name} is too large").format(var_name=var_name))
|
||||
return n
|
||||
|
||||
return validator
|
||||
|
||||
|
||||
def check_float(var_name: str, val: object) -> float:
|
||||
if not isinstance(val, float):
|
||||
raise ValidationError(_("{var_name} is not a float").format(var_name=var_name))
|
||||
@@ -455,6 +468,10 @@ def check_widget_content(widget_content: object) -> Dict[str, Any]:
|
||||
raise ValidationError("unknown widget type: " + widget_type)
|
||||
|
||||
|
||||
# This should match MAX_IDX in our client widgets. It is somewhat arbitrary.
|
||||
MAX_IDX = 1000
|
||||
|
||||
|
||||
def validate_poll_data(poll_data: object, is_widget_author: bool) -> None:
|
||||
check_dict([("type", check_string)])("poll data", poll_data)
|
||||
|
||||
@@ -489,7 +506,7 @@ def validate_poll_data(poll_data: object, is_widget_author: bool) -> None:
|
||||
[
|
||||
("type", check_string),
|
||||
("option", check_string),
|
||||
("idx", check_int),
|
||||
("idx", check_int_range(0, MAX_IDX)),
|
||||
]
|
||||
)
|
||||
checker("poll data", poll_data)
|
||||
@@ -507,7 +524,7 @@ def validate_todo_data(todo_data: object) -> None:
|
||||
checker = check_dict_only(
|
||||
[
|
||||
("type", check_string),
|
||||
("key", check_int),
|
||||
("key", check_int_range(0, MAX_IDX)),
|
||||
("task", check_string),
|
||||
("desc", check_string),
|
||||
("completed", check_bool),
|
||||
|
@@ -297,6 +297,8 @@ class WidgetContentTestCase(ZulipTestCase):
|
||||
|
||||
assert_error('{"type": "new_option"}', "key is missing")
|
||||
assert_error('{"type": "new_option", "idx": 7, "option": 999}', "not a string")
|
||||
assert_error('{"type": "new_option", "idx": -1, "option": "pizza"}', "too small")
|
||||
assert_error('{"type": "new_option", "idx": 1001, "option": "pizza"}', "too large")
|
||||
assert_error('{"type": "new_option", "idx": "bogus", "option": "maybe"}', "not an int")
|
||||
|
||||
def assert_success(data: Dict[str, object]) -> None:
|
||||
@@ -348,6 +350,14 @@ class WidgetContentTestCase(ZulipTestCase):
|
||||
'{"type": "new_task", "key": 7, "task": 7, "desc": "", "completed": false}',
|
||||
'data["task"] is not a string',
|
||||
)
|
||||
assert_error(
|
||||
'{"type": "new_task", "key": -1, "task": "eat", "desc": "", "completed": false}',
|
||||
'data["key"] is too small',
|
||||
)
|
||||
assert_error(
|
||||
'{"type": "new_task", "key": 1001, "task": "eat", "desc": "", "completed": false}',
|
||||
'data["key"] is too large',
|
||||
)
|
||||
|
||||
assert_error('{"type": "strike"}', "key is missing")
|
||||
assert_error('{"type": "strike", "key": 999}', 'data["key"] is not a string')
|
||||
|
Reference in New Issue
Block a user