Skip to content

Commit

Permalink
Fix linter problems, clean up unused code
Browse files Browse the repository at this point in the history
- Disable unsupported linters
- Fix problems with line lengths
- Fix error comparison with modern one using errors.Is()
- Wrap errors to fix some linter problems
- kaitai/stream.go: fix rest of wrapping errors
- kaitai/util.go: fix error wrapping problems
- kaitai/writer.go: fix wrapping problems
- kaitai/stream.go: fix traceless messages for invalid size requested
- Rewrite TestStream_ReadBitsIntBe + TestStream_ReadBitsIntLe to avoid duplication
- Remove unused/obsolete functions and tests for them: ReadStrEOS, ReadStrByteLimit, ReadBitsArray
  • Loading branch information
GreyCat authored Mar 29, 2024
2 parents aefeff8 + 5e3c2c2 commit 296c155
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 175 deletions.
4 changes: 0 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ linters:
- bodyclose
- contextcheck
- cyclop
- deadcode
# - depguard
- dogsled
- dupl
Expand Down Expand Up @@ -45,7 +44,6 @@ linters:
- gosec
- gosimple
- govet
- ifshort
- importas
- ineffassign
- ireturn
Expand All @@ -67,7 +65,6 @@ linters:
- rowserrcheck
- sqlclosecheck
- staticcheck
- structcheck
- stylecheck
- tagliatelle
- tenv
Expand All @@ -78,7 +75,6 @@ linters:
- unconvert
- unparam
- unused
- varcheck
# - varnamelen
- wastedassign
- whitespace
Expand Down
9 changes: 6 additions & 3 deletions kaitai/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ type ValidationNotEqualError struct {
}

// NewValidationNotEqualError creates a new ValidationNotEqualError instance.
func NewValidationNotEqualError(expected interface{}, actual interface{}, io *Stream, srcPath string) ValidationNotEqualError {
func NewValidationNotEqualError(
expected interface{}, actual interface{}, io *Stream, srcPath string) ValidationNotEqualError {
return ValidationNotEqualError{
expected,
actual,
Expand Down Expand Up @@ -93,7 +94,8 @@ type ValidationLessThanError struct {
}

// NewValidationLessThanError creates a new ValidationLessThanError instance.
func NewValidationLessThanError(min interface{}, actual interface{}, io *Stream, srcPath string) ValidationLessThanError {
func NewValidationLessThanError(
min interface{}, actual interface{}, io *Stream, srcPath string) ValidationLessThanError {
return ValidationLessThanError{
min,
actual,
Expand Down Expand Up @@ -124,7 +126,8 @@ type ValidationGreaterThanError struct {
}

// NewValidationGreaterThanError creates a new ValidationGreaterThanError instance.
func NewValidationGreaterThanError(max interface{}, actual interface{}, io *Stream, srcPath string) ValidationGreaterThanError {
func NewValidationGreaterThanError(
max interface{}, actual interface{}, io *Stream, srcPath string) ValidationGreaterThanError {
return ValidationGreaterThanError{
max,
actual,
Expand Down
106 changes: 58 additions & 48 deletions kaitai/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"bytes"
"encoding/binary"
"errors"
"fmt"
"io"
"io/ioutil"
Expand All @@ -13,6 +14,13 @@ import (
// APIVersion defines the currently used API version.
const APIVersion = 0x0001

// ErrInvalidSizeRequested is returned when KaitaiStream methods are called
// with a size argument which does not make sense:
//
// - ReadBytes with negative number of bytes
// - ReadBitsIntBe/Le with more than 8 bytes
var ErrInvalidSizeRequested = errors.New("invalid size requested")

// A Stream represents a sequence of bytes. It encapsulates reading from files
// and memory, stores pointer to its current position, and allows
// reading/writing of various primitives.
Expand Down Expand Up @@ -42,7 +50,7 @@ func (k *Stream) EOF() (bool, error) {

isEOF := false
_, err = k.ReadU1()
if err == io.EOF {
if errors.Is(err, io.EOF) {
isEOF = true
err = nil
}
Expand All @@ -51,7 +59,11 @@ func (k *Stream) EOF() (bool, error) {
}

_, err = k.Seek(curPos, io.SeekStart)
return isEOF, err
if err != nil {
return false, fmt.Errorf("EOF: error seeking back to current position: %w", err)
}

return isEOF, nil
}

// Size returns the number of bytes of the stream.
Expand All @@ -66,7 +78,7 @@ func (k *Stream) Size() (int64, error) {
// Seek to the end of the File object
_, err = k.Seek(0, io.SeekEnd)
if err != nil {
return 0, err
return 0, fmt.Errorf("Size: error seeking to end of the stream: %w", err)
}
// Remember position, which is equal to the full length
fullSize, err := k.Pos()
Expand All @@ -75,66 +87,73 @@ func (k *Stream) Size() (int64, error) {
}
// Seek back to the current position
_, err = k.Seek(curPos, io.SeekStart)
return fullSize, err
if err != nil {
return fullSize, fmt.Errorf("Size: error seeking back to current position: %w", err)
}
return fullSize, nil
}

// Pos returns the current position of the stream.
func (k *Stream) Pos() (int64, error) {
return k.Seek(0, io.SeekCurrent)
pos, err := k.Seek(0, io.SeekCurrent)
if err != nil {
return pos, fmt.Errorf("Pos: error getting current position: %w", err)
}
return pos, nil
}

// ReadU1 reads 1 byte and returns this as uint8.
func (k *Stream) ReadU1() (v uint8, err error) {
if _, err = k.Read(k.buf[:1]); err != nil {
return 0, err
return 0, fmt.Errorf("ReadU1: error reading 1 byte: %w", err)
}
return k.buf[0], nil
}

// ReadU2be reads 2 bytes in big-endian order and returns those as uint16.
func (k *Stream) ReadU2be() (v uint16, err error) {
if _, err = k.Read(k.buf[:2]); err != nil {
return 0, err
return 0, fmt.Errorf("ReadU2be: error reading 2 bytes: %w", err)
}
return binary.BigEndian.Uint16(k.buf[:2]), nil
}

// ReadU4be reads 4 bytes in big-endian order and returns those as uint32.
func (k *Stream) ReadU4be() (v uint32, err error) {
if _, err = k.Read(k.buf[:4]); err != nil {
return 0, err
return 0, fmt.Errorf("ReadU4be: error reading 4 bytes: %w", err)
}
return binary.BigEndian.Uint32(k.buf[:4]), nil
}

// ReadU8be reads 8 bytes in big-endian order and returns those as uint64.
func (k *Stream) ReadU8be() (v uint64, err error) {
if _, err = k.Read(k.buf[:8]); err != nil {
return 0, err
return 0, fmt.Errorf("ReadU8be: error reading 8 bytes: %w", err)
}
return binary.BigEndian.Uint64(k.buf[:8]), nil
}

// ReadU2le reads 2 bytes in little-endian order and returns those as uint16.
func (k *Stream) ReadU2le() (v uint16, err error) {
if _, err = k.Read(k.buf[:2]); err != nil {
return 0, err
return 0, fmt.Errorf("ReadU2le: error reading 2 bytes: %w", err)
}
return binary.LittleEndian.Uint16(k.buf[:2]), nil
}

// ReadU4le reads 4 bytes in little-endian order and returns those as uint32.
func (k *Stream) ReadU4le() (v uint32, err error) {
if _, err = k.Read(k.buf[:4]); err != nil {
return 0, err
return 0, fmt.Errorf("ReadU4le: error reading 4 bytes: %w", err)
}
return binary.LittleEndian.Uint32(k.buf[:4]), nil
}

// ReadU8le reads 8 bytes in little-endian order and returns those as uint64.
func (k *Stream) ReadU8le() (v uint64, err error) {
if _, err = k.Read(k.buf[:8]); err != nil {
return 0, err
return 0, fmt.Errorf("ReadU8le: error reading 8 bytes: %w", err)
}
return binary.LittleEndian.Uint64(k.buf[:8]), nil
}
Expand Down Expand Up @@ -208,17 +227,24 @@ func (k *Stream) ReadF8le() (v float64, err error) {
// ReadBytes reads n bytes and returns those as a byte array.
func (k *Stream) ReadBytes(n int) (b []byte, err error) {
if n < 0 {
return nil, fmt.Errorf("ReadBytes(%d): negative number of bytes to read", n)
return nil, fmt.Errorf("ReadBytes(%d): %w", n, ErrInvalidSizeRequested)
}

b = make([]byte, n)
_, err = io.ReadFull(k, b)
return b, err
if err != nil {
return nil, fmt.Errorf("ReadBytes: error reading %d bytes: %w", n, err)
}
return b, nil
}

// ReadBytesFull reads all remaining bytes and returns those as a byte array.
func (k *Stream) ReadBytesFull() ([]byte, error) {
return ioutil.ReadAll(k)
res, err := ioutil.ReadAll(k)
if err != nil {
return nil, fmt.Errorf("ReadBytesFull: error reading all bytes: %w", err)
}
return res, nil
}

// ReadBytesPadTerm reads up to size bytes. pad bytes are discarded. It
Expand Down Expand Up @@ -256,38 +282,27 @@ func (k *Stream) ReadBytesTerm(term byte, includeTerm, consumeTerm, eosError boo
}
slice, err := r.ReadBytes(term)

if err != nil && (err != io.EOF || eosError) {
return slice, err
if err != nil {
// If eosError if false, ignore io.EOF and bail out on any other error
// If eosError is true, bail out on any error, including io.EOF
if eosError || !errors.Is(err, io.EOF) {
return slice, fmt.Errorf("ReadBytesTerm: error reading bytes until term byte: %w", err)
}
}
_, err = k.Seek(pos+int64(len(slice)), io.SeekStart)
if err != nil {
return []byte{}, err
return []byte{}, fmt.Errorf("ReadBytesTerm: error seeking past term byte: %w", err)
}
if !includeTerm {
slice = slice[:len(slice)-1]
}
if !consumeTerm {
_, err = k.Seek(-1, io.SeekCurrent)
if err != nil {
return slice, fmt.Errorf("ReadBytesTerm: error seeking to term byte: %w", err)
}
}
return slice, err
}

// ReadStrEOS reads the remaining bytes as a string.
func (k *Stream) ReadStrEOS(encoding string) (string, error) {
buf, err := ioutil.ReadAll(k)

// Go's string type can contain any bytes. The Go `range` operator
// assumes that the encoding is UTF-8 and some standard Go libraries
// also would like UTF-8. For now we'll leave any advanced
// conversions up to the user.
return string(buf), err
}

// ReadStrByteLimit reads limit number of bytes and returns those as a string.
func (k *Stream) ReadStrByteLimit(limit int, encoding string) (string, error) {
buf := make([]byte, limit)
n, err := k.Read(buf)
return string(buf[:n]), err
return slice, nil
}

// AlignToByte discards the remaining bits and starts reading bits at the
Expand All @@ -310,11 +325,11 @@ func (k *Stream) ReadBitsIntBe(n int) (res uint64, err error) {
// 9 bits => 2 bytes
bytesNeeded := ((bitsNeeded - 1) / 8) + 1 // `ceil(bitsNeeded / 8)`
if bytesNeeded > 8 {
return res, fmt.Errorf("ReadBitsIntBe(%d): more than 8 bytes requested", n)
return res, fmt.Errorf("ReadBitsIntBe(%d): more than 8 bytes requested: %w", n, ErrInvalidSizeRequested)
}
_, err = k.Read(k.buf[:bytesNeeded])
if err != nil {
return res, err
return res, fmt.Errorf("ReadBitsIntBe(%d): %w", n, err)
}
for i := 0; i < bytesNeeded; i++ {
res = res<<8 | uint64(k.buf[i])
Expand All @@ -330,7 +345,7 @@ func (k *Stream) ReadBitsIntBe(n int) (res uint64, err error) {
var mask uint64 = (1 << k.bitsLeft) - 1 // `bitsLeft` is in range 0..7
k.bits &= mask

return res, err
return res, nil
}

// ReadBitsInt reads n-bit integer in big-endian byte order and returns it as uint64.
Expand All @@ -351,11 +366,11 @@ func (k *Stream) ReadBitsIntLe(n int) (res uint64, err error) {
// 9 bits => 2 bytes
bytesNeeded := ((bitsNeeded - 1) / 8) + 1 // `ceil(bitsNeeded / 8)`
if bytesNeeded > 8 {
return res, fmt.Errorf("ReadBitsIntLe(%d): more than 8 bytes requested", n)
return res, fmt.Errorf("ReadBitsIntLe(%d): more than 8 bytes requested: %w", n, ErrInvalidSizeRequested)
}
_, err = k.Read(k.buf[:bytesNeeded])
if err != nil {
return res, err
return res, fmt.Errorf("ReadBitsIntLe(%d): %w", n, err)
}
for i := 0; i < bytesNeeded; i++ {
res |= uint64(k.buf[i]) << (i * 8)
Expand All @@ -373,10 +388,5 @@ func (k *Stream) ReadBitsIntLe(n int) (res uint64, err error) {

var mask uint64 = (1 << n) - 1 // unlike some other languages, no problem with this in Go
res &= mask
return res, err
}

// ReadBitsArray is not implemented yet.
func (k *Stream) ReadBitsArray(n uint) error {
return nil // TODO: implement
return res, nil
}
Loading

0 comments on commit 296c155

Please sign in to comment.