Fix errors caused by incorrect delimiters

This commit is contained in:
David Howden 2015-05-19 22:09:32 +10:00
parent 0f62dc116a
commit 68d82a6107

View File

@ -37,9 +37,15 @@ func decodeText(enc byte, b []byte) (string, error) {
return decodeISO8859(b), nil
case 1: // UTF-16 with byte order marker
if len(b) == 1 {
return "", nil
}
return decodeUTF16WithBOM(b)
case 2: // UTF-16 without byte order (assuming BigEndian)
if len(b) == 1 {
return "", nil
}
return decodeUTF16(b, binary.BigEndian), nil
case 3: // UTF-8
@ -50,6 +56,17 @@ func decodeText(enc byte, b []byte) (string, error) {
}
}
func encodingDelim(enc byte) ([]byte, error) {
switch enc {
case 0, 3: // see decodeText above
return []byte{0}, nil
case 1, 2: // see decodeText above
return []byte{0, 0}, nil
default:
return nil, fmt.Errorf("invalid encoding byte %x", enc)
}
}
func decodeISO8859(b []byte) string {
r := make([]rune, len(b))
for i, x := range b {
@ -83,7 +100,6 @@ func decodeUTF16(b []byte, bo binary.ByteOrder) string {
// Comm is a type used in COMM and USLT tag. It's a text with a description and
// a specified language
type Comm struct {
Language string
Description string
@ -96,6 +112,40 @@ func (t Comm) String() string {
t.Language, t.Description, strings.Count(t.Text, "\n"))
}
// IDv2.{3,4}
// -- Header
// <Header for 'Unsynchronised lyrics/text transcription', ID: "USLT">
// <Header for 'Comment', ID: "COMM">
// -- readTextWithDescrFrame
// Text encoding $xx
// Language $xx xx xx
// Content descriptor <text string according to encoding> $00 (00)
// Lyrics/text <full text string according to encoding>
func readTextWithDescrFrame(b []byte) (*Comm, error) {
enc := b[0]
delim, err := encodingDelim(enc)
if err != nil {
return nil, err
}
descTextSplit := bytes.SplitN(b[4:], delim, 2)
desc, err := decodeText(enc, descTextSplit[0])
if err != nil {
return nil, fmt.Errorf("error decoding tag description text: %v", err)
}
text, err := decodeText(enc, descTextSplit[1])
if err != nil {
return nil, fmt.Errorf("error decoding tag text: %v", err)
}
return &Comm{
Language: string(b[1:4]),
Description: desc,
Text: text,
}, nil
}
var pictureTypes = map[byte]string{
0x00: "Other",
0x01: "32x32 pixels 'file icon' (PNG only)",
@ -150,7 +200,12 @@ func readPICFrame(b []byte) (*Picture, error) {
ext := string(b[1:4])
picType := b[4]
descDataSplit := bytes.SplitN(b[5:], []byte{0}, 2)
delim, err := encodingDelim(enc)
if err != nil {
return nil, err
}
descDataSplit := bytes.SplitN(b[5:], delim, 2)
desc, err := decodeText(enc, descDataSplit[0])
if err != nil {
return nil, fmt.Errorf("error decoding PIC description text: %v", err)
@ -173,35 +228,6 @@ func readPICFrame(b []byte) (*Picture, error) {
}, nil
}
// IDv2.{3,4}
// -- Header
// <Header for 'Unsynchronised lyrics/text transcription', ID: "USLT">
// <Header for 'Comment', ID: "COMM">
// -- readTextWithDescrFrame
// Text encoding $xx
// Language $xx xx xx
// Content descriptor <text string according to encoding> $00 (00)
// Lyrics/text <full text string according to encoding>
func readTextWithDescrFrame(b []byte) (*Comm, error) {
enc := b[0]
descTextSplit := bytes.SplitN(b[4:], []byte{0}, 2)
desc, err := decodeText(enc, descTextSplit[0])
if err != nil {
return nil, fmt.Errorf("error decoding tag description text: %v", err)
}
text, err := decodeText(enc, descTextSplit[1])
if err != nil {
return nil, fmt.Errorf("error decoding tag description text: %v", err)
}
return &Comm{
Language: string(b[1:4]),
Description: desc,
Text: text,
}, nil
}
// IDv2.{3,4}
// -- Header
// <Header for 'Attached picture', ID: "APIC">
@ -219,7 +245,12 @@ func readAPICFrame(b []byte) (*Picture, error) {
b = mimeDataSplit[1]
picType := b[0]
descDataSplit := bytes.SplitN(b[1:], []byte{0}, 2)
delim, err := encodingDelim(enc)
if err != nil {
return nil, err
}
descDataSplit := bytes.SplitN(b[1:], delim, 2)
desc, err := decodeText(enc, descDataSplit[0])
if err != nil {
return nil, fmt.Errorf("error decoding APIC description text: %v", err)