diff --git a/id3v2.go b/id3v2.go index c3052ec..c55ff50 100644 --- a/id3v2.go +++ b/id3v2.go @@ -167,6 +167,12 @@ func readID3v2Frames(r io.Reader, h *ID3v2Header) (map[string]interface{}, error return nil, err } + // Avoid corrupted padding (see http://id3.org/Compliance%20Issues). + if !validID3Frame(h.Version, name) { + break + } + + // FIXME: Do we still need this? // if size=0, we certainly are in a padding zone. ignore the rest of // the tags if size == 0 { diff --git a/id3v2frames.go b/id3v2frames.go index 23e4e8c..89903e2 100644 --- a/id3v2frames.go +++ b/id3v2frames.go @@ -13,6 +13,278 @@ import ( "unicode/utf16" ) +// ID3v2.2.0 frames (see http://id3.org/id3v2-00, sec 4). +var id3v22Frames = map[string]string{ + "BUF": "Recommended buffer size", + + "CNT": "Play counter", + "COM": "Comments", + "CRA": "Audio encryption", + "CRM": "Encrypted meta frame", + + "ETC": "Event timing codes", + "EQU": "Equalization", + + "GEO": "General encapsulated object", + + "IPL": "Involved people list", + + "LNK": "Linked information", + + "MCI": "Music CD Identifier", + "MLL": "MPEG location lookup table", + + "PIC": "Attached picture", + "POP": "Popularimeter", + + "REV": "Reverb", + "RVA": "Relative volume adjustment", + + "SLT": "Synchronized lyric/text", + "STC": "Synced tempo codes", + + "TAL": "Album/Movie/Show title", + "TBP": "BPM (Beats Per Minute)", + "TCM": "Composer", + "TCO": "Content type", + "TCR": "Copyright message", + "TDA": "Date", + "TDY": "Playlist delay", + "TEN": "Encoded by", + "TFT": "File type", + "TIM": "Time", + "TKE": "Initial key", + "TLA": "Language(s)", + "TLE": "Length", + "TMT": "Media type", + "TOA": "Original artist(s)/performer(s)", + "TOF": "Original filename", + "TOL": "Original Lyricist(s)/text writer(s)", + "TOR": "Original release year", + "TOT": "Original album/Movie/Show title", + "TP1": "Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group", + "TP2": "Band/Orchestra/Accompaniment", + "TP3": "Conductor/Performer refinement", + "TP4": "Interpreted, remixed, or otherwise modified by", + "TPA": "Part of a set", + "TPB": "Publisher", + "TRC": "ISRC (International Standard Recording Code)", + "TRD": "Recording dates", + "TRK": "Track number/Position in set", + "TSI": "Size", + "TSS": "Software/hardware and settings used for encoding", + "TT1": "Content group description", + "TT2": "Title/Songname/Content description", + "TT3": "Subtitle/Description refinement", + "TXT": "Lyricist/text writer", + "TXX": "User defined text information frame", + "TYE": "Year", + + "UFI": "Unique file identifier", + "ULT": "Unsychronized lyric/text transcription", + + "WAF": "Official audio file webpage", + "WAR": "Official artist/performer webpage", + "WAS": "Official audio source webpage", + "WCM": "Commercial information", + "WCP": "Copyright/Legal information", + "WPB": "Publishers official webpage", + "WXX": "User defined URL link frame", +} + +// ID3v2.3.0 frames (see http://id3.org/id3v2.3.0#Declared_ID3v2_frames). +var id3v23Frames = map[string]string{ + "AENC": "Audio encryption]", + "APIC": "Attached picture", + "COMM": "Comments", + "COMR": "Commercial frame", + "ENCR": "Encryption method registration", + "EQUA": "Equalization", + "ETCO": "Event timing codes", + "GEOB": "General encapsulated object", + "GRID": "Group identification registration", + "IPLS": "Involved people list", + "LINK": "Linked information", + "MCDI": "Music CD identifier", + "MLLT": "MPEG location lookup table", + "OWNE": "Ownership frame", + "PRIV": "Private frame", + "PCNT": "Play counter", + "POPM": "Popularimeter", + "POSS": "Position synchronisation frame", + "RBUF": "Recommended buffer size", + "RVAD": "Relative volume adjustment", + "RVRB": "Reverb", + "SYLT": "Synchronized lyric/text", + "SYTC": "Synchronized tempo codes", + "TALB": "Album/Movie/Show title", + "TBPM": "BPM (beats per minute)", + "TCOM": "Composer", + "TCON": "Content type", + "TCOP": "Copyright message", + "TDAT": "Date", + "TDLY": "Playlist delay", + "TENC": "Encoded by", + "TEXT": "Lyricist/Text writer", + "TFLT": "File type", + "TIME": "Time", + "TIT1": "Content group description", + "TIT2": "Title/songname/content description", + "TIT3": "Subtitle/Description refinement", + "TKEY": "Initial key", + "TLAN": "Language(s)", + "TLEN": "Length", + "TMED": "Media type", + "TOAL": "Original album/movie/show title", + "TOFN": "Original filename", + "TOLY": "Original lyricist(s)/text writer(s)", + "TOPE": "Original artist(s)/performer(s)", + "TORY": "Original release year", + "TOWN": "File owner/licensee", + "TPE1": "Lead performer(s)/Soloist(s)", + "TPE2": "Band/orchestra/accompaniment", + "TPE3": "Conductor/performer refinement", + "TPE4": "Interpreted, remixed, or otherwise modified by", + "TPOS": "Part of a set", + "TPUB": "Publisher", + "TRCK": "Track number/Position in set", + "TRDA": "Recording dates", + "TRSN": "Internet radio station name", + "TRSO": "Internet radio station owner", + "TSIZ": "Size", + "TSRC": "ISRC (international standard recording code)", + "TSSE": "Software/Hardware and settings used for encoding", + "TYER": "Year", + "TXXX": "User defined text information frame", + "UFID": "Unique file identifier", + "USER": "Terms of use", + "USLT": "Unsychronized lyric/text transcription", + "WCOM": "Commercial information", + "WCOP": "Copyright/Legal information", + "WOAF": "Official audio file webpage", + "WOAR": "Official artist/performer webpage", + "WOAS": "Official audio source webpage", + "WORS": "Official internet radio station homepage", + "WPAY": "Payment", + "WPUB": "Publishers official webpage", + "WXXX": "User defined URL link frame", +} + +// ID3v2.4.0 frames (see http://id3.org/id3v2.4.0-frames, sec 4). +var id3v24Frames = map[string]string{ + "AENC": "Audio encryption", + "APIC": "Attached picture", + "ASPI": "Audio seek point index", + + "COMM": "Comments", + "COMR": "Commercial frame", + + "ENCR": "Encryption method registration", + "EQU2": "Equalisation (2)", + "ETCO": "Event timing codes", + + "GEOB": "General encapsulated object", + "GRID": "Group identification registration", + + "LINK": "Linked information", + + "MCDI": "Music CD identifier", + "MLLT": "MPEG location lookup table", + + "OWNE": "Ownership frame", + + "PRIV": "Private frame", + "PCNT": "Play counter", + "POPM": "Popularimeter", + "POSS": "Position synchronisation frame", + + "RBUF": "Recommended buffer size", + "RVA2": "Relative volume adjustment (2)", + "RVRB": "Reverb", + + "SEEK": "Seek frame", + "SIGN": "Signature frame", + "SYLT": "Synchronised lyric/text", + "SYTC": "Synchronised tempo codes", + + "TALB": "Album/Movie/Show title", + "TBPM": "BPM (beats per minute)", + "TCOM": "Composer", + "TCON": "Content type", + "TCOP": "Copyright message", + "TDEN": "Encoding time", + "TDLY": "Playlist delay", + "TDOR": "Original release time", + "TDRC": "Recording time", + "TDRL": "Release time", + "TDTG": "Tagging time", + "TENC": "Encoded by", + "TEXT": "Lyricist/Text writer", + "TFLT": "File type", + "TIPL": "Involved people list", + "TIT1": "Content group description", + "TIT2": "Title/songname/content description", + "TIT3": "Subtitle/Description refinement", + "TKEY": "Initial key", + "TLAN": "Language(s)", + "TLEN": "Length", + "TMCL": "Musician credits list", + "TMED": "Media type", + "TMOO": "Mood", + "TOAL": "Original album/movie/show title", + "TOFN": "Original filename", + "TOLY": "Original lyricist(s)/text writer(s)", + "TOPE": "Original artist(s)/performer(s)", + "TOWN": "File owner/licensee", + "TPE1": "Lead performer(s)/Soloist(s)", + "TPE2": "Band/orchestra/accompaniment", + "TPE3": "Conductor/performer refinement", + "TPE4": "Interpreted, remixed, or otherwise modified by", + "TPOS": "Part of a set", + "TPRO": "Produced notice", + "TPUB": "Publisher", + "TRCK": "Track number/Position in set", + "TRSN": "Internet radio station name", + "TRSO": "Internet radio station owner", + "TSOA": "Album sort order", + "TSOP": "Performer sort order", + "TSOT": "Title sort order", + "TSRC": "ISRC (international standard recording code)", + "TSSE": "Software/Hardware and settings used for encoding", + "TSST": "Set subtitle", + "TXXX": "User defined text information frame", + + "UFID": "Unique file identifier", + "USER": "Terms of use", + "USLT": "Unsynchronised lyric/text transcription", + + "WCOM": "Commercial information", + "WCOP": "Copyright/Legal information", + "WOAF": "Official audio file webpage", + "WOAR": "Official artist/performer webpage", + "WOAS": "Official audio source webpage", + "WORS": "Official Internet radio station homepage", + "WPAY": "Payment", + "WPUB": "Publishers official webpage", + "WXXX": "User defined URL link frame", +} + +// ID3 frames that are defined in the specs. +var id3Frames = map[Format]map[string]string{ + ID3v2_2: id3v22Frames, + ID3v2_3: id3v23Frames, + ID3v2_4: id3v24Frames, +} + +func validID3Frame(version Format, name string) bool { + names, ok := id3Frames[version] + if !ok { + return false + } + _, ok = names[name] + return ok +} + func readWFrame(b []byte) (string, error) { // Frame text is always encoded in ISO-8859-1 b = append([]byte{0}, b...)