Skip to content

Commit 9ae927c

Browse files
committed
FLAC: Don't error by default on invalid picture types
FLAC picture blocks have `u32::MAX` possible picture types, but only 20 are actually defined. In the [spec] it states, "Others are reserved and should not be used." We used to only allow a picture type of up to 255 to be in sync with ID3v2's APIC, where this model comes from. Now any picture type can be specified and it will just be clamped to 255, so long as `ParsingMode::Strict` is not being used.
1 parent 15d9ca8 commit 9ae927c

File tree

4 files changed

+33
-13
lines changed

4 files changed

+33
-13
lines changed

CHANGELOG.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2424
- `Ilst::remove` will now return all of the removed atoms
2525
- `Ilst::insert_picture` will now combine all pictures into a single `covr` atom
2626
- `Ilst::insert` will now merge atoms with the same identifier into a single atom
27-
- **FLAC**: Allow multiple Vorbis Comment blocks when not using `ParsingMode::Strict`
28-
- This is not allowed [by spec](https://xiph.org/flac/format.html#def_VORBIS_COMMENT), but is still possible
29-
to encounter in the wild. Now we will just tag whichever tag happens to be latest in the stream and
30-
use it, they **will not be merged**.
27+
- **FLAC**:
28+
- Allow multiple Vorbis Comment blocks when not using `ParsingMode::Strict`
29+
- This is not allowed [by spec](https://xiph.org/flac/format.html#def_VORBIS_COMMENT), but is still possible
30+
to encounter in the wild. Now we will just tag whichever tag happens to be latest in the stream and
31+
use it, they **will not be merged**.
32+
- Allow picture types greater than 255 when not using `ParsingMode::Strict`
33+
- This is not allowed [by spec](https://xiph.org/flac/format.html#metadata_block_picture), but has been encountered
34+
in the wild. Now we will just cap the picture type at 255.
3135

3236
## Fixed
3337
- **WavPack**: Custom sample rates will no longer be overwritten

src/flac/read.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,17 @@ where
100100
}
101101

102102
if block.ty == BLOCK_ID_PICTURE {
103-
flac_file
104-
.pictures
105-
.push(Picture::from_flac_bytes(&block.content, false)?)
103+
match Picture::from_flac_bytes(&block.content, false, parse_options.parsing_mode) {
104+
Ok(picture) => flac_file.pictures.push(picture),
105+
Err(e) => {
106+
if parse_options.parsing_mode == ParsingMode::Strict {
107+
return Err(e);
108+
}
109+
110+
log::warn!("Unable to read FLAC picture block, discarding");
111+
continue;
112+
},
113+
}
106114
}
107115
}
108116

src/ogg/read.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ where
9494

9595
match key {
9696
k if k.eq_ignore_ascii_case(b"METADATA_BLOCK_PICTURE") => {
97-
match Picture::from_flac_bytes(value, true) {
97+
match Picture::from_flac_bytes(value, true, parse_mode) {
9898
Ok(picture) => tag.pictures.push(picture),
9999
Err(e) => {
100100
if parse_mode == ParsingMode::Strict {

src/picture.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::error::{ErrorKind, LoftyError, Result};
22
use crate::macros::err;
3+
use crate::probe::ParsingMode;
34

45
use std::borrow::Cow;
56
use std::fmt::{Debug, Formatter};
@@ -625,18 +626,25 @@ impl Picture {
625626
///
626627
/// This function will return [`NotAPicture`][ErrorKind::NotAPicture] if
627628
/// at any point it's unable to parse the data
628-
pub fn from_flac_bytes(bytes: &[u8], encoded: bool) -> Result<(Self, PictureInformation)> {
629+
pub fn from_flac_bytes(
630+
bytes: &[u8],
631+
encoded: bool,
632+
parse_mode: ParsingMode,
633+
) -> Result<(Self, PictureInformation)> {
629634
if encoded {
630635
let data = base64::engine::general_purpose::STANDARD
631636
.decode(bytes)
632637
.map_err(|_| LoftyError::new(ErrorKind::NotAPicture))?;
633-
Self::from_flac_bytes_inner(&data)
638+
Self::from_flac_bytes_inner(&data, parse_mode)
634639
} else {
635-
Self::from_flac_bytes_inner(bytes)
640+
Self::from_flac_bytes_inner(bytes, parse_mode)
636641
}
637642
}
638643

639-
fn from_flac_bytes_inner(content: &[u8]) -> Result<(Self, PictureInformation)> {
644+
fn from_flac_bytes_inner(
645+
content: &[u8],
646+
parse_mode: ParsingMode,
647+
) -> Result<(Self, PictureInformation)> {
640648
use crate::macros::try_vec;
641649

642650
let mut size = content.len();
@@ -652,7 +660,7 @@ impl Picture {
652660
// ID3v2 APIC uses a single byte for picture type.
653661
// Anything greater than that is probably invalid, so
654662
// we just stop early
655-
if pic_ty > 255 {
663+
if pic_ty > 255 && parse_mode == ParsingMode::Strict {
656664
err!(NotAPicture);
657665
}
658666

0 commit comments

Comments
 (0)