fix(api): answer 400 for bulk category ids beyond SQLite's INTEGER range
An id of 2**63 or more passed the parser and made sqlite3 raise OverflowError, which the route turned into a 500.
This commit is contained in:
+6
-2
@@ -25,16 +25,20 @@ EXPORT_PAGE_SIZE = 1000
|
||||
# The most prompts one bulk category request may change.
|
||||
BULK_CATEGORY_MAX_PROMPTS = 1000
|
||||
|
||||
# The largest value SQLite's INTEGER can bind; a larger id raises OverflowError.
|
||||
MAX_SQLITE_INT = 2**63 - 1
|
||||
|
||||
|
||||
def parse_bulk_prompt_ids(value, cap=BULK_CATEGORY_MAX_PROMPTS):
|
||||
"""A bulk request's ``prompt_ids``: distinct positive ints, first-seen order.
|
||||
|
||||
Raises ``ValueError`` unless ``value`` is a non-empty list of at most
|
||||
``cap`` distinct positive integers (booleans are not integers here).
|
||||
``cap`` distinct positive integers no larger than SQLite's INTEGER
|
||||
(booleans are not integers here).
|
||||
"""
|
||||
if not isinstance(value, list) or not value:
|
||||
raise ValueError("prompt_ids must be a non-empty list")
|
||||
if any(type(pid) is not int or pid < 1 for pid in value):
|
||||
if any(type(pid) is not int or not 1 <= pid <= MAX_SQLITE_INT for pid in value):
|
||||
raise ValueError("prompt_ids must be positive integers")
|
||||
ids = list(dict.fromkeys(value))
|
||||
if len(ids) > cap:
|
||||
|
||||
@@ -926,6 +926,9 @@ class TestBulkRoutes(RouteCoverageCase):
|
||||
[pid, 1.5],
|
||||
[True],
|
||||
[pid, None],
|
||||
# Beyond SQLite's INTEGER range: binding it would raise OverflowError.
|
||||
[pid, 2**63],
|
||||
[2**64],
|
||||
list(range(1, BULK_CATEGORY_MAX_PROMPTS + 2)),
|
||||
)
|
||||
for prompt_ids in cases:
|
||||
|
||||
Reference in New Issue
Block a user