Integrity check: don't quarantine valid streamed FLAC as 'zero-length' (#756)

HiFi assembles FLAC from HLS segments and demuxes with `ffmpeg -c copy`,
which preserves total_samples=0 in the STREAMINFO of Tidal's fragmented/
streamed FLAC. Every audio frame is present and the file plays fine, but
mutagen computes length = total_samples / sample_rate = 0, so the integrity
check rejected it as 'zero-length audio' and quarantined nearly every HiFi
download. Users confirmed the quarantined files play normally once restored.

Length 0 is not proof of corruption at that point: the file already passed
the size gate, was identified as a real audio format, and has a valid info
block — a genuinely empty/truncated/stub file fails one of those earlier
checks instead. Treat length 0 as 'length unknown': accept the file and skip
the duration cross-check we can't perform without a length. mutagen never
decoded/validated frame data anyway, so this doesn't weaken real corruption
detection — size, parse, format, info-block, and duration-drift guards all
remain.

Tests: a large valid-parse length-0 file (streamed-FLAC signature) is now
accepted; a tiny length-0 stub still fails (size gate fires first).
This commit is contained in:
BoulderBadgeDad 2026-05-31 11:28:40 -07:00
parent 2824c25ec6
commit d6f37f9667
2 changed files with 68 additions and 4 deletions

View file

@ -183,11 +183,29 @@ def check_audio_integrity(
checks["actual_length_s"] = actual_length_s
if actual_length_s <= 0:
# Length 0 is NOT proof of corruption here: the file already passed the
# size gate, was identified as a real audio format, and has a valid
# info block. A genuinely empty/truncated/stub file fails one of those
# earlier checks instead. The real cause of a clean-but-zero-length
# parse is "length unknown" — fragmented / streamed FLAC carries
# total_samples=0 in its STREAMINFO even though every audio frame is
# present and the file plays fine. HiFi is the common trigger: it
# assembles FLAC from HLS segments and demuxes with `ffmpeg -c copy`,
# which preserves total_samples=0, so mutagen computes length 0 and the
# file was wrongly quarantined (#756). Treat it as unknown length:
# accept the file and skip the duration cross-check we can't perform
# without a length. mutagen never decoded/validated frame data anyway,
# so accepting here doesn't weaken real corruption detection.
logger.warning(
"[Integrity] %s parsed cleanly (%d bytes, format=%s) but reports "
"length 0 — treating as unknown length (likely streamed/fragmented "
"FLAC), not rejecting",
os.path.basename(file_path), size, type(audio).__name__,
)
return IntegrityResult(
ok=False,
reason="Mutagen reports zero-length audio — file has no playable "
"audio data",
checks={**checks, "mutagen_parse": "zero_length"},
ok=True,
checks={**checks, "mutagen_parse": "zero_length_unknown",
"length_check": "skipped_unknown_length"},
)
# --- Check 3: duration agreement (optional) ---

View file

@ -124,6 +124,52 @@ def test_accepts_valid_wav_with_no_expected_duration(tmp_path: Path) -> None:
assert result.checks["length_check"] == "skipped"
# ---------------------------------------------------------------------------
# Zero-length-but-valid parse (#756): streamed / fragmented FLAC
# ---------------------------------------------------------------------------
def test_accepts_zero_length_when_parse_is_otherwise_valid(tmp_path: Path, monkeypatch) -> None:
"""#756: HiFi assembles FLAC from HLS segments and demuxes with
`ffmpeg -c copy`, leaving STREAMINFO total_samples=0. Mutagen then
reports length 0 even though every audio frame is present and the file
plays fine. Such a file large, identifiable format, valid info block
must be ACCEPTED (unknown length), not quarantined as 'zero-length'."""
import mutagen
f = tmp_path / "streamed.flac"
f.write_bytes(b"\x00" * (50 * 1024)) # clears size gate; bytes irrelevant (mutagen mocked)
# Valid parse, valid info block, but length 0 — the streamed-FLAC signature.
fake_audio = SimpleNamespace(info=SimpleNamespace(length=0))
monkeypatch.setattr(mutagen, "File", lambda *a, **k: fake_audio)
# Even with an expected duration present, it must accept (can't compare to
# an unknown length) rather than reject.
result = file_integrity.check_audio_integrity(str(f), expected_duration_ms=200_000)
assert result.ok is True
assert result.checks["mutagen_parse"] == "zero_length_unknown"
assert result.checks["length_check"] == "skipped_unknown_length"
def test_zero_length_still_rejects_when_too_small(tmp_path: Path, monkeypatch) -> None:
"""A genuinely empty/stub file with length 0 must still fail — the size
gate fires before parse, so the relaxation can't let real stubs through."""
import mutagen
f = tmp_path / "stub.flac"
f.write_bytes(b"\x00" * 200) # below the 10KB size gate
fake_audio = SimpleNamespace(info=SimpleNamespace(length=0))
monkeypatch.setattr(mutagen, "File", lambda *a, **k: fake_audio)
result = file_integrity.check_audio_integrity(str(f))
assert result.ok is False
assert "too small" in result.reason.lower()
# ---------------------------------------------------------------------------
# Duration agreement check
# ---------------------------------------------------------------------------