diff --git a/go.mod b/go.mod
index 6a0b9cf..a5ad50d 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.23.2
require (
github.com/BurntSushi/toml v1.4.0
- github.com/lrstanley/girc v0.0.0-20240914071631-5c0cc76257bf
+ github.com/lrstanley/girc v1.1.1
mellium.im/sasl v0.3.2
mellium.im/xmpp v0.22.0
)
diff --git a/go.sum b/go.sum
index b62a687..d304a29 100644
--- a/go.sum
+++ b/go.sum
@@ -2,6 +2,8 @@ github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/lrstanley/girc v0.0.0-20240914071631-5c0cc76257bf h1:DptjWYSDVuCSxM++oM/NJInqiD5v+z/PI6T3/OMWJR4=
github.com/lrstanley/girc v0.0.0-20240914071631-5c0cc76257bf/go.mod h1:lgrnhcF8bg/Bd5HA5DOb4Z+uGqUqGnp4skr+J2GwVgI=
+github.com/lrstanley/girc v1.1.1 h1:0Y8a2tqQGDeFXfBQkAYOu5DbWqlydCJsi+4N+td4azk=
+github.com/lrstanley/girc v1.1.1/go.mod h1:lgrnhcF8bg/Bd5HA5DOb4Z+uGqUqGnp4skr+J2GwVgI=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
diff --git a/vendor/github.com/lrstanley/girc/.editorconfig b/vendor/github.com/lrstanley/girc/.editorconfig
index 4ae34fd..302b0ba 100644
--- a/vendor/github.com/lrstanley/girc/.editorconfig
+++ b/vendor/github.com/lrstanley/girc/.editorconfig
@@ -33,7 +33,6 @@ indent_size = 2
[*.json]
indent_size = 2
-insert_final_newline = ignore
[*.html]
max_line_length = 140
@@ -47,7 +46,6 @@ indent_style = tab
[**.min.js]
indent_style = ignore
-insert_final_newline = ignore
[*.bat]
indent_style = tab
diff --git a/vendor/github.com/lrstanley/girc/.golangci.yaml b/vendor/github.com/lrstanley/girc/.golangci.yaml
new file mode 100644
index 0000000..b8b1c95
--- /dev/null
+++ b/vendor/github.com/lrstanley/girc/.golangci.yaml
@@ -0,0 +1,223 @@
+# THIS FILE IS GENERATED! DO NOT EDIT! Maintained by Terraform.
+#
+# golangci-lint: https://golangci-lint.run/
+# false-positives: https://golangci-lint.run/usage/false-positives/
+# actual source: https://github.com/lrstanley/.github/blob/master/terraform/github-common-files/templates/.golangci.yml
+# modified variant of: https://gist.github.com/maratori/47a4d00457a92aa426dbd48a18776322
+
+version: "2"
+
+formatters:
+ enable: [gofumpt]
+
+issues:
+ max-issues-per-linter: 0
+ max-same-issues: 50
+
+severity:
+ default: error
+ rules:
+ - linters:
+ - errcheck
+ - gocritic
+ severity: warning
+
+linters:
+ default: none
+ enable:
+ - asasalint # checks for pass []any as any in variadic func(...any)
+ - asciicheck # checks that your code does not contain non-ASCII identifiers
+ - bidichk # checks for dangerous unicode character sequences
+ - bodyclose # checks whether HTTP response body is closed successfully
+ - canonicalheader # checks whether net/http.Header uses canonical header
+ - copyloopvar # detects places where loop variables are copied (Go 1.22+)
+ - depguard # checks if package imports are in a list of acceptable packages
+ - dupl # tool for code clone detection
+ - durationcheck # checks for two durations multiplied together
+ - errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases
+ - errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error
+ - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13
+ - exhaustive # checks exhaustiveness of enum switch statements
+ - exptostd # detects functions from golang.org/x/exp/ that can be replaced by std functions
+ - fatcontext # detects nested contexts in loops
+ - forbidigo # forbids identifiers
+ - funlen # tool for detection of long functions
+ - gocheckcompilerdirectives # validates go compiler directive comments (//go:)
+ - gochecknoinits # checks that no init functions are present in Go code
+ - gochecksumtype # checks exhaustiveness on Go "sum types"
+ - gocognit # computes and checks the cognitive complexity of functions
+ - goconst # finds repeated strings that could be replaced by a constant
+ - gocritic # provides diagnostics that check for bugs, performance and style issues
+ # TODO: breaks multi-line comments when used with --fix: https://github.com/tetafro/godot/issues/39
+ # - godot # checks if comments end in a period
+ - gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod
+ - goprintffuncname # checks that printf-like functions are named with f at the end
+ - gosec # inspects source code for security problems
+ - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
+ - iface # checks the incorrect use of interfaces, helping developers avoid interface pollution
+ - ineffassign # detects when assignments to existing variables are not used
+ - intrange # finds places where for loops could make use of an integer range
+ - loggercheck # checks key value pairs for common logger libraries (kitlog,klog,logr,zap)
+ - makezero # finds slice declarations with non-zero initial length
+ - mirror # reports wrong mirror patterns of bytes/strings usage
+ - misspell # [useless] finds commonly misspelled English words in comments
+ - musttag # enforces field tags in (un)marshaled structs
+ - nakedret # finds naked returns in functions greater than a specified function length
+ - nestif # reports deeply nested if statements
+ - nilerr # finds the code that returns nil even if it checks that the error is not nil
+ - nilnesserr # reports that it checks for err != nil, but it returns a different nil value error (powered by nilness and nilerr)
+ - nilnil # checks that there is no simultaneous return of nil error and an invalid value
+ - noctx # finds sending http request without context.Context
+ - nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL
+ - perfsprint # checks that fmt.Sprintf can be replaced with a faster alternative
+ - predeclared # finds code that shadows one of Go's predeclared identifiers
+ - promlinter # checks Prometheus metrics naming via promlint
+ - reassign # checks that package variables are not reassigned
+ - recvcheck # checks for receiver type consistency
+ - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint
+ - rowserrcheck # checks whether Err of rows is checked successfully
+ - sloglint # ensure consistent code style when using log/slog
+ - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed
+ - staticcheck # is a go vet on steroids, applying a ton of static analysis checks
+ - testableexamples # checks if examples are testable (have an expected output)
+ - testifylint # checks usage of github.com/stretchr/testify
+ - tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes
+ - unconvert # removes unnecessary type conversions
+ - unparam # reports unused function parameters
+ - unused # checks for unused constants, variables, functions and types
+ - usestdlibvars # detects the possibility to use variables/constants from the Go standard library
+ - usetesting # reports uses of functions with replacement inside the testing package
+ - wastedassign # finds wasted assignment statements
+ - whitespace # detects leading and trailing whitespace
+
+ settings:
+ gocognit:
+ min-complexity: 40
+ errcheck:
+ check-type-assertions: true
+ funlen:
+ lines: 150
+ statements: 75
+ ignore-comments: true
+ gocritic:
+ disabled-checks:
+ - whyNoLint
+ - hugeParam
+ - ifElseChain
+ - singleCaseSwitch
+ enabled-tags:
+ - diagnostic
+ - opinionated
+ - performance
+ - style
+ settings:
+ captLocal:
+ paramsOnly: false
+ underef:
+ skipRecvDeref: false
+ rangeValCopy:
+ sizeThreshold: 512
+ depguard:
+ rules:
+ "deprecated":
+ files: ["$all"]
+ deny:
+ - pkg: github.com/golang/protobuf
+ desc: Use google.golang.org/protobuf instead, see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules
+ - pkg: github.com/satori/go.uuid
+ desc: Use github.com/google/uuid instead, satori's package is not maintained
+ - pkg: github.com/gofrs/uuid$
+ desc: Use github.com/gofrs/uuid/v5 or later, it was not a go module before v5
+ "non-test files":
+ files: ["!$test"]
+ deny:
+ - pkg: math/rand$
+ desc: Use math/rand/v2 instead, see https://go.dev/blog/randv2
+ "non-main files":
+ files: ["!**/main.go"]
+ deny:
+ - pkg: log$
+ desc: Use log/slog instead, see https://go.dev/blog/slog
+ "incorrect import":
+ files: ["$test"]
+ deny:
+ - pkg: github.com/tj/assert$
+ desc: Use github.com/stretchr/testify/assert instead, see
+ gochecksumtype:
+ default-signifies-exhaustive: false
+ exhaustive:
+ check:
+ - switch
+ - map
+ govet:
+ disable:
+ - fieldalignment
+ enable-all: true
+ settings:
+ shadow:
+ strict: true
+ perfsprint:
+ strconcat: false
+ nakedret:
+ max-func-lines: 0
+ nestif:
+ min-complexity: 10
+ rowserrcheck:
+ packages:
+ - github.com/jmoiron/sqlx
+ sloglint:
+ no-global: default
+ context: scope
+ staticcheck:
+ checks:
+ - all
+ # Incorrect or missing package comment: https://staticcheck.dev/docs/checks/#ST1000
+ - -ST1000
+ # Use consistent method receiver names: https://staticcheck.dev/docs/checks/#ST1016
+ - -ST1016
+ # Omit embedded fields from selector expression: https://staticcheck.dev/docs/checks/#QF1008
+ - -QF1008
+ # duplicate struct tags -- used commonly for things like go-flags.
+ - -SA5008
+ usetesting:
+ os-temp-dir: true
+ exclusions:
+ warn-unused: true
+ generated: lax
+ presets:
+ - common-false-positives
+ - std-error-handling
+ paths:
+ - ".*\\.gen\\.go$"
+ - ".*\\.gen_test\\.go$"
+ rules:
+ - source: "TODO"
+ linters: [godot]
+ - text: "should have a package comment"
+ linters: [revive]
+ - text: 'exported \S+ \S+ should have comment( \(or a comment on this block\))? or be unexported'
+ linters: [revive]
+ - text: 'package comment should be of the form ".+"'
+ source: "// ?(nolint|TODO)"
+ linters: [revive]
+ - text: 'comment on exported \S+ \S+ should be of the form ".+"'
+ source: "// ?(nolint|TODO)"
+ linters: [revive, staticcheck]
+ - text: 'unexported-return: exported func \S+ returns unexported type \S+ .*'
+ linters: [revive]
+ - text: "var-declaration: should drop .* from declaration of .*; it is the zero value"
+ linters: [revive]
+ - text: ".*use ALL_CAPS in Go names.*"
+ linters: [revive, staticcheck]
+ - text: '.* always receives \S+'
+ linters: [unparam]
+ - path: _test\.go
+ linters:
+ - bodyclose
+ - dupl
+ - funlen
+ - gocognit
+ - goconst
+ - gosec
+ - noctx
+ - wrapcheck
diff --git a/vendor/github.com/lrstanley/girc/.golangci.yml b/vendor/github.com/lrstanley/girc/.golangci.yml
deleted file mode 100644
index c0acb79..0000000
--- a/vendor/github.com/lrstanley/girc/.golangci.yml
+++ /dev/null
@@ -1,228 +0,0 @@
-# THIS FILE IS GENERATED! DO NOT EDIT! Maintained by Terraform.
-#
-# golangci-lint: https://golangci-lint.run/
-# false-positives: https://golangci-lint.run/usage/false-positives/
-# actual source: https://github.com/lrstanley/.github/blob/master/terraform/github-common-files/templates/.golangci.yml
-# modified variant of: https://gist.github.com/maratori/47a4d00457a92aa426dbd48a18776322
-#
-
-run:
- timeout: 3m
-
-issues:
- max-issues-per-linter: 0
- max-same-issues: 50
-
- exclude-rules:
- - source: "(noinspection|TODO)"
- linters: [godot]
- - source: "//noinspection"
- linters: [gocritic]
- - path: "_test\\.go"
- linters:
- - bodyclose
- - dupl
- - funlen
- - goconst
- - gosec
- - noctx
- - wrapcheck
-
-severity:
- default-severity: error
- rules:
- - linters:
- - errcheck
- - gocritic
- severity: warning
-
-linters:
- disable-all: true
- enable:
- - asasalint # checks for pass []any as any in variadic func(...any)
- - asciicheck # checks that your code does not contain non-ASCII identifiers
- - bidichk # checks for dangerous unicode character sequences
- - bodyclose # checks whether HTTP response body is closed successfully
- - canonicalheader # checks whether net/http.Header uses canonical header
- - copyloopvar # detects places where loop variables are copied
- - cyclop # checks function and package cyclomatic complexity
- - dupl # tool for code clone detection
- - durationcheck # checks for two durations multiplied together
- - errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases
- - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13
- - exportloopref # checks for pointers to enclosing loop variables
- - fatcontext # detects nested contexts in loops
- - forbidigo # forbids identifiers
- - funlen # tool for detection of long functions
- - gci # controls golang package import order and makes it always deterministic
- - gocheckcompilerdirectives # validates go compiler directive comments (//go:)
- - gochecknoinits # checks that no init functions are present in Go code
- - gochecksumtype # checks exhaustiveness on Go "sum types"
- - goconst # finds repeated strings that could be replaced by a constant
- - gocritic # provides diagnostics that check for bugs, performance and style issues
- - gocyclo # computes and checks the cyclomatic complexity of functions
- - godot # checks if comments end in a period
- - godox # detects FIXME, TODO and other comment keywords
- - goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt
- - gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod
- - gomodguard # allow and block lists linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations
- - goprintffuncname # checks that printf-like functions are named with f at the end
- - gosec # inspects source code for security problems
- - gosimple # specializes in simplifying a code
- - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
- - ineffassign # detects when assignments to existing variables are not used
- - intrange # finds places where for loops could make use of an integer range
- - loggercheck # checks key value pairs for common logger libraries (kitlog,klog,logr,zap)
- - makezero # finds slice declarations with non-zero initial length
- - misspell # finds commonly misspelled words
- - musttag # enforces field tags in (un)marshaled structs
- - nakedret # finds naked returns in functions greater than a specified function length
- - nilerr # finds the code that returns nil even if it checks that the error is not nil
- - nilnil # checks that there is no simultaneous return of nil error and an invalid value
- - noctx # finds sending http request without context.Context
- - nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL
- - perfsprint # checks that fmt.Sprintf can be replaced with a faster alternative
- - predeclared # finds code that shadows one of Go's predeclared identifiers
- - promlinter # checks Prometheus metrics naming via promlint
- - reassign # checks that package variables are not reassigned
- - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint
- - rowserrcheck # checks whether Err of rows is checked successfully
- - sloglint # ensure consistent code style when using log/slog
- - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed
- - staticcheck # is a go vet on steroids, applying a ton of static analysis checks
- - stylecheck # is a replacement for golint
- # - tagalign # aligns struct tags -- disable for now (https://github.com/4meepo/tagalign/issues/13)
- - tenv # detects using os.Setenv instead of t.Setenv since Go1.17
- - testableexamples # checks if examples are testable (have an expected output)
- - testifylint # checks usage of github.com/stretchr/testify
- - tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes
- - typecheck # like the front-end of a Go compiler, parses and type-checks Go code
- - unconvert # removes unnecessary type conversions
- - unparam # reports unused function parameters
- - unused # checks for unused constants, variables, functions and types
- - usestdlibvars # detects the possibility to use variables/constants from the Go standard library
- - wastedassign # finds wasted assignment statements
- - whitespace # detects leading and trailing whitespace
-
-linters-settings:
- cyclop:
- # The maximal code complexity to report.
- max-complexity: 30
- # The maximal average package complexity.
- # If it's higher than 0.0 (float) the check is enabled
- package-average: 10.0
-
- errcheck:
- # Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
- # Such cases aren't reported by default.
- check-type-assertions: true
-
- funlen:
- # Checks the number of lines in a function.
- lines: 150
- # Checks the number of statements in a function.
- statements: 75
- # Ignore comments.
- ignore-comments: true
-
- gocritic:
- disabled-checks:
- - whyNoLint
- - hugeParam
- - ifElseChain
- enabled-tags:
- - diagnostic
- - opinionated
- - performance
- - style
- # https://go-critic.github.io/overview.
- settings:
- captLocal:
- # Whether to restrict checker to params only.
- paramsOnly: false
- underef:
- # Whether to skip (*x).method() calls where x is a pointer receiver.
- skipRecvDeref: false
-
- gomodguard:
- blocked:
- # List of blocked modules.
- modules:
- - github.com/golang/protobuf:
- recommendations:
- - google.golang.org/protobuf
- reason: "see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules"
- - github.com/satori/go.uuid:
- recommendations:
- - github.com/google/uuid
- reason: "satori's package is not maintained"
- - github.com/gofrs/uuid:
- recommendations:
- - github.com/google/uuid
- reason: "gofrs' package is not go module"
-
- govet:
- enable-all: true
- # Run `go tool vet help` to see all analyzers.
- disable:
- - fieldalignment # too strict
- settings:
- shadow:
- # Whether to be strict about shadowing; can be noisy.
- strict: true
-
- nakedret:
- # Make an issue if func has more lines of code than this setting, and it has naked returns.
- max-func-lines: 0
-
- rowserrcheck:
- # database/sql is always checked
- packages:
- - github.com/jmoiron/sqlx
-
- stylecheck:
- checks:
- - all
- - -ST1008 # handled by revive already.
-
- sloglint:
- # Enforce not using global loggers.
- no-global: "all"
- # Enforce using methods that accept a context.
- context: "scope"
-
- tagalign:
- align: true
- sort: true
- order:
- # go-flags items
- - command
- - alias
- - group
- - namespace
- - env-namespace
- - subcommands-optional
- - env
- - env-delim
- - short
- - long
- - no-flag
- - hidden
- - required
- - value-name
- - default
- - choice
- - description
- - long-description
- # everything else
- - json
- - yaml
- - yml
- - toml
- - validate
- strict: false
-
- tenv:
- # The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.
- # Otherwise, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.
- all: true
diff --git a/vendor/github.com/lrstanley/girc/README.md b/vendor/github.com/lrstanley/girc/README.md
index 2a33757..4ffd420 100644
--- a/vendor/github.com/lrstanley/girc/README.md
+++ b/vendor/github.com/lrstanley/girc/README.md
@@ -15,6 +15,8 @@
+
+
@@ -147,7 +149,7 @@ Working on a project and want to add it to the list? Submit a pull request!
```
MIT License
-Copyright (c) 2016 Liam Stanley
+Copyright (c) 2016 Liam Stanley
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/github.com/lrstanley/girc/builtin.go b/vendor/github.com/lrstanley/girc/builtin.go
index 345452e..401565a 100644
--- a/vendor/github.com/lrstanley/girc/builtin.go
+++ b/vendor/github.com/lrstanley/girc/builtin.go
@@ -102,7 +102,7 @@ func handleConnect(c *Client, e Event) {
// nickCollisionHandler helps prevent the client from having conflicting
// nicknames with another bot, user, etc.
-func nickCollisionHandler(c *Client, e Event) {
+func nickCollisionHandler(c *Client, _ Event) {
if c.Config.HandleNickCollide == nil {
c.Cmd.Nick(c.GetNick() + "_")
return
@@ -119,7 +119,7 @@ func handlePING(c *Client, e Event) {
c.Cmd.Pong(e.Last())
}
-func handlePONG(c *Client, e Event) {
+func handlePONG(c *Client, _ Event) {
c.conn.mu.Lock()
c.conn.lastPong = time.Now()
c.conn.mu.Unlock()
@@ -223,14 +223,19 @@ func handlePART(c *Client, e Event) {
// handleTOPIC handles incoming TOPIC events and keeps channel tracking info
// updated with the latest channel topic.
func handleTOPIC(c *Client, e Event) {
- var name string
+ var name, topic string
switch len(e.Params) {
case 0:
return
- case 1:
+ case 1: // TOPIC, message format is `TOPIC `
name = e.Params[0]
- default:
+ topic = ""
+ case 2: // TOPIC, message format is `TOPIC :`
+ name = e.Params[0]
+ topic = e.Last()
+ default: // RPL_TOPIC, message format is `332 :`
name = e.Params[1]
+ topic = e.Last()
}
c.state.Lock()
@@ -240,7 +245,7 @@ func handleTOPIC(c *Client, e Event) {
return
}
- channel.Topic = e.Last()
+ channel.Topic = topic
c.state.Unlock()
c.state.notify(c, UPDATE_STATE)
}
@@ -508,7 +513,6 @@ func handleNAMES(c *Client, e Event) {
if s == nil {
continue
}
-
} else {
s = &Source{
Name: nick,
diff --git a/vendor/github.com/lrstanley/girc/cap.go b/vendor/github.com/lrstanley/girc/cap.go
index f35f2ec..e502035 100644
--- a/vendor/github.com/lrstanley/girc/cap.go
+++ b/vendor/github.com/lrstanley/girc/cap.go
@@ -117,6 +117,8 @@ func parseCap(raw string) map[string]map[string]string {
// handleCAP attempts to find out what IRCv3 capabilities the server supports.
// This will lock further registration until we have acknowledged (or denied)
// the capabilities.
+//
+//nolint:nestif,gocognit
func handleCAP(c *Client, e Event) {
c.state.Lock()
defer c.state.Unlock()
diff --git a/vendor/github.com/lrstanley/girc/cap_tags.go b/vendor/github.com/lrstanley/girc/cap_tags.go
index 3cc8887..718ab21 100644
--- a/vendor/github.com/lrstanley/girc/cap_tags.go
+++ b/vendor/github.com/lrstanley/girc/cap_tags.go
@@ -64,7 +64,7 @@ type Tags map[string]string
func ParseTags(raw string) (t Tags) {
t = make(Tags)
- if len(raw) > 0 && raw[0] == prefixTag {
+ if raw != "" && raw[0] == prefixTag {
raw = raw[1:]
}
@@ -143,8 +143,8 @@ func (t Tags) Bytes() []byte {
return []byte{}
}
- max := len(t)
- if max == 0 {
+ maxb := len(t)
+ if maxb == 0 {
return nil
}
@@ -170,13 +170,13 @@ func (t Tags) Bytes() []byte {
buffer.WriteString(names[i])
// Write the value as necessary.
- if len(t[names[i]]) > 0 {
+ if t[names[i]] != "" {
buffer.WriteByte(prefixTagValue)
buffer.WriteString(t[names[i]])
}
// add the separator ";" between tags.
- if current < max-1 {
+ if current < maxb-1 {
buffer.WriteByte(tagSeparator)
}
@@ -263,7 +263,7 @@ func (t Tags) Set(key, value string) error {
value = tagEncoder.Replace(value)
- if len(value) > 0 && !validTagValue(value) {
+ if value != "" && !validTagValue(value) {
return fmt.Errorf("tag value %q of key %q is invalid", value, key)
}
diff --git a/vendor/github.com/lrstanley/girc/client.go b/vendor/github.com/lrstanley/girc/client.go
index 9376619..c36b8cf 100644
--- a/vendor/github.com/lrstanley/girc/client.go
+++ b/vendor/github.com/lrstanley/girc/client.go
@@ -10,7 +10,7 @@ import (
"errors"
"fmt"
"io"
- "log"
+ "log" //nolint:depguard
"net"
"os"
"runtime"
@@ -210,19 +210,24 @@ func (w WebIRC) Params() []string {
return []string{w.Password, w.Gateway, w.Hostname, w.Address}
}
-// ErrInvalidConfig is returned when the configuration passed to the client
+// ErrInvalidConfig is aliased to InvalidConfigError.
+//
+// Deprecated: use InvalidConfigError instead.
+type ErrInvalidConfig = InvalidConfigError //nolint:errname
+
+// InvalidConfigError is returned when the configuration passed to the client
// is invalid.
-type ErrInvalidConfig struct {
+type InvalidConfigError struct {
Conf Config // Conf is the configuration that was not valid.
err error
}
-func (e ErrInvalidConfig) Error() string { return "invalid configuration: " + e.err.Error() }
+func (e InvalidConfigError) Error() string { return "invalid configuration: " + e.err.Error() }
// isValid checks some basic settings to ensure the config is valid.
func (conf *Config) isValid() error {
if conf.Server == "" {
- return &ErrInvalidConfig{Conf: *conf, err: errors.New("empty server")}
+ return &InvalidConfigError{Conf: *conf, err: errors.New("empty server")}
}
// Default port to 6667 (the standard IRC port).
@@ -231,14 +236,14 @@ func (conf *Config) isValid() error {
}
if conf.Port < 1 || conf.Port > 65535 {
- return &ErrInvalidConfig{Conf: *conf, err: errors.New("port outside valid range (1-65535)")}
+ return &InvalidConfigError{Conf: *conf, err: errors.New("port outside valid range (1-65535)")}
}
if !IsValidNick(conf.Nick) {
- return &ErrInvalidConfig{Conf: *conf, err: errors.New("bad nickname specified")}
+ return &InvalidConfigError{Conf: *conf, err: errors.New("bad nickname specified")}
}
if !IsValidUser(conf.User) {
- return &ErrInvalidConfig{Conf: *conf, err: errors.New("bad user/ident specified")}
+ return &InvalidConfigError{Conf: *conf, err: errors.New("bad user/ident specified")}
}
return nil
@@ -386,14 +391,19 @@ func (c *Client) Quit(reason string) {
c.Send(&Event{Command: QUIT, Params: []string{reason}})
}
-// ErrEvent is an error returned when the server (or library) sends an ERROR
+// ErrEvent is an alias to EventError.
+//
+// Deprecated: use EventError instead.
+type ErrEvent = EventError //nolint:errname
+
+// EventError is an error returned when the server (or library) sends an ERROR
// message response. The string returned contains the trailing text from the
// message.
-type ErrEvent struct {
+type EventError struct {
Event *Event
}
-func (e *ErrEvent) Error() string {
+func (e *EventError) Error() string {
if e.Event == nil {
return "unknown error occurred"
}
@@ -438,7 +448,7 @@ func (c *Client) execLoop(ctx context.Context) error {
// if this library is the source of the error, this should
// signal back up to the main connect loop, to disconnect.
- return &ErrEvent{Event: event}
+ return &EventError{Event: event}
}
}
}
@@ -723,12 +733,12 @@ func (c *Client) GetServerOptionInt(key string) (result int, ok bool) {
// by the protocol. If state tracking is enabled, this will utilize ISUPPORT/IRCv3
// information to more accurately calculate the maximum supported length (i.e. extended
// length events).
-func (c *Client) MaxEventLength() (max int) {
+func (c *Client) MaxEventLength() (maxLen int) {
if !c.Config.disableTracking {
c.state.RLock()
- max = c.state.maxLineLength - c.state.maxPrefixLength
+ maxLen = c.state.maxLineLength - c.state.maxPrefixLength
c.state.RUnlock()
- return max
+ return maxLen
}
return DefaultMaxLineLength - DefaultMaxPrefixLength
}
diff --git a/vendor/github.com/lrstanley/girc/commands.go b/vendor/github.com/lrstanley/girc/commands.go
index a3bec87..5f2759e 100644
--- a/vendor/github.com/lrstanley/girc/commands.go
+++ b/vendor/github.com/lrstanley/girc/commands.go
@@ -26,12 +26,12 @@ func (cmd *Commands) Nick(name string) {
func (cmd *Commands) Join(channels ...string) {
// We can join multiple channels at once, however we need to ensure that
// we are not exceeding the line length (see Client.MaxEventLength()).
- max := cmd.c.MaxEventLength() - len(JOIN) - 1
+ maxLen := cmd.c.MaxEventLength() - len(JOIN) - 1
var buffer string
for i := 0; i < len(channels); i++ {
- if len(buffer+","+channels[i]) > max {
+ if len(buffer+","+channels[i]) > maxLen {
cmd.c.Send(&Event{Command: JOIN, Params: []string{buffer}})
buffer = ""
continue
@@ -218,6 +218,19 @@ func (cmd *Commands) SendRawf(format string, a ...interface{}) error {
return cmd.SendRaw(fmt.Sprintf(format, a...))
}
+// SendRawNoSplit sends a raw string directly to the server without any splitting
+// or length checking. Use with caution - this bypasses all safety checks.
+func (cmd *Commands) SendRawNoSplit(raw string) error {
+ event := ParseEvent(raw)
+ if event == nil {
+ return errors.New("invalid event: " + raw)
+ }
+
+ // Call write directly to bypass Send's splitting logic
+ cmd.c.write(event)
+ return nil
+}
+
// Topic sets the topic of channel to message. Does not verify the length
// of the topic.
func (cmd *Commands) Topic(channel, message string) {
@@ -330,12 +343,12 @@ func (cmd *Commands) List(channels ...string) {
// We can LIST multiple channels at once, however we need to ensure that
// we are not exceeding the line length (see Client.MaxEventLength()).
- max := cmd.c.MaxEventLength() - len(JOIN) - 1
+ maxLen := cmd.c.MaxEventLength() - len(JOIN) - 1
var buffer string
for i := 0; i < len(channels); i++ {
- if len(buffer+","+channels[i]) > max {
+ if len(buffer+","+channels[i]) > maxLen {
cmd.c.Send(&Event{Command: LIST, Params: []string{buffer}})
buffer = ""
continue
diff --git a/vendor/github.com/lrstanley/girc/conn.go b/vendor/github.com/lrstanley/girc/conn.go
index 58a0a60..1467817 100644
--- a/vendor/github.com/lrstanley/girc/conn.go
+++ b/vendor/github.com/lrstanley/girc/conn.go
@@ -8,8 +8,9 @@ import (
"bufio"
"context"
"crypto/tls"
- "fmt"
+ "errors"
"net"
+ "strconv"
"sync"
"time"
@@ -96,21 +97,7 @@ func newConn(conf Config, dialer Dialer, addr string, sts *strictTransport) (*ir
}
if conf.SSL || sts.enabled() {
- var tlsConn net.Conn
- tlsConn, err = tlsHandshake(conn, conf.TLSConfig, conf.Server, true)
- if err != nil {
- if sts.enabled() {
- err = &ErrSTSUpgradeFailed{Err: err}
- }
-
- if sts.expired() && !conf.DisableSTSFallback {
- sts.lastFailed = time.Now()
- sts.reset()
- }
- return nil, err
- }
-
- conn = tlsConn
+ conn = tlsHandshake(conn, conf.TLSConfig, conf.Server, true)
}
ctime := time.Now()
@@ -137,12 +124,17 @@ func newMockConn(conn net.Conn) *ircConn {
return c
}
-// ErrParseEvent is returned when an event cannot be parsed with ParseEvent().
-type ErrParseEvent struct {
+// ErrParseEvent is aliased to ParseEventError.
+//
+// Deprecated: use ParseEventError instead.
+type ErrParseEvent = ParseEventError //nolint:errname
+
+// ParseEventError is returned when an event cannot be parsed with ParseEvent().
+type ParseEventError struct {
Line string
}
-func (e ErrParseEvent) Error() string { return "unable to parse event: " + e.Line }
+func (e ParseEventError) Error() string { return "unable to parse event: " + e.Line }
type decodedEvent struct {
event *Event
@@ -188,13 +180,13 @@ func (c *ircConn) newReadWriter() {
c.io = bufio.NewReadWriter(bufio.NewReader(c.sock), bufio.NewWriter(c.sock))
}
-func tlsHandshake(conn net.Conn, conf *tls.Config, server string, validate bool) (net.Conn, error) {
+func tlsHandshake(conn net.Conn, conf *tls.Config, server string, validate bool) net.Conn {
if conf == nil {
- conf = &tls.Config{ServerName: server, InsecureSkipVerify: !validate}
+ conf = &tls.Config{ServerName: server, InsecureSkipVerify: !validate} //nolint:gosec
}
tlsConn := tls.Client(conn, conf)
- return net.Conn(tlsConn), nil
+ return net.Conn(tlsConn)
}
// Close closes the underlying socket.
@@ -296,7 +288,8 @@ startConn:
c.debug.Printf("connecting to %s... (sts: %v, config-ssl: %v)", addr, c.state.sts.enabled(), c.Config.SSL)
conn, err := newConn(c.Config, dialer, addr, &c.state.sts)
if err != nil {
- if _, ok := err.(*ErrSTSUpgradeFailed); ok {
+ errSTSUpgradeFailed := &ErrSTSUpgradeFailed{}
+ if errors.As(err, &errSTSUpgradeFailed) {
if !c.state.sts.enabled() {
c.RunHandlers(&Event{Command: STS_ERR_FALLBACK})
}
@@ -446,8 +439,7 @@ func (c *Client) Send(event *Event) {
event.Params[len(event.Params)-1] = Fmt(event.Params[len(event.Params)-1])
}
- var events []*Event
- events = event.split(c.MaxEventLength())
+ events := event.split(c.MaxEventLength())
for _, e := range events {
if !c.Config.AllowFlood {
@@ -573,9 +565,14 @@ func (c *Client) sendLoop(ctx context.Context) error {
}
}
-// ErrTimedOut is returned when we attempt to ping the server, and timed out
+// ErrTimedOut is aliased to TimedOutError.
+//
+// Deprecated: use TimedOutError instead.
+type ErrTimedOut = TimedOutError //nolint:errname
+
+// TimedOutError is returned when we attempt to ping the server, and timed out
// before receiving a PONG back.
-type ErrTimedOut struct {
+type TimedOutError struct {
// TimeSinceSuccess is how long ago we received a successful pong.
TimeSinceSuccess time.Duration
// LastPong is the time we received our last successful pong.
@@ -586,7 +583,7 @@ type ErrTimedOut struct {
Delay time.Duration
}
-func (ErrTimedOut) Error() string { return "timed out waiting for a requested PING response" }
+func (TimedOutError) Error() string { return "timed out waiting for a requested PING response" }
func (c *Client) pingLoop(ctx context.Context) error {
// Don't run the pingLoop if they want to disable it.
@@ -641,7 +638,7 @@ func (c *Client) pingLoop(ctx context.Context) error {
c.conn.lastPing = time.Now()
c.conn.mu.Unlock()
- c.Cmd.Ping(fmt.Sprintf("%d", time.Now().UnixNano()))
+ c.Cmd.Ping(strconv.FormatInt(time.Now().UnixNano(), 10))
pingSent = true
case <-ctx.Done():
return nil
diff --git a/vendor/github.com/lrstanley/girc/ctcp.go b/vendor/github.com/lrstanley/girc/ctcp.go
index 9e35d69..8e75610 100644
--- a/vendor/github.com/lrstanley/girc/ctcp.go
+++ b/vendor/github.com/lrstanley/girc/ctcp.go
@@ -110,7 +110,7 @@ func EncodeCTCPRaw(cmd, text string) (out string) {
out = string(ctcpDelim) + cmd
- if len(text) > 0 {
+ if text != "" {
out += string(eventSpace) + text
}
diff --git a/vendor/github.com/lrstanley/girc/event.go b/vendor/github.com/lrstanley/girc/event.go
index 2622f89..7e3b708 100644
--- a/vendor/github.com/lrstanley/girc/event.go
+++ b/vendor/github.com/lrstanley/girc/event.go
@@ -331,7 +331,7 @@ func (e *Event) Len() (length int) {
// supports), which may be useful if you are trying to check and see if a message is
// too long, to trim it down yourself.
func (e *Event) LenOpts(includeTags bool) (length int) {
- if e.Tags != nil {
+ if e.Tags != nil && includeTags {
// Include tags and trailing space.
length = e.Tags.Len() + 1
}
@@ -357,7 +357,7 @@ func (e *Event) LenOpts(includeTags bool) (length int) {
}
}
- return
+ return length
}
// Bytes returns a []byte representation of event. Strips all newlines and
@@ -367,7 +367,7 @@ func (e *Event) Bytes() []byte {
// Tags.
if e.Tags != nil {
- e.Tags.writeTo(buffer)
+ _, _ = e.Tags.writeTo(buffer)
}
// Event prefix.
@@ -416,7 +416,7 @@ func (e *Event) String() string {
// support prettification, ok is false. Pretty is not just useful to make
// an event prettier, but also to filter out events that most don't visually
// see in normal IRC clients. e.g. most clients don't show WHO queries.
-func (e *Event) Pretty() (out string, ok bool) {
+func (e *Event) Pretty() (out string, ok bool) { //nolint:gocognit
if e.Sensitive || e.Echo {
return "", false
}
@@ -448,7 +448,7 @@ func (e *Event) Pretty() (out string, ok bool) {
if (e.Command == PRIVMSG || e.Command == NOTICE) && len(e.Params) > 0 {
if ctcp := DecodeCTCP(e); ctcp != nil {
if ctcp.Reply {
- return
+ return out, ok
}
if ctcp.Command == CTCP_ACTION {
@@ -678,14 +678,14 @@ func ParseSource(raw string) (src *Source) {
// Len calculates the length of the string representation of prefix
func (s *Source) Len() (length int) {
length = len(s.Name)
- if len(s.Ident) > 0 {
+ if s.Ident != "" {
length = 1 + length + len(s.Ident)
}
- if len(s.Host) > 0 {
+ if s.Host != "" {
length = 1 + length + len(s.Host)
}
- return
+ return length
}
// Bytes returns a []byte representation of source.
@@ -699,19 +699,19 @@ func (s *Source) Bytes() []byte {
// String returns a string representation of source.
func (s *Source) String() (out string) {
out = s.Name
- if len(s.Ident) > 0 {
+ if s.Ident != "" {
out = out + string(prefixIdent) + s.Ident
}
- if len(s.Host) > 0 {
+ if s.Host != "" {
out = out + string(prefixHost) + s.Host
}
- return
+ return out
}
// IsHostmask returns true if source looks like a user hostmask.
func (s *Source) IsHostmask() bool {
- return len(s.Ident) > 0 && len(s.Host) > 0
+ return s.Ident != "" && s.Host != ""
}
// IsServer returns true if this source looks like a server name.
@@ -723,11 +723,11 @@ func (s *Source) IsServer() bool {
// in Event.String().
func (s *Source) writeTo(buffer *bytes.Buffer) {
buffer.WriteString(s.Name)
- if len(s.Ident) > 0 {
+ if s.Ident != "" {
buffer.WriteByte(prefixIdent)
buffer.WriteString(s.Ident)
}
- if len(s.Host) > 0 {
+ if s.Host != "" {
buffer.WriteByte(prefixHost)
buffer.WriteString(s.Host)
}
diff --git a/vendor/github.com/lrstanley/girc/format.go b/vendor/github.com/lrstanley/girc/format.go
index 3b9d60a..26dac2a 100644
--- a/vendor/github.com/lrstanley/girc/format.go
+++ b/vendor/github.com/lrstanley/girc/format.go
@@ -83,7 +83,7 @@ func Fmt(text string) string {
continue
}
- if text[i] == fmtCloseChar && last > -1 {
+ if text[i] == fmtCloseChar && last > -1 { //nolint:nestif
code := strings.ToLower(text[last+1 : i])
// Check to see if they're passing in a second (background) color
@@ -381,7 +381,7 @@ func sliceInsert(input []string, i int, v ...string) []string {
// that are above maxWordSplitLength characters, split the word into chunks to fit the
//
// maximum width.
-func splitMessage(input string, maxWidth int) (output []string) {
+func splitMessage(input string, maxWidth int) (output []string) { //nolint:gocognit
input = strings.ToValidUTF8(input, "?")
words := strings.FieldsFunc(strings.TrimSpace(input), func(r rune) bool {
diff --git a/vendor/github.com/lrstanley/girc/handler.go b/vendor/github.com/lrstanley/girc/handler.go
index 55fd4e9..ca1b921 100644
--- a/vendor/github.com/lrstanley/girc/handler.go
+++ b/vendor/github.com/lrstanley/girc/handler.go
@@ -6,8 +6,8 @@ package girc
import (
"fmt"
- "log"
- "math/rand"
+ "log" //nolint:depguard // min go version we support doesn't support slog.
+ "math/rand" //nolint:depguard // min go version we support doesn't support v2.
"runtime"
"runtime/debug"
"strings"
@@ -145,7 +145,7 @@ func (c *Caller) cuid(cmd string, n int) (cuid, uid string) {
b := make([]byte, n)
for i := range b {
- b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))]
+ b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))] //nolint:gosec // not used for cryptographic purposes.
}
return cmd + ":" + string(b), string(b)
@@ -264,9 +264,7 @@ func (c *Caller) Clear(cmd string) {
cmd = strings.ToUpper(cmd)
c.mu.Lock()
- if _, ok := c.external[cmd]; ok {
- delete(c.external, cmd)
- }
+ delete(c.external, cmd)
c.mu.Unlock()
c.debug.Printf("cleared external handlers for %s", cmd)
@@ -496,8 +494,8 @@ func (e *HandlerError) String() string {
// debug log (see Config.Debug), or os.Stdout if Config.Debug is unset.
func DefaultRecoverHandler(client *Client, err *HandlerError) {
if client.Config.Debug == nil {
- fmt.Println(err.Error())
- fmt.Println(err.String())
+ fmt.Println(err.Error()) //nolint:forbidigo
+ fmt.Println(err.String()) //nolint:forbidigo
return
}
diff --git a/vendor/github.com/lrstanley/girc/modes.go b/vendor/github.com/lrstanley/girc/modes.go
index 127b0a7..b879526 100644
--- a/vendor/github.com/lrstanley/girc/modes.go
+++ b/vendor/github.com/lrstanley/girc/modes.go
@@ -56,15 +56,12 @@ type CModes struct {
// Copy returns a deep copy of CModes.
func (c *CModes) Copy() (nc CModes) {
- nc = CModes{}
nc = *c
nc.modes = make([]CMode, len(c.modes))
// Copy modes.
- for i := 0; i < len(c.modes); i++ {
- nc.modes[i] = c.modes[i]
- }
+ copy(nc.modes, c.modes)
return nc
}
@@ -72,8 +69,7 @@ func (c *CModes) Copy() (nc CModes) {
// String returns a complete set of modes for this given state (change?). For
// example, "+a-b+cde some-arg".
func (c *CModes) String() string {
- var out string
- var args string
+ var out, args string
if len(c.modes) > 0 {
out += "+"
@@ -82,7 +78,7 @@ func (c *CModes) String() string {
for i := 0; i < len(c.modes); i++ {
out += string(c.modes[i].name)
- if len(c.modes[i].args) > 0 {
+ if c.modes[i].args != "" {
args += " " + c.modes[i].args
}
}
@@ -445,7 +441,7 @@ func (p *UserPerms) remove(channel string) {
// Perms contains all channel-based user permissions. The minimum op, and
// voice should be supported on all networks. This also supports non-rfc
// Owner, Admin, and HalfOp, if the network has support for it.
-type Perms struct {
+type Perms struct { //nolint:recvcheck
// Owner (non-rfc) indicates that the user has full permissions to the
// channel. More than one user can have owner permission.
Owner bool `json:"owner"`
@@ -547,5 +543,5 @@ func parseUserPrefix(raw string) (modes, nick string, success bool) {
return modes, raw[i:], true
}
- return
+ return modes, nick, success
}
diff --git a/vendor/github.com/lrstanley/girc/state.go b/vendor/github.com/lrstanley/girc/state.go
index 96d2ef8..a1373bf 100644
--- a/vendor/github.com/lrstanley/girc/state.go
+++ b/vendor/github.com/lrstanley/girc/state.go
@@ -130,7 +130,7 @@ type User struct {
// Channels returns a reference of *Channels that the client knows the user
// is in. If you're just looking for the namme of the channels, use
// User.ChannelList.
-func (u User) Channels(c *Client) []*Channel {
+func (u *User) Channels(c *Client) []*Channel {
if c == nil {
panic("nil Client provided")
}
@@ -244,7 +244,7 @@ type Channel struct {
// Users returns a reference of *Users that the client knows the channel has
// If you're just looking for just the name of the users, use Channnel.UserList.
-func (ch Channel) Users(c *Client) []*User {
+func (ch *Channel) Users(c *Client) []*User {
if c == nil {
panic("nil Client provided")
}
@@ -265,7 +265,7 @@ func (ch Channel) Users(c *Client) []*User {
// Trusted returns a list of users which have voice or greater in the given
// channel. See Perms.IsTrusted() for more information.
-func (ch Channel) Trusted(c *Client) []*User {
+func (ch *Channel) Trusted(c *Client) []*User {
if c == nil {
panic("nil Client provided")
}
@@ -292,7 +292,7 @@ func (ch Channel) Trusted(c *Client) []*User {
// Admins returns a list of users which have half-op (if supported), or
// greater permissions (op, admin, owner, etc) in the given channel. See
// Perms.IsAdmin() for more information.
-func (ch Channel) Admins(c *Client) []*User {
+func (ch *Channel) Admins(c *Client) []*User {
if c == nil {
panic("nil Client provided")
}
@@ -389,7 +389,7 @@ func (s *state) createChannel(name string) (ok bool) {
supported := s.chanModes()
prefixes, _ := parsePrefixes(s.userPrefixes())
- if _, ok := s.channels[ToRFC1459(name)]; ok {
+ if _, sok := s.channels[ToRFC1459(name)]; sok {
return false
}
@@ -440,7 +440,7 @@ func (s *state) lookupUser(name string) *User {
// createUser creates the user in state, if not already done.
func (s *state) createUser(src *Source) (ok bool) {
- if _, ok := s.users[src.ID()]; ok {
+ if _, sok := s.users[src.ID()]; sok {
// User already exists.
return false
}
@@ -544,15 +544,20 @@ func (s *strictTransport) enabled() bool {
return s.upgradePort > 0
}
-// ErrSTSUpgradeFailed is an error that occurs when a connection that was attempted
+// ErrSTSUpgradeFailed is an alias to STSUpgradeError.
+//
+// Deprecated: use STSUpgradeError instead.
+type ErrSTSUpgradeFailed = STSUpgradeError //nolint:errname
+
+// STSUpgradeError is an error that occurs when a connection that was attempted
// to be upgraded via a strict transport policy, failed. This does not necessarily
// indicate that STS was to blame, but the underlying connection failed for some
// reason.
-type ErrSTSUpgradeFailed struct {
+type STSUpgradeError struct {
Err error
}
-func (e ErrSTSUpgradeFailed) Error() string {
+func (e STSUpgradeError) Error() string {
return fmt.Sprintf("fail to upgrade to secure (sts) connection: %v", e.Err)
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c92e2a7..f7b0a78 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -2,7 +2,7 @@
## explicit; go 1.18
github.com/BurntSushi/toml
github.com/BurntSushi/toml/internal
-# github.com/lrstanley/girc v0.0.0-20240914071631-5c0cc76257bf
+# github.com/lrstanley/girc v1.1.1
## explicit; go 1.18
github.com/lrstanley/girc
github.com/lrstanley/girc/internal/ctxgroup