in common/buildlogger/internal/urlsanitizer/urlsanitizer.go [53:152]
func (s *URLSanitizer) Write(p []byte) (n int, err error) {
var last int
for n < len(p) {
// if we're in masking mode, we throw away all bytes until we find
// the end of the parameter we're masking.
if s.masking {
off := bytes.IndexFunc(p[n:], isParamEnd)
if off == -1 {
// no end found, so skip these bytes
n += len(p[n:])
last = n
break
} else {
// end found, so skip the bytes up until the match and write
// [MASKED] in their place.
n += off
last += off
s.masking = false
_, err = s.w.Write(mask)
if err != nil {
return n, err
}
}
}
// if our match is at capacity (maximum token size), reset it and
// continue looking for the next token.
if len(s.match) == cap(s.match) {
s.match = s.match[:0]
}
// fast path: if we're not matching any parameters, skip towards ? or &
// if none found, we can bail early
if len(s.match) == 0 {
off := bytes.IndexAny(p[n:], "?&")
if off == -1 {
n += len(p[n:])
break
} else {
s.match = append(s.match, p[n+off])
n += off + 1
}
}
// all of p consumed, so break
if n >= len(p) {
break
}
// find any of key name
off := bytes.IndexAny(p[n:], "=?&")
// if not found, continue adding to key match
if off == -1 {
s.match = append(s.match, p[n])
n++
continue
}
// bail early if the key contains another param separator
if p[n+off] == '?' || p[n+off] == '&' {
s.match = s.match[:0]
n += off
continue
}
// bail early if key would exceed our known key sizes
if off+len(s.match) > cap(s.match) {
s.match = s.match[:0]
n++
continue
}
key := append(s.match, p[n:n+off]...) //nolint:gocritic
n += off + 1
// check if the key is one supported, and if so, write data until this
// point and move to masking mode
if _, ok := tokenParamKeys[strings.ToLower(string(key[1:]))]; ok {
_, err = s.w.Write(p[last:n])
if err != nil {
return n, err
}
last = n
s.masking = true
}
// reset match
s.match = s.match[:0]
}
if len(p[last:n]) > 0 {
_, err = s.w.Write(p[last:n])
}
return n, err
}