From 7e5c04feccd822269ccfabb38b2eb5f127c3b181 Mon Sep 17 00:00:00 2001 From: David Howden Date: Fri, 22 Nov 2019 22:50:59 +1100 Subject: [PATCH] move towards using uint for all sizes (#59) * move towards using uint for all sizes * dsf: support larger files --- dsf.go | 3 +-- id3v2.go | 30 +++++++++++++++--------------- mp4.go | 4 ++-- ogg.go | 4 ++-- util.go | 29 ++++++++++++++++++----------- util_test.go | 20 ++++++++++++-------- vorbis.go | 8 ++++---- 7 files changed, 54 insertions(+), 44 deletions(-) diff --git a/dsf.go b/dsf.go index d826a74..8ca34f2 100644 --- a/dsf.go +++ b/dsf.go @@ -26,11 +26,10 @@ func ReadDSFTags(r io.ReadSeeker) (Metadata, error) { return nil, err } - n4, err := readBytes(r, 8) + id3Pointer, err := readUint64LittleEndian(r) if err != nil { return nil, err } - id3Pointer := getIntLittleEndian(n4) _, err = r.Seek(int64(id3Pointer), io.SeekStart) if err != nil { diff --git a/id3v2.go b/id3v2.go index 063e6cb..74314bd 100644 --- a/id3v2.go +++ b/id3v2.go @@ -48,12 +48,12 @@ type id3v2Header struct { Unsynchronisation bool ExtendedHeader bool Experimental bool - Size int + Size uint } // readID3v2Header reads the ID3v2 header from the given io.Reader. // offset it number of bytes of header that was read -func readID3v2Header(r io.Reader) (h *id3v2Header, offset int, err error) { +func readID3v2Header(r io.Reader) (h *id3v2Header, offset uint, err error) { offset = 10 b, err := readBytes(r, offset) if err != nil { @@ -85,7 +85,7 @@ func readID3v2Header(r io.Reader) (h *id3v2Header, offset int, err error) { Unsynchronisation: getBit(b[2], 7), ExtendedHeader: getBit(b[2], 6), Experimental: getBit(b[2], 5), - Size: get7BitChunkedInt(b[3:7]), + Size: uint(get7BitChunkedInt(b[3:7])), } if h.ExtendedHeader { @@ -96,7 +96,7 @@ func readID3v2Header(r io.Reader) (h *id3v2Header, offset int, err error) { return nil, 0, fmt.Errorf("expected to read 4 bytes (ID3v23 extended header len): %v", err) } // skip header, size is excluding len bytes - extendedHeaderSize := getInt(b) + extendedHeaderSize := uint(getInt(b)) _, err = readBytes(r, extendedHeaderSize) if err != nil { return nil, 0, fmt.Errorf("expected to read %d bytes (ID3v23 skip extended header): %v", extendedHeaderSize, err) @@ -108,7 +108,7 @@ func readID3v2Header(r io.Reader) (h *id3v2Header, offset int, err error) { return nil, 0, fmt.Errorf("expected to read 4 bytes (ID3v24 extended header len): %v", err) } // skip header, size is synchsafe int including len bytes - extendedHeaderSize := get7BitChunkedInt(b) - 4 + extendedHeaderSize := uint(get7BitChunkedInt(b)) - 4 _, err = readBytes(r, extendedHeaderSize) if err != nil { return nil, 0, fmt.Errorf("expected to read %d bytes (ID3v24 skip extended header): %v", extendedHeaderSize, err) @@ -179,12 +179,12 @@ func readID3v24FrameFlags(r io.Reader) (*id3v2FrameFlags, error) { } -func readID3v2_2FrameHeader(r io.Reader) (name string, size int, headerSize int, err error) { +func readID3v2_2FrameHeader(r io.Reader) (name string, size uint, headerSize uint, err error) { name, err = readString(r, 3) if err != nil { return } - size, err = readInt(r, 3) + size, err = readUint(r, 3) if err != nil { return } @@ -192,12 +192,12 @@ func readID3v2_2FrameHeader(r io.Reader) (name string, size int, headerSize int, return } -func readID3v2_3FrameHeader(r io.Reader) (name string, size int, headerSize int, err error) { +func readID3v2_3FrameHeader(r io.Reader) (name string, size uint, headerSize uint, err error) { name, err = readString(r, 4) if err != nil { return } - size, err = readInt(r, 4) + size, err = readUint(r, 4) if err != nil { return } @@ -205,12 +205,12 @@ func readID3v2_3FrameHeader(r io.Reader) (name string, size int, headerSize int, return } -func readID3v2_4FrameHeader(r io.Reader) (name string, size int, headerSize int, err error) { +func readID3v2_4FrameHeader(r io.Reader) (name string, size uint, headerSize uint, err error) { name, err = readString(r, 4) if err != nil { return } - size, err = read7BitChunkedInt(r, 4) + size, err = read7BitChunkedUint(r, 4) if err != nil { return } @@ -219,13 +219,13 @@ func readID3v2_4FrameHeader(r io.Reader) (name string, size int, headerSize int, } // readID3v2Frames reads ID3v2 frames from the given reader using the ID3v2Header. -func readID3v2Frames(r io.Reader, offset int, h *id3v2Header) (map[string]interface{}, error) { +func readID3v2Frames(r io.Reader, offset uint, h *id3v2Header) (map[string]interface{}, error) { result := make(map[string]interface{}) for offset < h.Size { var err error var name string - var size, headerSize int + var size, headerSize uint var flags *id3v2FrameFlags switch h.Version { @@ -269,7 +269,7 @@ func readID3v2Frames(r io.Reader, offset int, h *id3v2Header) (map[string]interf if flags != nil { if flags.Compression { - _, err = read7BitChunkedInt(r, 4) // read 4 + _, err = read7BitChunkedUint(r, 4) // read 4 if err != nil { return nil, err } @@ -281,7 +281,7 @@ func readID3v2Frames(r io.Reader, offset int, h *id3v2Header) (map[string]interf if err != nil { return nil, err } - size -= 1 + size-- } } diff --git a/mp4.go b/mp4.go index 4c3dd59..bc0286b 100644 --- a/mp4.go +++ b/mp4.go @@ -138,7 +138,7 @@ func (m metadataMP4) readAtomData(r io.ReadSeeker, name string, size uint32, pro contentType = "text" } else { // read the data - b, err = readBytes(r, int(size)) + b, err = readBytes(r, uint(size)) if err != nil { return err } @@ -246,7 +246,7 @@ func readCustomAtom(r io.ReadSeeker, size uint32) (_ string, data []string, _ er return "", nil, errors.New("--- invalid size") } - b, err := readBytes(r, int(subSize-8)) + b, err := readBytes(r, uint(subSize-8)) if err != nil { return "", nil, err } diff --git a/ogg.go b/ogg.go index 3256b87..9d65183 100644 --- a/ogg.go +++ b/ogg.go @@ -132,7 +132,7 @@ func readPackets(r io.ReadSeeker) ([]byte, error) { firstPage = false // Read the number of segments - nS, err := readInt(r, 1) + nS, err := readUint(r, 1) if err != nil { return nil, err } @@ -145,7 +145,7 @@ func readPackets(r io.ReadSeeker) ([]byte, error) { // Calculate remaining page size pageSize := 0 - for i := 0; i < nS; i++ { + for i := uint(0); i < nS; i++ { pageSize += int(segments[i]) } diff --git a/util.go b/util.go index 7ffd0f8..73078ab 100644 --- a/util.go +++ b/util.go @@ -32,16 +32,15 @@ func getInt(b []byte) int { return n } -func getIntLittleEndian(b []byte) int { - var n int - for i := len(b) - 1; i >= 0; i-- { - n = n << 8 - n |= int(b[i]) +func readUint64LittleEndian(r io.Reader) (uint64, error) { + b, err := readBytes(r, 8) + if err != nil { + return 0, err } - return n + return binary.LittleEndian.Uint64(b), nil } -func readBytes(r io.Reader, n int) ([]byte, error) { +func readBytes(r io.Reader, n uint) ([]byte, error) { b := make([]byte, n) _, err := io.ReadFull(r, b) if err != nil { @@ -50,7 +49,7 @@ func readBytes(r io.Reader, n int) ([]byte, error) { return b, nil } -func readString(r io.Reader, n int) (string, error) { +func readString(r io.Reader, n uint) (string, error) { b, err := readBytes(r, n) if err != nil { return "", err @@ -58,7 +57,15 @@ func readString(r io.Reader, n int) (string, error) { return string(b), nil } -func readInt(r io.Reader, n int) (int, error) { +func readUint(r io.Reader, n uint) (uint, error) { + x, err := readInt(r, n) + if err != nil { + return 0, err + } + return uint(x), nil +} + +func readInt(r io.Reader, n uint) (int, error) { b, err := readBytes(r, n) if err != nil { return 0, err @@ -66,12 +73,12 @@ func readInt(r io.Reader, n int) (int, error) { return getInt(b), nil } -func read7BitChunkedInt(r io.Reader, n int) (int, error) { +func read7BitChunkedUint(r io.Reader, n uint) (uint, error) { b, err := readBytes(r, n) if err != nil { return 0, err } - return get7BitChunkedInt(b), nil + return uint(get7BitChunkedInt(b)), nil } func readUint32LittleEndian(r io.Reader) (uint32, error) { diff --git a/util_test.go b/util_test.go index a122fce..d0ab2e7 100644 --- a/util_test.go +++ b/util_test.go @@ -5,6 +5,7 @@ package tag import ( + "bytes" "testing" ) @@ -80,35 +81,38 @@ func TestGetInt(t *testing.T) { } } -func TestGetIntLittleEndian(t *testing.T) { +func TestGetUintLittleEndian(t *testing.T) { tests := []struct { input []byte - output int + output uint64 }{ { - []byte{}, + []byte{0, 0, 0, 0, 0, 0, 0, 0}, 0, }, { - []byte{0x01}, + []byte{0x01, 0, 0, 0, 0, 0, 0, 0}, 1, }, { - []byte{0xF1, 0xF2}, + []byte{0xF1, 0xF2, 0, 0, 0, 0, 0, 0}, 0xF2F1, }, { - []byte{0xF1, 0xF2, 0xF3}, + []byte{0xF1, 0xF2, 0xF3, 0, 0, 0, 0, 0}, 0xF3F2F1, }, { - []byte{0xF1, 0xF2, 0xF3, 0xF4}, + []byte{0xF1, 0xF2, 0xF3, 0xF4, 0, 0, 0, 0}, 0xF4F3F2F1, }, } for ii, tt := range tests { - got := getIntLittleEndian(tt.input) + got, err := readUint64LittleEndian(bytes.NewReader(tt.input)) + if err != nil { + t.Errorf("unexpected error: %v", err) + } if got != tt.output { t.Errorf("[%d] getInt(%v) = %v, expected %v", ii, tt.input, got, tt.output) } diff --git a/vorbis.go b/vorbis.go index a140c4a..057eb6e 100644 --- a/vorbis.go +++ b/vorbis.go @@ -30,7 +30,7 @@ func (m *metadataVorbis) readVorbisComment(r io.Reader) error { return err } - vendor, err := readString(r, int(vendorLen)) + vendor, err := readString(r, uint(vendorLen)) if err != nil { return err } @@ -46,7 +46,7 @@ func (m *metadataVorbis) readVorbisComment(r io.Reader) error { if err != nil { return err } - s, err := readString(r, int(l)) + s, err := readString(r, uint(l)) if err != nil { return err } @@ -68,7 +68,7 @@ func (m *metadataVorbis) readPictureBlock(r io.Reader) error { if !ok { return fmt.Errorf("invalid picture type: %v", b) } - mimeLen, err := readInt(r, 4) + mimeLen, err := readUint(r, 4) if err != nil { return err } @@ -87,7 +87,7 @@ func (m *metadataVorbis) readPictureBlock(r io.Reader) error { ext = "gif" } - descLen, err := readInt(r, 4) + descLen, err := readUint(r, 4) if err != nil { return err }