Skip to content

v1.9.22 — Audit round: /file regression revert, timer leaks, boolean coercion sweep

Choose a tag to compare

@SysAdminDoc SysAdminDoc released this 11 Apr 22:28

OpenCut v1.9.22 — Audit Round

Full QA pass over v1.9.21 by parallel audit agents (backend security,
frontend state, route boolean coercion). This release reverts one
security regression, finishes a half-complete boolean-coercion
sweep, and fixes two CEP panel reliability regressions uncovered by
the audit.

Security — /file preview route regression (reverted)

v1.9.21 replaced the realpath allowlist on GET /file with a
MIME-type check, reasoning that the allowlist blocked legitimate
Premiere project media previews. That reasoning was wrong — the
CEP panel only ever passes backend-generated output paths (TTS,
SFX, music) to /file, all of which live under
~/.opencut or the system temp dir. With the allowlist removed, any
page loaded in the user's browser could side-channel-enumerate local
media files via <img>/<audio> tags pointing at
http://127.0.0.1:5679/file?path=….

Fixed. The realpath allowlist is restored and the MIME-type
check is kept as defence-in-depth. /file now refuses anything
outside tempdir + ~/.opencut, and anything that isn't
audio/video/image MIME, even inside those roots.

Backend — safe_bool() hardening + completion sweep

v1.9.21's safe_bool() helper was threaded into ~6 routes but the
underlying bug class (bool("false") is True) still existed in 15
more places. All finished in this release:

  • audio.pyinclude_context_fillers, remove_silence,
    auto_import on /audio/separate
  • captions.pyword_timestamps, auto_detect_energy,
    skip_captions, skip_zoom, remove_fillers, diarize
  • system.pycpu_mode on /whisper/reinstall
  • video_ai.pyalpha_only on /video/ai/background
  • video_core.pytransparent, preview, auto_import on
    /video/watermark, audio_only on /video/export, use_faces
    on /export/thumbnails, parallel on /batch/create
  • video_editing.pyuse_vision on /video/highlights

safe_bool() itself is also hardened:

  • NaN / inf / -inf floats return the caller default instead of
    True (consistent with safe_float behaviour).
  • bytes / bytearray values are decoded as UTF-8 and parsed like
    strings, so b"false" correctly returns False.
  • Lists, tuples, sets, dicts, and arbitrary objects return the
    caller default. Previously non-empty containers silently coerced
    to True.

Covered by a 25-case parametrized unit test in
tests/test_boolean_coercion.py.

Backend — defensive fixes

  • core/highlights.pyextract_highlights() now tolerates None
    / missing-attribute LLM responses instead of raising when the
    provider is unreachable mid-request.
  • mcp_server.py — JSON-RPC response serialisation is wrapped in
    try/except; non-JSON-serialisable tool results now return a
    proper -32603 error instead of leaving the client hanging.

Frontend — CEP panel reliability

Two real regressions uncovered by the panel state audit:

  • mediaScanTimer reconnect leak. cleanupTimers() kills the
    project media poller on every disconnect, but only the initial
    bootstrap restarted it. After one server disconnect/reconnect the
    panel silently stopped detecting new media imported into
    Premiere until the user reloaded the panel.
  • _statusTimer reconnect leak. Same bug for the system status
    bar — after one reconnect it would show stale GPU/job counts
    until reload.

Both are fixed by a new startBackgroundPollers() helper called
from both the init path and the health-check reconnect branch.
initStatusBar() is now idempotent (guards against double timers
on re-entry), and a spurious var _statusTimer redeclaration that
was shadowing the module-scope hoisted variable has been removed.

UXP panel polish

  • New .oc-hidden / .oc-chat-history utility classes replacing
    inline style="display:none" attributes.
  • Cut tab accessibility fix: aria-labelledby now references a
    real button id.

Tests

  • test_boolean_coercion.py — 25 parametrized cases for
    safe_bool (bools, ints, floats, NaN/inf, strings, bytes,
    containers, arbitrary objects).
  • test_new_features.pyTestPreviewFileServing adds a third
    case: a media file OUTSIDE the approved roots must return 403
    regardless of MIME type.
  • Focused validation: pytest -q tests/test_boolean_coercion.py tests/test_context.py tests/test_new_features.py tests/test_integration.py tests/test_core_modules.py tests/test_core_modules_batch2.py377 passed, 3 skipped.

Artifact

Windows x64 PyInstaller build attached as
OpenCut-Server-v1.9.22-win-x64.zip (~226 MB). Unzip and run
OpenCut-Server\OpenCut-Server.exe or the standard
OpenCut-Server.bat / OpenCut-Launcher.vbs launchers.