mirror of
https://github.com/smittix/intercept.git
synced 2026-07-06 00:28:12 -07:00
fix(ook): address upstream PR review — SDR tracking, validation, cleanup, XSS
Critical:
- Pass sdr_type_str to claim/release_sdr_device (was missing 3rd arg)
- Add ook_active_sdr_type module-level var for proper device registry tracking
- Add server-side range validation on all timing params via validate_positive_int
Major:
- Extract cleanup_ook() function for full teardown (stop_event, pipes, process,
SDR release) — called from both stop_ook() and kill_all()
- Replace Popen monkey-patching with module-level _ook_stop_event/_ook_parser_thread
- Fix XSS: define local _esc() fallback in ook.js, never use raw innerHTML
- Remove dead inversion code path in utils/ook.py (bytes.fromhex on same
string that already failed decode — could never produce a result)
Minor:
- Status event key 'status' → 'text' for consistency with other modules
- Parser thread logging: debug → warning for missing code field and errors
- Parser thread emits status:stopped on exit (normal EOF or crash)
- Add cache-busting ?v={{ version }}&r=ook1 to ook.js script include
- Fix gain/ppm comparison: != '0' (string) → != 0 (number)
Tests: 22 → 33 (added start success, stop with process, SSE stream,
timing range validation, stopped-on-exit event)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+110
-1
@@ -6,12 +6,12 @@ import io
|
||||
import json
|
||||
import queue
|
||||
import threading
|
||||
import unittest.mock
|
||||
|
||||
import pytest
|
||||
|
||||
from utils.ook import decode_ook_frame, ook_parser_thread
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -250,3 +250,112 @@ class TestOokRoutes:
|
||||
json={'frequency': '-5'},
|
||||
content_type='application/json')
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_start_rejects_out_of_range_timing(self, client):
|
||||
"""Timing params that exceed server-side max should be rejected."""
|
||||
_login_session(client)
|
||||
resp = client.post('/ook/start',
|
||||
json={'short_pulse': 999999},
|
||||
content_type='application/json')
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_start_rejects_negative_timing(self, client):
|
||||
_login_session(client)
|
||||
resp = client.post('/ook/start',
|
||||
json={'min_bits': -1},
|
||||
content_type='application/json')
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_start_success_mocked(self, client, monkeypatch):
|
||||
"""start_ook with mocked Popen should return 'started'."""
|
||||
import subprocess
|
||||
|
||||
import app as app_module
|
||||
|
||||
_login_session(client)
|
||||
|
||||
mock_proc = unittest.mock.MagicMock()
|
||||
mock_proc.poll.return_value = None
|
||||
mock_proc.stdout = io.BytesIO(b'')
|
||||
mock_proc.stderr = io.BytesIO(b'')
|
||||
mock_proc.pid = 12345
|
||||
|
||||
monkeypatch.setattr(subprocess, 'Popen', lambda *a, **kw: mock_proc)
|
||||
monkeypatch.setattr(app_module, 'claim_sdr_device', lambda *a, **kw: None)
|
||||
monkeypatch.setattr(app_module, 'release_sdr_device', lambda *a, **kw: None)
|
||||
|
||||
resp = client.post('/ook/start',
|
||||
json={'frequency': '433.920'},
|
||||
content_type='application/json')
|
||||
data = resp.get_json()
|
||||
assert resp.status_code == 200
|
||||
assert data['status'] == 'started'
|
||||
assert 'command' in data
|
||||
|
||||
# Cleanup
|
||||
with app_module.ook_lock:
|
||||
app_module.ook_process = None
|
||||
|
||||
def test_stop_with_running_process(self, client, monkeypatch):
|
||||
"""stop_ook should clean up a running process."""
|
||||
import app as app_module
|
||||
|
||||
_login_session(client)
|
||||
|
||||
mock_proc = unittest.mock.MagicMock()
|
||||
mock_proc.poll.return_value = None
|
||||
mock_proc.stdout = None
|
||||
mock_proc.stderr = None
|
||||
mock_proc.pid = 12345
|
||||
|
||||
# Inject a fake running process
|
||||
import routes.ook as ook_module
|
||||
app_module.ook_process = mock_proc
|
||||
ook_module._ook_stop_event = threading.Event()
|
||||
ook_module._ook_parser_thread = None
|
||||
ook_module.ook_active_device = 0
|
||||
ook_module.ook_active_sdr_type = 'rtlsdr'
|
||||
|
||||
monkeypatch.setattr(app_module, 'release_sdr_device', lambda *a, **kw: None)
|
||||
monkeypatch.setattr('utils.process.safe_terminate', lambda p: None)
|
||||
monkeypatch.setattr('utils.process.unregister_process', lambda p: None)
|
||||
|
||||
resp = client.post('/ook/stop')
|
||||
data = resp.get_json()
|
||||
assert resp.status_code == 200
|
||||
assert data['status'] == 'stopped'
|
||||
assert app_module.ook_process is None
|
||||
assert ook_module.ook_active_device is None
|
||||
|
||||
def test_stream_endpoint(self, client):
|
||||
"""SSE stream endpoint should return text/event-stream."""
|
||||
_login_session(client)
|
||||
resp = client.get('/ook/stream')
|
||||
assert resp.content_type.startswith('text/event-stream')
|
||||
assert resp.headers.get('Cache-Control') == 'no-cache'
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Parser thread — stopped status on exit
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestOokParserStoppedEvent:
|
||||
def test_emits_stopped_on_normal_exit(self):
|
||||
"""Parser thread should emit a status: stopped event when stream ends."""
|
||||
stdout = io.BytesIO(b'')
|
||||
output_queue = queue.Queue()
|
||||
stop_event = threading.Event()
|
||||
|
||||
t = threading.Thread(
|
||||
target=ook_parser_thread,
|
||||
args=(stdout, output_queue, stop_event),
|
||||
)
|
||||
t.start()
|
||||
t.join(timeout=2)
|
||||
|
||||
events = []
|
||||
while not output_queue.empty():
|
||||
events.append(output_queue.get_nowait())
|
||||
status_events = [e for e in events if e.get('type') == 'status']
|
||||
assert len(status_events) == 1
|
||||
assert status_events[0]['text'] == 'stopped'
|
||||
|
||||
Reference in New Issue
Block a user