@@ -3,12 +3,14 @@ use crate::error::{Id3v2Error, Id3v2ErrorKind, Result};
3
3
use crate :: id3:: v2:: util:: synchsafe:: SynchsafeInteger ;
4
4
use crate :: id3:: v2:: util:: upgrade:: { upgrade_v2, upgrade_v3} ;
5
5
use crate :: id3:: v2:: FrameId ;
6
+ use crate :: ParsingMode ;
6
7
7
8
use std:: borrow:: Cow ;
8
9
use std:: io:: Read ;
9
10
10
11
pub ( crate ) fn parse_v2_header < R > (
11
12
reader : & mut R ,
13
+ parse_mode : ParsingMode ,
12
14
) -> Result < Option < ( FrameId < ' static > , u32 , FrameFlags ) > >
13
15
where
14
16
R : Read ,
@@ -24,12 +26,20 @@ where
24
26
return Ok ( None ) ;
25
27
}
26
28
27
- let frame_id = & frame_header[ ..3 ] ;
28
- let id_str = std:: str:: from_utf8 ( frame_id)
29
- . map_err ( |_| Id3v2Error :: new ( Id3v2ErrorKind :: BadFrameId ( frame_id. to_vec ( ) ) ) ) ?;
30
- let id = upgrade_v2 ( id_str) . map_or_else ( || Cow :: Owned ( id_str. to_owned ( ) ) , Cow :: Borrowed ) ;
31
-
32
- let frame_id = FrameId :: new_cow ( id) ?;
29
+ let frame_id_bytes = & frame_header[ ..3 ] ;
30
+ let frame_id = match std:: str:: from_utf8 ( frame_id_bytes)
31
+ . map_err ( |_| Id3v2Error :: new ( Id3v2ErrorKind :: BadFrameId ( frame_id_bytes. to_vec ( ) ) ) . into ( ) )
32
+ . map ( |id_str| {
33
+ upgrade_v2 ( id_str) . map_or_else ( || Cow :: Owned ( id_str. to_owned ( ) ) , Cow :: Borrowed )
34
+ } )
35
+ . and_then ( FrameId :: new_cow)
36
+ {
37
+ Ok ( id) => id,
38
+ Err ( err) => match parse_mode {
39
+ ParsingMode :: Strict => return Err ( err) ,
40
+ ParsingMode :: BestAttempt | ParsingMode :: Relaxed => return Ok ( None ) ,
41
+ } ,
42
+ } ;
33
43
34
44
let size = u32:: from_be_bytes ( [ 0 , frame_header[ 3 ] , frame_header[ 4 ] , frame_header[ 5 ] ] ) ;
35
45
40
50
pub ( crate ) fn parse_header < R > (
41
51
reader : & mut R ,
42
52
synchsafe : bool ,
53
+ parse_mode : ParsingMode ,
43
54
) -> Result < Option < ( FrameId < ' static > , u32 , FrameFlags ) > >
44
55
where
45
56
R : Read ,
64
75
frame_id_end = 3 ;
65
76
}
66
77
67
- let frame_id = & frame_header[ ..frame_id_end] ;
68
- let id_str = std:: str:: from_utf8 ( & frame_header[ ..frame_id_end] )
69
- . map_err ( |_| Id3v2Error :: new ( Id3v2ErrorKind :: BadFrameId ( frame_id. to_vec ( ) ) ) ) ?;
78
+ let frame_id_bytes = & frame_header[ ..frame_id_end] ;
79
+ let id_str = match std:: str:: from_utf8 ( frame_id_bytes)
80
+ . map_err ( |_| Id3v2Error :: new ( Id3v2ErrorKind :: BadFrameId ( frame_id_bytes. to_vec ( ) ) ) . into ( ) )
81
+ {
82
+ Ok ( id_str) => id_str,
83
+ Err ( err) => match parse_mode {
84
+ ParsingMode :: Strict => return Err ( err) ,
85
+ ParsingMode :: BestAttempt | ParsingMode :: Relaxed => return Ok ( None ) ,
86
+ } ,
87
+ } ;
70
88
71
89
let mut size = u32:: from_be_bytes ( [
72
90
frame_header[ 4 ] ,
@@ -87,7 +105,13 @@ where
87
105
} else {
88
106
Cow :: Owned ( id_str. to_owned ( ) )
89
107
} ;
90
- let frame_id = FrameId :: new_cow ( id) ?;
108
+ let frame_id = match FrameId :: new_cow ( id) {
109
+ Ok ( frame_id) => frame_id,
110
+ Err ( err) => match parse_mode {
111
+ ParsingMode :: Strict => return Err ( err) ,
112
+ ParsingMode :: BestAttempt | ParsingMode :: Relaxed => return Ok ( None ) ,
113
+ } ,
114
+ } ;
91
115
92
116
// unsynch the frame size if necessary
93
117
if synchsafe {
0 commit comments