Skip to content
This repository was archived by the owner on Sep 3, 2025. It is now read-only.

Commit d1c18df

Browse files
Holzhauspolyfloyd
authored andcommitted
fix(content): Decode IPLS/TIPL/TMCL with odd value count gracefully
1 parent adda14e commit d1c18df

File tree

1 file changed

+37
-7
lines changed

1 file changed

+37
-7
lines changed

src/stream/frame/content.rs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -596,12 +596,21 @@ impl<'a> Decoder<'a> {
596596
Some(result)
597597
}
598598
(Some(_), None) => {
599-
// This can only happen if there is an uneven number of elements.
600-
*last_string = None;
601-
Some(Err(Error::new(
602-
ErrorKind::Parsing,
603-
"uneven number of IPLS strings",
604-
)))
599+
// This can only happen if there is an uneven number of elements. For
600+
// compatibility, we assume that the missing value is an empty string instead of
601+
// erroring out and failing to parse the entire tag.
602+
//
603+
// This is in line with what the Python mutagen library does. See this issue for
604+
// details:
605+
// - <https://github.com/polyfloyd/rust-id3/issues/147>
606+
let first = last_string.take().expect("option must be some");
607+
let result = first.map(|involvement| {
608+
Some(InvolvedPeopleListItem {
609+
involvement,
610+
involvee: String::new(),
611+
})
612+
});
613+
Some(result)
605614
}
606615
(None, None) => None,
607616
})
@@ -1711,7 +1720,28 @@ mod tests {
17111720
data.extend(bytes_for_encoding("other involvement", *encoding).into_iter());
17121721
data.extend(delim_for_encoding(*encoding).into_iter());
17131722
// involveee missing here
1714-
assert!(decode(frame_id, version, &data[..]).is_err());
1723+
1724+
let content = frame::InvolvedPeopleList {
1725+
items: vec![
1726+
InvolvedPeopleListItem {
1727+
involvement: "involvement".to_string(),
1728+
involvee: "involvee".to_string(),
1729+
},
1730+
InvolvedPeopleListItem {
1731+
involvement: "other involvement".to_string(),
1732+
// Assume empty string if value is missing
1733+
involvee: "".to_string(),
1734+
},
1735+
],
1736+
};
1737+
assert_eq!(
1738+
*decode(frame_id, version, &data[..])
1739+
.unwrap()
1740+
.0
1741+
.involved_people_list()
1742+
.unwrap(),
1743+
content
1744+
);
17151745
}
17161746
}
17171747

0 commit comments

Comments
 (0)