fix(signal): detect RIFF/WAVE attachments as .wav so they route to STT

This commit is contained in:
Bartok9 2026-06-22 04:03:04 -04:00 committed by Teknium
parent 4ae27548d6
commit 38b0b7ae3f
2 changed files with 43 additions and 0 deletions

View file

@ -97,6 +97,12 @@ def _guess_extension(data: bytes) -> str:
return ".gif"
if len(data) >= 12 and data[:4] == b"RIFF" and data[8:12] == b"WEBP":
return ".webp"
# RIFF/WAVE shares the ``RIFF`` chunk header with WebP; the form-type at
# bytes 8-11 disambiguates. Without this, an inbound WAV voice note fell
# through to ``.bin`` (octet-stream) and was cached as a document, so STT
# never saw it — even though ``.wav`` is in the audio allowlist + MIME map.
if len(data) >= 12 and data[:4] == b"RIFF" and data[8:12] == b"WAVE":
return ".wav"
if data[:4] == b"%PDF":
return ".pdf"
if len(data) >= 8 and data[4:8] == b"ftyp":

View file

@ -164,6 +164,43 @@ class TestSignalHelpers:
from gateway.platforms.signal import _guess_extension
assert _guess_extension(b"\x00\x00\x00\x18ftypisom" + b"\x00" * 100) == ".mp4"
def test_guess_extension_wav(self):
"""RIFF/WAVE must be detected as ``.wav`` (regression for the WAV gap).
WAV shares the ``RIFF`` chunk header with WebP; only the form-type at
bytes 8-11 (``WAVE`` vs ``WEBP``) distinguishes them. Before the fix the
sniffer only handled ``WEBP`` and a WAV file fell through to ``.bin``.
"""
from gateway.platforms.signal import _guess_extension
# Canonical WAV header: 'RIFF' <size> 'WAVE' 'fmt '...
wav = b"RIFF\x24\x08\x00\x00WAVEfmt " + b"\x00" * 100
assert _guess_extension(wav) == ".wav"
def test_guess_extension_wav_not_misread_as_webp(self):
"""A RIFF container that is NOT WebP must not be returned as ``.webp``."""
from gateway.platforms.signal import _guess_extension
wav = b"RIFF\x24\x08\x00\x00WAVEfmt " + b"\x00" * 100
assert _guess_extension(wav) != ".webp"
def test_guess_extension_wav_routes_to_audio_cache(self):
"""A detected WAV must route to the audio cache, not the document cache.
``.wav`` is already in ``_is_audio_ext``; the bug was purely that
``_guess_extension`` never produced ``.wav`` for raw bytes, so the
attachment was treated as a document and STT never received it.
"""
from gateway.platforms.signal import _is_audio_ext, _guess_extension
wav = b"RIFF\x24\x08\x00\x00WAVEfmt " + b"\x00" * 100
ext = _guess_extension(wav)
assert ext == ".wav"
assert _is_audio_ext(ext) is True
def test_guess_extension_webp_still_detected(self):
"""Guard that adding WAVE detection didn't break the WebP branch."""
from gateway.platforms.signal import _guess_extension
webp = b"RIFF\x24\x08\x00\x00WEBPVP8 " + b"\x00" * 100
assert _guess_extension(webp) == ".webp"
def test_guess_extension_aac_adts_unprotected(self):
"""ADTS AAC, MPEG-4, no CRC (the canonical Android Signal voice note).