diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 83e77d0d..00fb0b17 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: - uses: golangci/golangci-lint-action@v3 with: - version: v1.55.0 + version: v1.55.2 go-mod-tidy: runs-on: ubuntu-20.04 diff --git a/.golangci.yml b/.golangci.yml index 593d6b20..d2c93841 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,7 +1,10 @@ linters: enable: + - asciicheck + - bidichk - bodyclose - dupl + - errorlint - exportloopref - gochecknoinits - gocritic @@ -13,6 +16,7 @@ linters: - prealloc - revive - unconvert + - tparallel - wastedassign - whitespace diff --git a/Makefile b/Makefile index cc16e4b8..3459af40 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ BASE_IMAGE = golang:1.21-alpine3.18 -LINT_IMAGE = golangci/golangci-lint:v1.55.0 +LINT_IMAGE = golangci/golangci-lint:v1.55.2 .PHONY: $(shell ls) diff --git a/pkg/description/session.go b/pkg/description/session.go index aa4f6911..57a338f8 100644 --- a/pkg/description/session.go +++ b/pkg/description/session.go @@ -80,7 +80,7 @@ func (d *Session) Unmarshal(ssd *sdp.SessionDescription) error { var m Media err := m.Unmarshal(md) if err != nil { - return fmt.Errorf("media %d is invalid: %v", i+1, err) + return fmt.Errorf("media %d is invalid: %w", i+1, err) } if m.ID != "" && hasMediaWithID(d.Medias[:i], m.ID) { diff --git a/pkg/format/h265.go b/pkg/format/h265.go index b3a4f85c..17bfa932 100644 --- a/pkg/format/h265.go +++ b/pkg/format/h265.go @@ -53,7 +53,7 @@ func (f *H265) unmarshal(ctx *unmarshalContext) error { var spsp h265.SPS err = spsp.Unmarshal(f.SPS) if err != nil { - return fmt.Errorf("invalid SPS: %v", err) + return fmt.Errorf("invalid SPS: %w", err) } case "sprop-pps": @@ -69,7 +69,7 @@ func (f *H265) unmarshal(ctx *unmarshalContext) error { var ppsp h265.PPS err = ppsp.Unmarshal(f.PPS) if err != nil { - return fmt.Errorf("invalid PPS: %v", err) + return fmt.Errorf("invalid PPS: %w", err) } case "sprop-max-don-diff": diff --git a/pkg/format/mpeg4_audio.go b/pkg/format/mpeg4_audio.go index 633cc162..eb7b0e6b 100644 --- a/pkg/format/mpeg4_audio.go +++ b/pkg/format/mpeg4_audio.go @@ -141,7 +141,7 @@ func (f *MPEG4Audio) unmarshal(ctx *unmarshalContext) error { f.StreamMuxConfig = &mpeg4audio.StreamMuxConfig{} err = f.StreamMuxConfig.Unmarshal(enc) if err != nil { - return fmt.Errorf("invalid AAC config: %v", err) + return fmt.Errorf("invalid AAC config: %w", err) } case "sbr-enabled": diff --git a/pkg/format/mpeg4_video.go b/pkg/format/mpeg4_video.go index 1b28c45c..ba638de5 100644 --- a/pkg/format/mpeg4_video.go +++ b/pkg/format/mpeg4_video.go @@ -46,7 +46,7 @@ func (f *MPEG4Video) unmarshal(ctx *unmarshalContext) error { err = mpeg4video.IsValidConfig(f.Config) if err != nil { - return fmt.Errorf("invalid config: %v", err) + return fmt.Errorf("invalid config: %w", err) } } } diff --git a/pkg/format/rtpac3/decoder_test.go b/pkg/format/rtpac3/decoder_test.go index 81743bce..4121b654 100644 --- a/pkg/format/rtpac3/decoder_test.go +++ b/pkg/format/rtpac3/decoder_test.go @@ -1,6 +1,7 @@ package rtpac3 import ( + "errors" "testing" "github.com/pion/rtp" @@ -24,7 +25,7 @@ func TestDecode(t *testing.T) { // test input integrity require.Equal(t, clone, pkt) - if err == ErrMorePacketsNeeded { + if errors.Is(err, ErrMorePacketsNeeded) { continue } diff --git a/pkg/format/rtpav1/decoder.go b/pkg/format/rtpav1/decoder.go index d37d1497..258025e6 100644 --- a/pkg/format/rtpav1/decoder.go +++ b/pkg/format/rtpav1/decoder.go @@ -52,7 +52,7 @@ func (d *Decoder) decodeOBUs(pkt *rtp.Packet) ([][]byte, error) { if err != nil { d.fragments = d.fragments[:0] // discard pending fragments d.fragmentsSize = 0 - return nil, fmt.Errorf("invalid header: %v", err) + return nil, fmt.Errorf("invalid header: %w", err) } for _, el := range av1header.OBUElements { diff --git a/pkg/format/rtpav1/decoder_test.go b/pkg/format/rtpav1/decoder_test.go index 89139dbc..dbe1c3ff 100644 --- a/pkg/format/rtpav1/decoder_test.go +++ b/pkg/format/rtpav1/decoder_test.go @@ -1,6 +1,7 @@ package rtpav1 import ( + "errors" "testing" "github.com/bluenviron/mediacommon/pkg/codecs/av1" @@ -19,7 +20,7 @@ func TestDecode(t *testing.T) { for _, pkt := range ca.pkts { addOBUs, err := d.Decode(pkt) - if err == ErrMorePacketsNeeded { + if errors.Is(err, ErrMorePacketsNeeded) { continue } diff --git a/pkg/format/rtph264/decoder_test.go b/pkg/format/rtph264/decoder_test.go index e858c4fe..8293a46d 100644 --- a/pkg/format/rtph264/decoder_test.go +++ b/pkg/format/rtph264/decoder_test.go @@ -2,6 +2,7 @@ package rtph264 import ( "bytes" + "errors" "testing" "github.com/bluenviron/mediacommon/pkg/codecs/h264" @@ -26,7 +27,7 @@ func TestDecode(t *testing.T) { // test input integrity require.Equal(t, clone, pkt) - if err == ErrMorePacketsNeeded { + if errors.Is(err, ErrMorePacketsNeeded) { continue } diff --git a/pkg/format/rtph265/decoder_test.go b/pkg/format/rtph265/decoder_test.go index 78129fda..82baaaba 100644 --- a/pkg/format/rtph265/decoder_test.go +++ b/pkg/format/rtph265/decoder_test.go @@ -1,6 +1,7 @@ package rtph265 import ( + "errors" "testing" "github.com/bluenviron/mediacommon/pkg/codecs/h265" @@ -25,7 +26,7 @@ func TestDecode(t *testing.T) { // test input integrity require.Equal(t, clone, pkt) - if err == ErrMorePacketsNeeded { + if errors.Is(err, ErrMorePacketsNeeded) { continue } diff --git a/pkg/format/rtpmjpeg/decoder_test.go b/pkg/format/rtpmjpeg/decoder_test.go index 5f537877..87e9074e 100644 --- a/pkg/format/rtpmjpeg/decoder_test.go +++ b/pkg/format/rtpmjpeg/decoder_test.go @@ -1,6 +1,7 @@ package rtpmjpeg import ( + "errors" "testing" "github.com/pion/rtp" @@ -16,7 +17,7 @@ func TestDecode(t *testing.T) { for _, pkt := range ca.pkts { image, err := d.Decode(pkt) - if err == ErrMorePacketsNeeded { + if errors.Is(err, ErrMorePacketsNeeded) { continue } diff --git a/pkg/format/rtpmpeg4audio/decoder_generic.go b/pkg/format/rtpmpeg4audio/decoder_generic.go index d40a4fc0..4d9019c1 100644 --- a/pkg/format/rtpmpeg4audio/decoder_generic.go +++ b/pkg/format/rtpmpeg4audio/decoder_generic.go @@ -176,7 +176,7 @@ func (d *Decoder) removeADTS(aus [][]byte) ([][]byte, error) { var pkts mpeg4audio.ADTSPackets err := pkts.Unmarshal(aus[0]) if err != nil { - return nil, fmt.Errorf("unable to decode ADTS: %s", err) + return nil, fmt.Errorf("unable to decode ADTS: %w", err) } if len(pkts) != 1 { diff --git a/pkg/format/rtpmpeg4audio/decoder_generic_test.go b/pkg/format/rtpmpeg4audio/decoder_generic_test.go index fd8ccaab..ead128b5 100644 --- a/pkg/format/rtpmpeg4audio/decoder_generic_test.go +++ b/pkg/format/rtpmpeg4audio/decoder_generic_test.go @@ -1,6 +1,7 @@ package rtpmpeg4audio import ( + "errors" "testing" "github.com/pion/rtp" @@ -28,7 +29,7 @@ func TestDecodeGeneric(t *testing.T) { // test input integrity require.Equal(t, clone, pkt) - if err == ErrMorePacketsNeeded { + if errors.Is(err, ErrMorePacketsNeeded) { continue } diff --git a/pkg/format/rtpmpeg4audio/decoder_latm_test.go b/pkg/format/rtpmpeg4audio/decoder_latm_test.go index e6f0d322..4cb0e3fd 100644 --- a/pkg/format/rtpmpeg4audio/decoder_latm_test.go +++ b/pkg/format/rtpmpeg4audio/decoder_latm_test.go @@ -1,6 +1,7 @@ package rtpmpeg4audio import ( + "errors" "testing" "github.com/pion/rtp" @@ -26,7 +27,7 @@ func TestDecodeLATM(t *testing.T) { // test input integrity require.Equal(t, clone, pkt) - if err == ErrMorePacketsNeeded { + if errors.Is(err, ErrMorePacketsNeeded) { continue } diff --git a/pkg/format/rtpmpeg4video/decoder_test.go b/pkg/format/rtpmpeg4video/decoder_test.go index 90be7437..abaa7b98 100644 --- a/pkg/format/rtpmpeg4video/decoder_test.go +++ b/pkg/format/rtpmpeg4video/decoder_test.go @@ -1,6 +1,7 @@ package rtpmpeg4video import ( + "errors" "testing" "github.com/pion/rtp" @@ -18,7 +19,7 @@ func TestDecode(t *testing.T) { for _, pkt := range ca.pkts { frame, err = d.Decode(pkt) - if err == ErrMorePacketsNeeded { + if errors.Is(err, ErrMorePacketsNeeded) { continue } diff --git a/server_conn.go b/server_conn.go index b51ef5c0..c3633c32 100644 --- a/server_conn.go +++ b/server_conn.go @@ -3,6 +3,7 @@ package gortsplib import ( "context" "crypto/tls" + "errors" "net" gourl "net/url" "strconv" @@ -384,7 +385,8 @@ func (sc *ServerConn) handleRequestOuter(req *base.Request) error { } // add cseq - if _, ok := err.(liberrors.ErrServerCSeqMissing); !ok { + var eerr liberrors.ErrServerCSeqMissing + if !errors.As(err, &eerr) { res.Header["CSeq"] = req.Header["CSeq"] } diff --git a/server_conn_reader.go b/server_conn_reader.go index 489e44b0..b5e89160 100644 --- a/server_conn_reader.go +++ b/server_conn_reader.go @@ -1,6 +1,7 @@ package gortsplib import ( + "errors" "sync/atomic" "time" @@ -8,17 +9,17 @@ import ( "github.com/bluenviron/gortsplib/v4/pkg/liberrors" ) -type errSwitchReadFunc struct { +type switchReadFuncError struct { tcp bool } -func (errSwitchReadFunc) Error() string { +func (switchReadFuncError) Error() string { return "switching read function" } -func isErrSwitchReadFunc(err error) bool { - _, ok := err.(errSwitchReadFunc) - return ok +func isSwitchReadFuncError(err error) bool { + var eerr switchReadFuncError + return errors.As(err, &eerr) } type serverConnReader struct { @@ -44,8 +45,9 @@ func (cr *serverConnReader) run() { for { err := readFunc() - if err, ok := err.(errSwitchReadFunc); ok { - if err.tcp { + var eerr switchReadFuncError + if errors.As(err, &eerr) { + if eerr.tcp { readFunc = cr.readFuncTCP } else { readFunc = cr.readFuncStandard diff --git a/server_session.go b/server_session.go index e4a56dd2..cfc12818 100644 --- a/server_session.go +++ b/server_session.go @@ -403,7 +403,7 @@ func (ss *ServerSession) runInner() error { returnedSession := ss - if err == nil || isErrSwitchReadFunc(err) { + if err == nil || isSwitchReadFuncError(err) { // ANNOUNCE responses don't contain the session header. if req.req.Method != base.Announce && req.req.Method != base.Teardown { @@ -444,7 +444,7 @@ func (ss *ServerSession) runInner() error { ss: returnedSession, } - if (err == nil || isErrSwitchReadFunc(err)) && savedMethod == base.Teardown { + if (err == nil || isSwitchReadFuncError(err)) && savedMethod == base.Teardown { return liberrors.ErrServerSessionTornDown{Author: req.sc.NetConn().RemoteAddr()} } @@ -951,7 +951,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( default: // TCP ss.tcpConn = sc - err = errSwitchReadFunc{true} + err = switchReadFuncError{true} // writer.start() is called by ServerConn after the response has been sent } @@ -1034,7 +1034,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( default: // TCP ss.tcpConn = sc - err = errSwitchReadFunc{true} + err = switchReadFuncError{true} // runWriter() is called by conn after sending the response } @@ -1089,7 +1089,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( ss.udpCheckStreamTimer = emptyTimer() default: // TCP - err = errSwitchReadFunc{false} + err = switchReadFuncError{false} ss.tcpConn = nil } @@ -1099,7 +1099,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( ss.udpCheckStreamTimer = emptyTimer() default: // TCP - err = errSwitchReadFunc{false} + err = switchReadFuncError{false} ss.tcpConn = nil } @@ -1112,7 +1112,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( var err error if (ss.state == ServerSessionStatePlay || ss.state == ServerSessionStateRecord) && *ss.setuppedTransport == TransportTCP { - err = errSwitchReadFunc{false} + err = switchReadFuncError{false} } return &base.Response{