Fix: Wrap all unsafe int() conversions with try/except

Fixed ValueError-prone int() calls in:
- communications/api/viewsets.py (4 places: limit, before_limit, after_limit)
- notifications/api/views.py (2 places: page, page_size)
- api/v1/search/views.py (1 place: limit)
- api/v1/procurement/views.py (1 place: quantity)
Also updated audit script to exclude .venv/
This commit is contained in:
lizerk 2026-03-20 09:10:33 +03:00
parent 2ef43e7177
commit 2688df46ef
5 changed files with 38 additions and 13 deletions

View File

@ -902,7 +902,10 @@ class EquipmentViewSet(viewsets.ModelViewSet):
Если передан параметр quantity > 1, создаётся несколько единиц
с автоматически сгенерированными инвентарными номерами.
"""
quantity = int(request.data.get('quantity', 1))
try:
quantity = int(request.data.get('quantity', 1))
except (ValueError, TypeError):
quantity = 1
quantity = max(1, min(quantity, 100)) # Ограничение от 1 до 100
if quantity == 1:

View File

@ -294,7 +294,10 @@ def search_api_view(request: DRFRequest) -> Response:
"""
raw_q = request.query_params.get("q", "") or ""
query = escape(raw_q.strip())
limit = int(request.query_params.get("limit", 10))
try:
limit = int(request.query_params.get("limit", 10))
except (ValueError, TypeError):
limit = 10
if not query:
return Response(

View File

@ -542,7 +542,10 @@ class ChatViewSet(viewsets.ModelViewSet):
before_id = request.query_params.get('before_id')
after_ts = request.query_params.get('after')
after_id = request.query_params.get('after_id')
limit = min(int(request.query_params.get('limit', 50)), 100)
try:
limit = min(int(request.query_params.get('limit', 50)), 100)
except (ValueError, TypeError):
limit = 50
queryset = chat.messages.filter(is_deleted=False).select_related(
'author', 'reply_to', 'reply_to__author', 'poll'
@ -623,12 +626,21 @@ class ChatViewSet(viewsets.ModelViewSet):
around_id = request.query_params.get('around_id')
# Асимметричные лимиты (24 + 10 = 34 сообщения )
before_limit = int(request.query_params.get('before_limit', 24))
after_limit = int(request.query_params.get('after_limit', 10))
try:
before_limit = int(request.query_params.get('before_limit', 24))
except (ValueError, TypeError):
before_limit = 24
try:
after_limit = int(request.query_params.get('after_limit', 10))
except (ValueError, TypeError):
after_limit = 10
# Для обратной совместимости с limit параметром
if 'limit' in request.query_params and 'before_limit' not in request.query_params:
total_limit = min(int(request.query_params.get('limit', 30)), 100)
try:
total_limit = min(int(request.query_params.get('limit', 30)), 100)
except (ValueError, TypeError):
total_limit = 30
before_limit = int(total_limit * 0.8) # 80% на контекст
after_limit = total_limit - before_limit # 20% на новые

View File

@ -37,8 +37,14 @@ def get_notifications(request):
- unread_only: только непрочитанные (true/false)
- search: поиск по описанию
"""
page = int(request.GET.get('page', 1))
page_size = int(request.GET.get('page_size', 20))
try:
page = int(request.GET.get('page', 1))
except (ValueError, TypeError):
page = 1
try:
page_size = int(request.GET.get('page_size', 20))
except (ValueError, TypeError):
page_size = 20
verb = request.GET.get('verb')
unread_only = request.GET.get('unread_only', 'false').lower() == 'true'
search = request.GET.get('search', '').strip()

View File

@ -1,27 +1,28 @@
#!/bin/bash
# Аудит потенциально проблемных паттернов в коде
# Исключает .venv/ (сторонние пакеты)
echo "=== Поиск потенциальных проблем ==="
echo ""
echo "1. Небезопасный доступ к request.data:"
grep -rn "request\.data\[" --include="*.py" . | grep -v "# noqa" || echo "✓ Не найдено"
grep -rn "request\.data\[" --include="*.py" . --exclude-dir=.venv | grep -v "# noqa" || echo "✓ Не найдено"
echo ""
echo "2. Использование .dict() без проверки типа:"
grep -rn "\.data\.dict()" --include="*.py" . | grep -v "hasattr" || echo "✓ Не найдено"
grep -rn "\.data\.dict()" --include="*.py" . --exclude-dir=.venv | grep -v "hasattr" || echo "✓ Не найдено"
echo ""
echo "3. Прямое обращение к QueryDict без .get():"
grep -rn "request\.POST\[" --include="*.py" . | grep -v "# noqa" || echo "✓ Не найдено"
grep -rn "request\.POST\[" --include="*.py" . --exclude-dir=.venv | grep -v "# noqa" || echo "✓ Не найдено"
echo ""
echo "4. Небезопасный int() без try/except:"
grep -rn "int(.*request\." --include="*.py" . | head -20
grep -rn "int(.*request\." --include="*.py" . --exclude-dir=.venv | head -20
echo ""
echo "5. Отсутствие проверки на None перед .strip():"
grep -rn "\.strip()" --include="*.py" . | grep -v "if.*:" | head -10
grep -rn "\.strip()" --include="*.py" . --exclude-dir=.venv | grep -v "if.*:" | head -10
echo ""
echo "=== Аудит завершен ==="