Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions gateway/platforms/qqbot/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1797,16 +1797,14 @@ def _is_voice_content_type(content_type: str, filename: str) -> bool:
fn = filename.strip().lower()
if ct == "voice" or ct.startswith("audio/"):
return True
# QQ file uploads have content_type="file". Without this guard,
# any uploaded audio file (e.g. .wav, .mp3) would be misrouted into
# the STT pipeline and never be received as a normal file attachment.
if ct == "file":
return False
_VOICE_EXTENSIONS = (
".silk",
".amr",
".mp3",
".wav",
".ogg",
".m4a",
".aac",
".speex",
".flac",
".silk", ".amr", ".mp3", ".wav", ".ogg",
".m4a", ".aac", ".speex", ".flac",
)
if any(fn.endswith(ext) for ext in _VOICE_EXTENSIONS):
return True
Expand Down
13 changes: 11 additions & 2 deletions tests/gateway/test_qqbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,24 @@ def test_voice_content_type(self):
def test_audio_content_type(self):
assert self._fn("audio/mp3", "file.mp3") is True

def test_voice_extension(self):
def test_voice_extension_fallback_when_content_type_empty(self):
"""content_type='' with audio extension → True (extension fallback)."""
assert self._fn("", "file.silk") is True

def test_non_voice(self):
assert self._fn("image/jpeg", "photo.jpg") is False

def test_audio_extension_amr(self):
def test_audio_extension_amr_fallback_when_content_type_empty(self):
"""content_type='' with .amr extension → True (extension fallback)."""
assert self._fn("", "recording.amr") is True

def test_file_upload_with_audio_extension(self):
"""content_type='file' is never voice, even with audio extension."""
assert self._fn("file", "song.mp3") is False
assert self._fn("file", "audio-30251.instrumental..wav") is False
assert self._fn("file", "recording.silk") is False
assert self._fn("file", "voice.amr") is False


# ---------------------------------------------------------------------------
# Voice attachment SSRF protection
Expand Down