Files
Tobias GesellchenandClaude Sonnet 4.6 2722e2383c fix(lint): sec6/sec7 post-pass — static.go Close + remove unused sanitizeErr
- stockholm/static.go: wrap deferred root.Close() in func(){}() to
  silence errcheck; change 'rel = rel + ...' to 'rel += ...' (gocritic).

- Remove sanitizeErr from four logutil files where no call site exists
  (cmd/soundtouch-cli, cmd/websocket-demo, pkg/discovery, pkg/service/setup).
  The log-injection fixes in those packages used sanitizeLog on string
  arguments rather than sanitizeErr on error values.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 11:28:26 +02:00

64 lines
2.0 KiB
Go

package discovery
import (
"log"
"net"
"strings"
"sync/atomic"
)
// verboseLogging toggles the per-packet / per-header diagnostic output
// that was historically emitted unconditionally during UPnP and mDNS
// discovery. The service binary leaves it at its zero value (off) so
// the log stays useful at info-level; the CLI's `discover` command
// flips it on so interactive runs surface full protocol details.
//
// Stored as an int32 so the read path in logVerbose is allocation-
// free (atomic.Bool would work too on Go 1.19+, but a uint8 lookup
// keeps the toggle hot-path even on older toolchains we still build
// against in CI).
var verboseLogging atomic.Bool
// SetVerbose enables (or disables) the package-wide verbose-discovery
// log toggle. Safe to call from any goroutine.
func SetVerbose(v bool) {
verboseLogging.Store(v)
}
// IsVerbose reports the current value of the verbose toggle. Mainly
// for tests that want to assert the CLI flipped it on.
func IsVerbose() bool {
return verboseLogging.Load()
}
// logVerbose forwards to log.Printf only when verbose-discovery
// logging is enabled. The fast path (verbose off) is a single
// atomic load + branch, so it's safe to scatter calls liberally
// across the hot path.
func logVerbose(format string, args ...any) {
if verboseLogging.Load() {
log.Printf(format, args...)
}
}
// sanitizeLog strips newline characters from s to prevent log-injection
// (CodeQL go/log-injection). Values from speakers, HTTP requests, and
// external APIs may contain attacker-controlled newlines.
func sanitizeLog(s string) string {
s = strings.ReplaceAll(s, "\n", `\n`)
s = strings.ReplaceAll(s, "\r", `\r`)
return s
}
// remoteAddrString safely converts a net.Addr to a string, returning
// an empty string when addr is nil (dns.ResponseWriter.RemoteAddr may
// return nil in unit-test contexts).
func remoteAddrString(w interface{ RemoteAddr() net.Addr }) string {
if ra := w.RemoteAddr(); ra != nil {
return ra.String()
}
return ""
}