Stop reporting a corrupt mkv:// source as an empty title

E6008 meant two unrelated things: "this title produced no muxable
frames", which is a benign stub worth skipping, and "the source file is
malformed", which is not. Because a single code carried both,
is_skippable_title_stub answered yes to the second one — so feeding a
truncated or corrupt mkv:// input made the engine classify it
SkippableStub, print a notice saying the title was empty, and exit 0.
Silent data loss reported as success.

Split into E9053 MkvSourceInvalid for the read path (25 raise sites
across mkvstream.rs and ebml.rs's read primitives) and E9054
MkvUnencodable for the four write-side sites, which are the encoder
refusing to emit a body at or above the 56-bit VINT limit — an output
limit with no input involved, so calling it a corrupt source would be
wrong in the other direction. E6008 keeps only the zero-frame guard it
was documented to mean.

Kept one code for the whole read path rather than one per raise site:
nothing a consumer does differs between a bad VINT, a non-UTF-8 string
element, a truncated body and a child overrunning its parent. E9052 is
the model for when a carve-out earns its keep — laced blocks name one
specific RFC 9559 §10.3 feature with its own diagnosis.

Also fixed meta_sink.rs raising MkvInvalid for a serde_json encode
failure in the json:// sink, where no MKV is involved at all; it now
matches the identical guard in mux/meta.rs.

Reverting the split at the single code() arm reproduces the old
classification: 22 tests fail, including both new assertions. The
opposite direction is pinned too — dropping E6008 from the predicate
fails the genuine-stub test, which drives the real muxer end to end.
This commit is contained in:
Matthew Jackson
2026-07-29 22:11:53 -07:00
parent 0bbceed985
commit f5e169efb3
6 changed files with 260 additions and 79 deletions
+6 -1
View File
@@ -248,8 +248,13 @@ impl JsonSink {
// never holds an unencodable value); still, propagate rather than silently
// writing "{}" if that ever changes — an empty metadata file must not
// masquerade as a successful json:// export.
//
// `NoMetadata` (E9008), matching `mux::meta`'s serialize guard: this is a
// metadata-encoding failure with no MKV involved. It was `MkvInvalid`,
// which `error::is_skippable_title_stub` reports as a skippable empty
// nav/menu stub — a json:// export that failed to encode is not that.
let doc = serde_json::to_string_pretty(&title_json(title))
.map_err(|_| crate::error::Error::MkvInvalid)?;
.map_err(|_| crate::error::Error::NoMetadata)?;
let mut f = File::create(path)?;
f.write_all(doc.as_bytes())?;
f.write_all(b"\n")?;