mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-16 03:31:39 +00:00
ipn/ipnlocal: simplify redactErr (#6716)
Use multierr.Range to iterate through an error tree instead of multiple invocations of errors.As. This scales better as we add more Go error types to the switch. Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
parent
c47578b528
commit
bd2995c14b
@ -48,6 +48,7 @@ import (
|
|||||||
"tailscale.com/net/netutil"
|
"tailscale.com/net/netutil"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/util/clientmetric"
|
"tailscale.com/util/clientmetric"
|
||||||
|
"tailscale.com/util/multierr"
|
||||||
"tailscale.com/util/strs"
|
"tailscale.com/util/strs"
|
||||||
"tailscale.com/wgengine"
|
"tailscale.com/wgengine"
|
||||||
"tailscale.com/wgengine/filter"
|
"tailscale.com/wgengine/filter"
|
||||||
@ -365,58 +366,45 @@ func redactString(s string) string {
|
|||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func redactErr(err error) error {
|
func redactErr(root error) error {
|
||||||
|
// redactStrings is a list of sensitive strings that were redacted.
|
||||||
|
// It is not sufficient to just snub out sensitive fields in Go errors
|
||||||
|
// since some wrapper errors like fmt.Errorf pre-cache the error string,
|
||||||
|
// which would unfortunately remain unaffected.
|
||||||
var redactStrings []string
|
var redactStrings []string
|
||||||
|
|
||||||
var pe *os.PathError
|
// Redact sensitive fields in known Go error types.
|
||||||
if errors.As(err, &pe) {
|
var unknownErrors int
|
||||||
// If this is the root error, then we can redact it directly.
|
multierr.Range(root, func(err error) bool {
|
||||||
if err == pe {
|
switch err := err.(type) {
|
||||||
pe.Path = redactString(pe.Path)
|
case *os.PathError:
|
||||||
return pe
|
redactStrings = append(redactStrings, err.Path)
|
||||||
|
err.Path = redactString(err.Path)
|
||||||
|
case *os.LinkError:
|
||||||
|
redactStrings = append(redactStrings, err.New, err.Old)
|
||||||
|
err.New = redactString(err.New)
|
||||||
|
err.Old = redactString(err.Old)
|
||||||
|
default:
|
||||||
|
unknownErrors++
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
// Otherwise, we have a *PathError somewhere in the error
|
// If there are no redacted strings or no unknown error types,
|
||||||
// chain, and we can't redact it because something later in the
|
// then we can return the possibly modified root error verbatim.
|
||||||
// chain may have cached the Error() return already (as
|
// Otherwise, we must replace redacted strings from any wrappers.
|
||||||
// fmt.Errorf does).
|
if len(redactStrings) == 0 || unknownErrors == 0 {
|
||||||
//
|
return root
|
||||||
// Add this path to the set of paths that we will redact, below.
|
|
||||||
redactStrings = append(redactStrings, pe.Path)
|
|
||||||
|
|
||||||
// Also redact the Path value so that anything that calls
|
|
||||||
// Unwrap in the future gets the redacted value.
|
|
||||||
pe.Path = redactString(pe.Path)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var le *os.LinkError
|
// Stringify and replace any paths that we found above, then return
|
||||||
if errors.As(err, &le) {
|
|
||||||
// If this is the root error, then we can redact it directly.
|
|
||||||
if err == le {
|
|
||||||
le.New = redactString(le.New)
|
|
||||||
le.Old = redactString(le.Old)
|
|
||||||
return le
|
|
||||||
}
|
|
||||||
|
|
||||||
// As above
|
|
||||||
redactStrings = append(redactStrings, le.New, le.Old)
|
|
||||||
le.New = redactString(le.New)
|
|
||||||
le.Old = redactString(le.Old)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(redactStrings) == 0 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
s := err.Error()
|
|
||||||
for _, toRedact := range redactStrings {
|
|
||||||
s = strings.Replace(s, toRedact, redactString(toRedact), -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stringify and and replace any paths that we found above, then return
|
|
||||||
// the error wrapped in a type that uses the newly-redacted string
|
// the error wrapped in a type that uses the newly-redacted string
|
||||||
// while also allowing Unwrap()-ing to the inner error type(s).
|
// while also allowing Unwrap()-ing to the inner error type(s).
|
||||||
return &redactedErr{msg: s, inner: err}
|
s := root.Error()
|
||||||
|
for _, toRedact := range redactStrings {
|
||||||
|
s = strings.ReplaceAll(s, toRedact, redactString(toRedact))
|
||||||
|
}
|
||||||
|
return &redactedErr{msg: s, inner: root}
|
||||||
}
|
}
|
||||||
|
|
||||||
func touchFile(path string) error {
|
func touchFile(path string) error {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user