Upgrade versions of vendored libs
This commit is contained in:
333
vendor/github.com/cockroachdb/redact/internal/buffer/buffer.go
generated
vendored
Normal file
333
vendor/github.com/cockroachdb/redact/internal/buffer/buffer.go
generated
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
// Copyright 2021 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package buffer
|
||||
|
||||
import (
|
||||
origFmt "fmt"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
|
||||
"github.com/cockroachdb/redact/internal/escape"
|
||||
m "github.com/cockroachdb/redact/internal/markers"
|
||||
)
|
||||
|
||||
// Buffer is a variable-sized buffer of bytes with a
|
||||
// Write method. Writes are escaped in different ways
|
||||
// depending on the output mode.
|
||||
type Buffer struct {
|
||||
buf []byte
|
||||
validUntil int // exclusive upper bound of data that's already validated
|
||||
mode OutputMode
|
||||
markerOpen bool
|
||||
}
|
||||
|
||||
// OutputMode determines how writes are processed in the Buffer.
|
||||
type OutputMode int
|
||||
|
||||
const (
|
||||
// UnsafeEscaped says that written data is unsafe for reporting,
|
||||
// so it should be enclosed in redaction markers,
|
||||
// and may contain redaction markers itself, and so it should be escaped.
|
||||
UnsafeEscaped OutputMode = iota
|
||||
// SafeEscaped says that written data is safe for reporting
|
||||
// (should not be enclosed in redaction markers) but may itself
|
||||
// contain redaction markers, and so it should be escaped.
|
||||
SafeEscaped
|
||||
// SafeRaw says that written data is safe for reporting
|
||||
// (should not be enclosed in redaction markers) and is
|
||||
// guaranteed not to contain redaction markers, so it
|
||||
// needs not be escaped.
|
||||
SafeRaw
|
||||
// PreRedactable says that written data already contains a mixed
|
||||
// of safe and unsafe information with suitably placed redaction markers,
|
||||
// and so should be inlined.
|
||||
PreRedactable = SafeRaw
|
||||
)
|
||||
|
||||
// RedactableBytes returns the bytes in the buffer.
|
||||
func (b Buffer) RedactableBytes() m.RedactableBytes {
|
||||
// NB: we're dependent on the fact this is a copy of the original
|
||||
// buffer. The finalize() method should not be called
|
||||
// in a conceputally read-only accessor like RedactableBytes().
|
||||
b.finalize()
|
||||
return m.RedactableBytes(b.buf)
|
||||
}
|
||||
|
||||
// RedactableString returns the bytes in the buffer.
|
||||
func (b Buffer) RedactableString() m.RedactableString {
|
||||
// NB: we're dependent on the fact this is a copy of the original
|
||||
// buffer. The finalize() method should not be called
|
||||
// in a conceputally read-only accessor like RedactableString().
|
||||
b.finalize()
|
||||
return m.RedactableString(b.buf)
|
||||
}
|
||||
|
||||
// String implemens fmt.Stringer.
|
||||
func (b Buffer) String() string {
|
||||
// NB: we're dependent on the fact this is a copy of the original
|
||||
// buffer. The finalize() method should not be called
|
||||
// in a conceputally read-only accessor like String().
|
||||
b.finalize()
|
||||
return m.RedactableString(b.buf).StripMarkers()
|
||||
}
|
||||
|
||||
// TakeRedactableBytes returns the buffer
|
||||
// contents and reinitializes the buffer. This saves
|
||||
// a memory allocation compared to RedactableBytes().
|
||||
func (b *Buffer) TakeRedactableBytes() m.RedactableBytes {
|
||||
b.finalize()
|
||||
r := b.buf
|
||||
b.buf = nil
|
||||
b.validUntil = 0
|
||||
b.mode = UnsafeEscaped
|
||||
return m.RedactableBytes(r)
|
||||
}
|
||||
|
||||
// TakeRedactableString returns the buffer
|
||||
// contents and reinitializes the buffer. This saves
|
||||
// a memory allocation compared to RedactableString().
|
||||
func (b *Buffer) TakeRedactableString() m.RedactableString {
|
||||
if b == nil {
|
||||
// Special case, useful in debugging.
|
||||
return "<nil>"
|
||||
}
|
||||
b.finalize()
|
||||
r := *(*m.RedactableString)(unsafe.Pointer(&b.buf))
|
||||
b.buf = nil
|
||||
b.validUntil = 0
|
||||
b.mode = UnsafeEscaped
|
||||
return r
|
||||
}
|
||||
|
||||
// Len returns the number of bytes in the buffer.
|
||||
func (b *Buffer) Len() int {
|
||||
copy := *b
|
||||
copy.finalize()
|
||||
return len(copy.buf)
|
||||
}
|
||||
|
||||
// Cap returns the capacity of the buffer's underlying byte slice,
|
||||
// that is, the total space allocated for the buffer's data.
|
||||
func (b *Buffer) Cap() int {
|
||||
return cap(b.buf)
|
||||
}
|
||||
|
||||
// Write appends the contents of p to the buffer, growing the buffer as
|
||||
// needed. The return value n is the length of p; err is always nil. If the
|
||||
// buffer becomes too large, Write will panic with ErrTooLarge.
|
||||
func (b *Buffer) Write(p []byte) (n int, err error) {
|
||||
b.startWrite()
|
||||
m, ok := b.tryGrowByReslice(len(p))
|
||||
if !ok {
|
||||
m = b.grow(len(p))
|
||||
}
|
||||
return copy(b.buf[m:], p), nil
|
||||
}
|
||||
|
||||
// WriteString appends the contents of s to the buffer, growing the buffer as
|
||||
// needed. The return value n is the length of s; err is always nil. If the
|
||||
// buffer becomes too large, WriteString will panic with ErrTooLarge.
|
||||
func (b *Buffer) WriteString(s string) (n int, err error) {
|
||||
b.startWrite()
|
||||
m, ok := b.tryGrowByReslice(len(s))
|
||||
if !ok {
|
||||
m = b.grow(len(s))
|
||||
}
|
||||
return copy(b.buf[m:], s), nil
|
||||
}
|
||||
|
||||
// WriteByte emits a single byte.
|
||||
func (b *Buffer) WriteByte(s byte) error {
|
||||
b.startWrite()
|
||||
if b.mode == UnsafeEscaped &&
|
||||
(s >= utf8.RuneSelf ||
|
||||
s == m.StartS[0] || s == m.EndS[0]) {
|
||||
// Unsafe byte. Escape it.
|
||||
_, err := b.WriteString(m.EscapeMarkS)
|
||||
return err
|
||||
}
|
||||
m, ok := b.tryGrowByReslice(1)
|
||||
if !ok {
|
||||
m = b.grow(1)
|
||||
}
|
||||
b.buf[m] = s
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteRune emits a single rune.
|
||||
func (b *Buffer) WriteRune(s rune) error {
|
||||
b.startWrite()
|
||||
l := utf8.RuneLen(s)
|
||||
m, ok := b.tryGrowByReslice(l)
|
||||
if !ok {
|
||||
m = b.grow(l)
|
||||
}
|
||||
_ = utf8.EncodeRune(b.buf[m:], s)
|
||||
return nil
|
||||
}
|
||||
|
||||
// finalize ensures that all the buffer is properly
|
||||
// marked.
|
||||
func (b *Buffer) finalize() {
|
||||
if b.mode == SafeRaw {
|
||||
b.validUntil = len(b.buf)
|
||||
} else {
|
||||
b.escapeToEnd(b.mode == UnsafeEscaped /* breakNewLines */)
|
||||
}
|
||||
if b.markerOpen {
|
||||
b.endRedactable()
|
||||
b.validUntil = len(b.buf)
|
||||
}
|
||||
}
|
||||
|
||||
// endRedactable adds the closing redaction marker.
|
||||
func (b *Buffer) endRedactable() {
|
||||
if len(b.buf) == 0 {
|
||||
return
|
||||
}
|
||||
p, ok := b.tryGrowByReslice(len(m.EndS))
|
||||
if !ok {
|
||||
p = b.grow(len(m.EndS))
|
||||
}
|
||||
copy(b.buf[p:], m.EndS)
|
||||
b.markerOpen = false
|
||||
}
|
||||
|
||||
func (b *Buffer) startWrite() {
|
||||
if b.mode == UnsafeEscaped && !b.markerOpen {
|
||||
b.startRedactable()
|
||||
b.validUntil = len(b.buf)
|
||||
}
|
||||
}
|
||||
|
||||
// endRedactable adds the closing redaction marker.
|
||||
func (b *Buffer) startRedactable() {
|
||||
p, ok := b.tryGrowByReslice(len(m.StartS))
|
||||
if !ok {
|
||||
p = b.grow(len(m.StartS))
|
||||
}
|
||||
copy(b.buf[p:], m.StartS)
|
||||
b.markerOpen = true
|
||||
}
|
||||
|
||||
// escapeToEnd escapes occurrences of redaction markers in
|
||||
// b.buf[b.validUntil:] and advances b.validUntil until the end.
|
||||
func (b *Buffer) escapeToEnd(breakNewLines bool) {
|
||||
b.buf = escape.InternalEscapeBytes(b.buf, b.validUntil, breakNewLines, breakNewLines)
|
||||
b.validUntil = len(b.buf)
|
||||
}
|
||||
|
||||
// GetMode retrieves the output mode.
|
||||
func (b *Buffer) GetMode() OutputMode {
|
||||
return b.mode
|
||||
}
|
||||
|
||||
// SetMode changes the output mode.
|
||||
func (b *Buffer) SetMode(newMode OutputMode) {
|
||||
if b.mode == newMode {
|
||||
// noop
|
||||
return
|
||||
}
|
||||
if b.mode == UnsafeEscaped || b.mode == SafeEscaped {
|
||||
b.escapeToEnd(b.mode == UnsafeEscaped /* breakNewLines */)
|
||||
}
|
||||
if b.markerOpen {
|
||||
b.endRedactable()
|
||||
}
|
||||
b.validUntil = len(b.buf)
|
||||
b.mode = newMode
|
||||
}
|
||||
|
||||
// Reset resets the buffer to be empty,
|
||||
// but it retains the underlying storage for use by future writes.
|
||||
// It also resets the output mode to UnsafeEscaped.
|
||||
func (b *Buffer) Reset() {
|
||||
b.buf = b.buf[:0]
|
||||
b.validUntil = 0
|
||||
b.mode = UnsafeEscaped
|
||||
b.markerOpen = false
|
||||
}
|
||||
|
||||
// tryGrowByReslice is a inlineable version of grow for the fast-case where the
|
||||
// internal buffer only needs to be resliced.
|
||||
// It returns the index where bytes should be written and whether it succeeded.
|
||||
func (b *Buffer) tryGrowByReslice(n int) (int, bool) {
|
||||
if l := len(b.buf); n <= cap(b.buf)-l {
|
||||
b.buf = b.buf[:l+n]
|
||||
return l, true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// grow grows the buffer to guarantee space for n more bytes.
|
||||
// It returns the index where bytes should be written.
|
||||
// If the buffer can't grow it will panic with ErrTooLarge.
|
||||
func (b *Buffer) grow(n int) int {
|
||||
m := len(b.buf)
|
||||
// Try to grow by means of a reslice.
|
||||
if i, ok := b.tryGrowByReslice(n); ok {
|
||||
return i
|
||||
}
|
||||
if b.buf == nil && n <= smallBufferSize {
|
||||
b.buf = make([]byte, n, smallBufferSize)
|
||||
return 0
|
||||
}
|
||||
c := cap(b.buf)
|
||||
const maxInt = int(^uint(0) >> 1)
|
||||
if n <= c/2-m {
|
||||
// let capacity get twice as large.
|
||||
} else if c > maxInt-c-n {
|
||||
panic(ErrTooLarge)
|
||||
} else {
|
||||
// Not enough space anywhere, we need to allocate.
|
||||
buf := makeSlice(2*c + n)
|
||||
copy(buf, b.buf)
|
||||
b.buf = buf
|
||||
}
|
||||
b.buf = b.buf[:m+n]
|
||||
return m
|
||||
}
|
||||
|
||||
// Grow grows the buffer's capacity, if necessary, to guarantee space for
|
||||
// another n bytes. After Grow(n), at least n bytes can be written to the
|
||||
// buffer without another allocation.
|
||||
// If n is negative, Grow will panic.
|
||||
// If the buffer can't grow it will panic with ErrTooLarge.
|
||||
func (b *Buffer) Grow(n int) {
|
||||
if n < 0 {
|
||||
panic(origFmt.Errorf("redact.Buffer.Grow: negative count"))
|
||||
}
|
||||
m := b.grow(n)
|
||||
b.buf = b.buf[:m]
|
||||
}
|
||||
|
||||
// makeSlice allocates a slice of size n. If the allocation fails, it panics
|
||||
// with ErrTooLarge.
|
||||
func makeSlice(n int) []byte {
|
||||
// If the make fails, give a known error.
|
||||
defer func() {
|
||||
if recover() != nil {
|
||||
panic(ErrTooLarge)
|
||||
}
|
||||
}()
|
||||
return make([]byte, n)
|
||||
}
|
||||
|
||||
// ErrTooLarge is passed to panic if memory cannot be allocated to
|
||||
// store data in a buffer.
|
||||
var ErrTooLarge = origFmt.Errorf("redact.Buffer: too large")
|
||||
|
||||
// smallBufferSize is an initial allocation minimal capacity.
|
||||
const smallBufferSize = 64
|
||||
129
vendor/github.com/cockroachdb/redact/internal/escape/escape.go
generated
vendored
Normal file
129
vendor/github.com/cockroachdb/redact/internal/escape/escape.go
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright 2020 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package escape
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"unicode/utf8"
|
||||
|
||||
m "github.com/cockroachdb/redact/internal/markers"
|
||||
)
|
||||
|
||||
// InternalEscapeBytes escapes redaction markers in the provided buf
|
||||
// starting at the location startLoc.
|
||||
// The bytes before startLoc are considered safe (already escaped).
|
||||
//
|
||||
// If breakNewLines is set, a closing redaction marker
|
||||
// is placed before sequences of one or more newline characters,
|
||||
// and an open redaction marker is placed afterwards.
|
||||
func InternalEscapeBytes(b []byte, startLoc int, breakNewLines, strip bool) (res []byte) {
|
||||
// Note: we use len(...RedactableS) and not len(...RedactableBytes)
|
||||
// because the ...S variant is a compile-time constant so this
|
||||
// accelerates the loops below.
|
||||
start, ls := m.StartBytes, len(m.StartS)
|
||||
end, le := m.EndBytes, len(m.EndS)
|
||||
escape := m.EscapeMarkBytes
|
||||
|
||||
// Trim final newlines/spaces, for convenience.
|
||||
if strip {
|
||||
end := len(b)
|
||||
for i := end - 1; i >= startLoc; i-- {
|
||||
if b[i] == '\n' || b[i] == ' ' {
|
||||
end = i
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
b = b[:end]
|
||||
}
|
||||
|
||||
// res is the output slice. In the common case where there is
|
||||
// nothing to escape, the input slice is returned directly
|
||||
// and no allocation takes place.
|
||||
res = b
|
||||
// copied is true if and only if `res` is a copy of `b`. It only
|
||||
// turns to true if the loop below finds something to escape.
|
||||
copied := false
|
||||
// k is the index in b up to (and excluding) the byte which we've
|
||||
// already copied into res (if copied=true).
|
||||
k := 0
|
||||
|
||||
for i := startLoc; i < len(b); i++ {
|
||||
if breakNewLines && b[i] == '\n' {
|
||||
if !copied {
|
||||
// We only allocate an output slice when we know we definitely
|
||||
// need it.
|
||||
res = make([]byte, 0, len(b))
|
||||
copied = true
|
||||
}
|
||||
res = append(res, b[k:i]...)
|
||||
res = append(res, end...)
|
||||
// Advance to the last newline character. We want to forward
|
||||
// them all in a single call to doWrite, for performance.
|
||||
lastNewLine := i
|
||||
for lastNewLine < len(b) && b[lastNewLine] == '\n' {
|
||||
lastNewLine++
|
||||
}
|
||||
res = append(res, b[i:lastNewLine]...)
|
||||
res = append(res, start...)
|
||||
k = lastNewLine
|
||||
i = lastNewLine - 1
|
||||
} else
|
||||
// Ensure that occurrences of the delimiter inside the string get
|
||||
// escaped.
|
||||
// Reminder: ls and le are likely greater than 1, as we are scanning
|
||||
// utf-8 encoded delimiters (the utf-8 encoding is multibyte).
|
||||
if i+ls <= len(b) && bytes.Equal(b[i:i+ls], start) {
|
||||
if !copied {
|
||||
// We only allocate an output slice when we know we definitely
|
||||
// need it.
|
||||
res = make([]byte, 0, len(b)+len(escape))
|
||||
copied = true
|
||||
}
|
||||
res = append(res, b[k:i]...)
|
||||
res = append(res, escape...)
|
||||
// Advance the counters by the length (in bytes) of the delimiter.
|
||||
k = i + ls
|
||||
i += ls - 1 /* -1 because we have i++ at the end of every iteration */
|
||||
} else if i+le <= len(b) && bytes.Equal(b[i:i+le], end) {
|
||||
if !copied {
|
||||
// See the comment above about res allocation.
|
||||
res = make([]byte, 0, len(b)+len(escape))
|
||||
copied = true
|
||||
}
|
||||
res = append(res, b[k:i]...)
|
||||
res = append(res, escape...)
|
||||
// Advance the counters by the length (in bytes) of the delimiter.
|
||||
k = i + le
|
||||
i += le - 1 /* -1 because we have i++ at the end of every iteration */
|
||||
}
|
||||
}
|
||||
// If the string terminates with an invalid utf-8 sequence, we
|
||||
// want to avoid a run-in with a subsequent redaction marker.
|
||||
if r, s := utf8.DecodeLastRune(b); s == 1 && r == utf8.RuneError {
|
||||
if !copied {
|
||||
// See the comment above about res allocation.
|
||||
res = make([]byte, 0, len(b)+len(escape))
|
||||
copied = true
|
||||
}
|
||||
res = append(res, b[k:]...)
|
||||
res = append(res, escape...)
|
||||
k = len(b)
|
||||
}
|
||||
if copied {
|
||||
res = append(res, b[k:]...)
|
||||
}
|
||||
return
|
||||
}
|
||||
88
vendor/github.com/cockroachdb/redact/internal/fmtforward/make_format.go
generated
vendored
Normal file
88
vendor/github.com/cockroachdb/redact/internal/fmtforward/make_format.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2020 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package fmtforward
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ReproducePrintf calls fmt.Print/fmt.Printf on the argument
|
||||
// based on the details present in the fmt.State and
|
||||
// writes to the io.Writer.
|
||||
func ReproducePrintf(w io.Writer, s fmt.State, verb rune, arg interface{}) {
|
||||
justV, revFmt := MakeFormat(s, verb)
|
||||
if justV {
|
||||
// Common case, avoids generating then parsing the format again.
|
||||
fmt.Fprint(w, arg)
|
||||
} else {
|
||||
fmt.Fprintf(w, revFmt, arg)
|
||||
}
|
||||
}
|
||||
|
||||
// MakeFormat reproduces the format currently active
|
||||
// in fmt.State and verb. This is provided because Go's standard
|
||||
// fmt.State does not make the original format string available to us.
|
||||
//
|
||||
// If the return value justV is true, then the current state
|
||||
// was found to be %v exactly; in that case the caller
|
||||
// can avoid a full-blown Printf call and use just Print instead
|
||||
// to take a shortcut.
|
||||
func MakeFormat(s fmt.State, verb rune) (justV bool, format string) {
|
||||
plus, minus, hash, sp, z := s.Flag('+'), s.Flag('-'), s.Flag('#'), s.Flag(' '), s.Flag('0')
|
||||
w, wp := s.Width()
|
||||
p, pp := s.Precision()
|
||||
|
||||
if !plus && !minus && !hash && !sp && !z && !wp && !pp {
|
||||
switch verb {
|
||||
case 'v':
|
||||
return true, "%v"
|
||||
case 's':
|
||||
return false, "%s"
|
||||
case 'd':
|
||||
return false, "%d"
|
||||
}
|
||||
// Other cases handled in the slow path below.
|
||||
}
|
||||
|
||||
var f strings.Builder
|
||||
f.WriteByte('%')
|
||||
if plus {
|
||||
f.WriteByte('+')
|
||||
}
|
||||
if minus {
|
||||
f.WriteByte('-')
|
||||
}
|
||||
if hash {
|
||||
f.WriteByte('#')
|
||||
}
|
||||
if sp {
|
||||
f.WriteByte(' ')
|
||||
}
|
||||
if z {
|
||||
f.WriteByte('0')
|
||||
}
|
||||
if wp {
|
||||
f.WriteString(strconv.Itoa(w))
|
||||
}
|
||||
if pp {
|
||||
f.WriteByte('.')
|
||||
f.WriteString(strconv.Itoa(p))
|
||||
}
|
||||
f.WriteRune(verb)
|
||||
return false, f.String()
|
||||
}
|
||||
83
vendor/github.com/cockroachdb/redact/internal/hooks.go
generated
vendored
83
vendor/github.com/cockroachdb/redact/internal/hooks.go
generated
vendored
@@ -1,83 +0,0 @@
|
||||
// Copyright 2020 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package fmt
|
||||
|
||||
// printArg overrides the original implementation by redirecting the
|
||||
// call to a substitute function in the printer, if available.
|
||||
func (p *pp) printArg(a interface{}, verb rune) {
|
||||
if p.printArgSubstituteFn != nil {
|
||||
p.substituteState = p.printArgSubstituteFn(p, a, verb)
|
||||
} else {
|
||||
p.printArgOrig(a, verb)
|
||||
}
|
||||
}
|
||||
|
||||
// InternalPrinter exposes pp to the redact package.
|
||||
type InternalPrinter = pp
|
||||
|
||||
// InternalBuffer exposes buffer to the redact package.
|
||||
type InternalBuffer = buffer
|
||||
|
||||
// NewInternalPrinter exposes pp allocation to the redact package.
|
||||
func NewInternalPrinter() *InternalPrinter { return newPrinter() }
|
||||
|
||||
// SetHook connects an outer printer to the inner printer.
|
||||
func SetHook(
|
||||
p *InternalPrinter, fn func(p *InternalPrinter, arg interface{}, verb rune) (newState int),
|
||||
) {
|
||||
p.printArgSubstituteFn = fn
|
||||
}
|
||||
|
||||
// Free exposes pp deallocation to the redact package.
|
||||
func Free(p *InternalPrinter) {
|
||||
p.substituteState = 0
|
||||
p.printArgSubstituteFn = nil
|
||||
p.free()
|
||||
}
|
||||
|
||||
// Buf exposes the string buffer to the redact package.
|
||||
func Buf(p *InternalPrinter) []byte { return []byte(p.buf) }
|
||||
|
||||
// GetState exposes the state to the redact package.
|
||||
func GetState(p *InternalPrinter) int {
|
||||
return p.substituteState
|
||||
}
|
||||
|
||||
// SetState exposes the string buffer to the redact package.
|
||||
func SetState(p *InternalPrinter, b []byte) {
|
||||
p.buf = buffer(b)
|
||||
p.substituteState = len(p.buf)
|
||||
}
|
||||
|
||||
// Append adds bytes to the buffer.
|
||||
func Append(p *InternalPrinter, b []byte) { p.buf.write(b) }
|
||||
|
||||
// PrintArg exposes the printArgOrig() method to the redact package.
|
||||
func PrintArg(p *InternalPrinter, a interface{}, verb rune) { p.printArgOrig(a, verb) }
|
||||
|
||||
// DoPrint exposes the doPrint() method to the redact package.
|
||||
func DoPrint(p *InternalPrinter, a []interface{}) { p.doPrint(a) }
|
||||
|
||||
// DoPrintf exposes the doPrintf() method to the redact package.
|
||||
func DoPrintf(p *InternalPrinter, format string, a []interface{}) { p.doPrintf(format, a) }
|
||||
|
||||
// SetCollectError enables wrapped error collection.
|
||||
func SetCollectError(p *InternalPrinter) { p.wrapErrs = true }
|
||||
|
||||
// CollectingError exposes wrapped error collection.
|
||||
func CollectingError(p *InternalPrinter) bool { return p.wrapErrs }
|
||||
|
||||
// WrappedError retrieves the wrapped error if found.
|
||||
func WrappedError(p *InternalPrinter) error { return p.wrappedErr }
|
||||
38
vendor/github.com/cockroachdb/redact/internal/markers/constants.go
generated
vendored
Normal file
38
vendor/github.com/cockroachdb/redact/internal/markers/constants.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2020 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package markers
|
||||
|
||||
import "regexp"
|
||||
|
||||
// Internal constants.
|
||||
const (
|
||||
Start = '‹'
|
||||
StartS = string(Start)
|
||||
End = '›'
|
||||
EndS = string(End)
|
||||
EscapeMark = '?'
|
||||
EscapeMarkS = string(EscapeMark)
|
||||
RedactedS = StartS + "×" + EndS
|
||||
)
|
||||
|
||||
// Internal variables.
|
||||
var (
|
||||
StartBytes = []byte(StartS)
|
||||
EndBytes = []byte(EndS)
|
||||
EscapeMarkBytes = []byte(EscapeMarkS)
|
||||
RedactedBytes = []byte(RedactedS)
|
||||
ReStripSensitive = regexp.MustCompile(StartS + "[^" + StartS + EndS + "]*" + EndS)
|
||||
ReStripMarkers = regexp.MustCompile("[" + StartS + EndS + "]")
|
||||
)
|
||||
99
vendor/github.com/cockroachdb/redact/internal/markers/markers.go
generated
vendored
Normal file
99
vendor/github.com/cockroachdb/redact/internal/markers/markers.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright 2020 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package markers
|
||||
|
||||
import i "github.com/cockroachdb/redact/interfaces"
|
||||
|
||||
// RedactableString is a string that contains a mix of safe and unsafe
|
||||
// bits of data, but where it is known that unsafe bits are enclosed
|
||||
// by redaction markers ‹ and ›, and occurrences of the markers
|
||||
// inside the original data items have been escaped.
|
||||
//
|
||||
// Instances of RedactableString should not be constructed directly;
|
||||
// instead use the facilities from print.go (Sprint, Sprintf)
|
||||
// or the methods below.
|
||||
type RedactableString string
|
||||
|
||||
// StripMarkers removes the redaction markers from the
|
||||
// RedactableString. This returns an unsafe string where all safe and
|
||||
// unsafe bits are mixed together.
|
||||
func (s RedactableString) StripMarkers() string {
|
||||
return ReStripMarkers.ReplaceAllString(string(s), "")
|
||||
}
|
||||
|
||||
// Redact replaces all occurrences of unsafe substrings by the
|
||||
// “Redacted” marker, ‹×›. The result string is still safe.
|
||||
func (s RedactableString) Redact() RedactableString {
|
||||
return RedactableString(ReStripSensitive.ReplaceAllString(string(s), RedactedS))
|
||||
}
|
||||
|
||||
// ToBytes converts the string to a byte slice.
|
||||
func (s RedactableString) ToBytes() RedactableBytes {
|
||||
return RedactableBytes([]byte(string(s)))
|
||||
}
|
||||
|
||||
// SafeFormat formats the redactable safely.
|
||||
func (s RedactableString) SafeFormat(sp i.SafePrinter, _ rune) {
|
||||
// As per annotateArgs() in markers_internal_print.go,
|
||||
// we consider the redactable string not further formattable.
|
||||
sp.Print(s)
|
||||
}
|
||||
|
||||
// RedactableBytes is like RedactableString but is a byte slice.
|
||||
//
|
||||
// Instances of RedactableBytes should not be constructed directly;
|
||||
// instead use the facilities from print.go (Sprint, Sprintf)
|
||||
// or the methods below.
|
||||
type RedactableBytes []byte
|
||||
|
||||
// StripMarkers removes the redaction markers from the
|
||||
// RedactableBytes. This returns an unsafe string where all safe and
|
||||
// unsafe bits are mixed together.
|
||||
func (s RedactableBytes) StripMarkers() []byte {
|
||||
return ReStripMarkers.ReplaceAll([]byte(s), nil)
|
||||
}
|
||||
|
||||
// Redact replaces all occurrences of unsafe substrings by the
|
||||
// “Redacted” marker, ‹×›.
|
||||
func (s RedactableBytes) Redact() RedactableBytes {
|
||||
return RedactableBytes(ReStripSensitive.ReplaceAll(s, RedactedBytes))
|
||||
}
|
||||
|
||||
// ToString converts the byte slice to a string.
|
||||
func (s RedactableBytes) ToString() RedactableString {
|
||||
return RedactableString(string([]byte(s)))
|
||||
}
|
||||
|
||||
// SafeFormat formats the redactable safely.
|
||||
func (s RedactableBytes) SafeFormat(sp i.SafePrinter, _ rune) {
|
||||
// As per annotateArgs() in markers_internal_print.go,
|
||||
// we consider the redactable bytes not further formattable.
|
||||
sp.Print(s)
|
||||
}
|
||||
|
||||
// StartMarker returns the start delimiter for an unsafe string.
|
||||
func StartMarker() []byte { return []byte(StartS) }
|
||||
|
||||
// EndMarker returns the end delimiter for an unsafe string.
|
||||
func EndMarker() []byte { return []byte(EndS) }
|
||||
|
||||
// RedactedMarker returns the special string used by Redact.
|
||||
func RedactedMarker() []byte { return []byte(RedactedS) }
|
||||
|
||||
// EscapeMarkers escapes the special delimiters from the provided
|
||||
// byte slice.
|
||||
func EscapeMarkers(s []byte) []byte {
|
||||
return ReStripMarkers.ReplaceAll(s, EscapeMarkBytes)
|
||||
}
|
||||
58
vendor/github.com/cockroachdb/redact/internal/print.go.diff
generated
vendored
58
vendor/github.com/cockroachdb/redact/internal/print.go.diff
generated
vendored
@@ -1,58 +0,0 @@
|
||||
--- print.go.orig 2020-08-26 14:49:30.396184000 +0200
|
||||
+++ print.go 2020-08-26 14:50:29.330829000 +0200
|
||||
@@ -1,3 +1,6 @@
|
||||
+// Code generated from print.go.orig. DO NOT EDIT
|
||||
+// GENERATED FILE DO NOT EDIT
|
||||
+//
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
@@ -5,12 +8,16 @@
|
||||
package fmt
|
||||
|
||||
import (
|
||||
- "internal/fmtsort"
|
||||
+ // CUSTOM: needed to avoid a type mismatch on Formatter.
|
||||
+ origFmt "fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
+
|
||||
+ // CUSTOM: our own import since we can't use internal from go stdlib.
|
||||
+ "github.com/cockroachdb/redact/internal/fmtsort"
|
||||
)
|
||||
|
||||
// Strings for use with buffer.WriteString.
|
||||
@@ -51,7 +58,8 @@
|
||||
// The implementation of Format may call Sprint(f) or Fprint(f) etc.
|
||||
// to generate its output.
|
||||
type Formatter interface {
|
||||
- Format(f State, c rune)
|
||||
+ // CUSTOM: refer to the original type, not the one defined here.
|
||||
+ Format(f origFmt.State, c rune)
|
||||
}
|
||||
|
||||
// Stringer is implemented by any value that has a String method,
|
||||
@@ -105,6 +113,10 @@
|
||||
type pp struct {
|
||||
buf buffer
|
||||
|
||||
+ // CUSTOM: hook fn for the redact package.
|
||||
+ printArgSubstituteFn func(p *pp, a interface{}, verb rune) (newState int)
|
||||
+ substituteState int
|
||||
+
|
||||
// arg holds the current item, as an interface{}.
|
||||
arg interface{}
|
||||
|
||||
@@ -635,7 +647,8 @@
|
||||
return false
|
||||
}
|
||||
|
||||
-func (p *pp) printArg(arg interface{}, verb rune) {
|
||||
+// CUSTOM: printArg() renamed to printArgOrig().
|
||||
+func (p *pp) printArgOrig(arg interface{}, verb rune) {
|
||||
p.arg = arg
|
||||
p.value = reflect.Value{}
|
||||
|
||||
19
vendor/github.com/cockroachdb/redact/internal/redact/doc.go
generated
vendored
Normal file
19
vendor/github.com/cockroachdb/redact/internal/redact/doc.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2021 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// Package redact is a helper internal package that provides the
|
||||
// Unsafe and Safe value wrappers. Its name is 'redact' even though a
|
||||
// better name would be 'wrappers' so as to ensure that the type name
|
||||
// of generated values contains the 'redact.' prefix.
|
||||
package redact
|
||||
84
vendor/github.com/cockroachdb/redact/internal/redact/wrappers.go
generated
vendored
Normal file
84
vendor/github.com/cockroachdb/redact/internal/redact/wrappers.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2020 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package redact
|
||||
|
||||
import (
|
||||
origFmt "fmt"
|
||||
|
||||
i "github.com/cockroachdb/redact/interfaces"
|
||||
"github.com/cockroachdb/redact/internal/fmtforward"
|
||||
)
|
||||
|
||||
// Unsafe turns any value that would otherwise be considered safe,
|
||||
// into an unsafe value.
|
||||
func Unsafe(a interface{}) interface{} {
|
||||
return unsafeWrap{a}
|
||||
}
|
||||
|
||||
// UnsafeWrap is the type of wrapper produced by Unsafe.
|
||||
// This is exported only for use by the rfmt package.
|
||||
// Client packages should not make assumptions about
|
||||
// the concrete return type of Unsafe().
|
||||
type UnsafeWrap = unsafeWrap
|
||||
|
||||
type unsafeWrap struct {
|
||||
a interface{}
|
||||
}
|
||||
|
||||
func (w unsafeWrap) GetValue() interface{} { return w.a }
|
||||
|
||||
func (w unsafeWrap) Format(s origFmt.State, verb rune) {
|
||||
fmtforward.ReproducePrintf(s, s, verb, w.a)
|
||||
}
|
||||
|
||||
// Safe turns any value into an object that is considered as safe by
|
||||
// the formatter.
|
||||
//
|
||||
// This is provided as an “escape hatch” for cases where the other
|
||||
// interfaces and conventions fail. Increased usage of this mechanism
|
||||
// should be taken as a signal that a new abstraction is missing.
|
||||
// The implementation is also slow.
|
||||
func Safe(a interface{}) i.SafeValue {
|
||||
return safeWrapper{a}
|
||||
}
|
||||
|
||||
// SafeWrapper is the type of wrapper produced by Safe.
|
||||
// This is exported only for use by the rfmt package.
|
||||
// Client packages should not make assumptions about
|
||||
// the concrete return type of Safe().
|
||||
type SafeWrapper = safeWrapper
|
||||
|
||||
type safeWrapper struct {
|
||||
a interface{}
|
||||
}
|
||||
|
||||
var _ i.SafeValue = safeWrapper{}
|
||||
var _ origFmt.Formatter = safeWrapper{}
|
||||
var _ i.SafeMessager = safeWrapper{}
|
||||
|
||||
func (w safeWrapper) GetValue() interface{} { return w.a }
|
||||
|
||||
// SafeValue implements the SafeValue interface.
|
||||
func (w safeWrapper) SafeValue() {}
|
||||
|
||||
// Format implements the fmt.Formatter interface.
|
||||
func (w safeWrapper) Format(s origFmt.State, verb rune) {
|
||||
fmtforward.ReproducePrintf(s, s, verb, w.a)
|
||||
}
|
||||
|
||||
// SafeMessage implements SafeMessager.
|
||||
func (w safeWrapper) SafeMessage() string {
|
||||
return origFmt.Sprintf("%v", w.a)
|
||||
}
|
||||
@@ -24,15 +24,6 @@ Overall, the original Go code is structured as follows:
|
||||
characters from the format string, as well as certain *constant*
|
||||
error strings (e.g. `%(BADPREC)`).
|
||||
|
||||
At this point **we make the following assumption**: there is no data
|
||||
from the printed *arguments* that is emitted to `pp.buf` directly by a
|
||||
`doPrint()` method. This is true of the implementation as of Go 1.14.
|
||||
|
||||
From this point, this package contains a *custom patch* onto the
|
||||
default implementation: the calls to `p.printArg` performed by the
|
||||
`doPrint()` methods are redirected to a function callback that is
|
||||
injected by the `redact` package.
|
||||
|
||||
Refreshing the sources
|
||||
======================
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Code generated from the Go standard library. DO NOT EDIT
|
||||
// GENERATED FILE DO NOT EDIT
|
||||
//
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fmt
|
||||
package rfmt
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
@@ -67,25 +68,17 @@ func (f *fmt) writePadding(n int) {
|
||||
if n <= 0 { // No padding bytes needed.
|
||||
return
|
||||
}
|
||||
buf := *f.buf
|
||||
oldLen := len(buf)
|
||||
newLen := oldLen + n
|
||||
// Make enough room for padding.
|
||||
if newLen > cap(buf) {
|
||||
buf = make(buffer, cap(buf)*2+n)
|
||||
copy(buf, *f.buf)
|
||||
}
|
||||
f.buf.Grow(n)
|
||||
// Decide which byte the padding should be filled with.
|
||||
padByte := byte(' ')
|
||||
if f.zero {
|
||||
padByte = byte('0')
|
||||
}
|
||||
// Fill padding with padByte.
|
||||
padding := buf[oldLen:newLen]
|
||||
for i := range padding {
|
||||
padding[i] = padByte
|
||||
for i := 0; i < n; i++ {
|
||||
f.buf.writeByte(padByte)
|
||||
}
|
||||
*f.buf = buf[:newLen]
|
||||
}
|
||||
|
||||
// pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
|
||||
@@ -403,19 +396,20 @@ func (f *fmt) fmtSbx(s string, b []byte, digits string) {
|
||||
f.writePadding(f.wid - width)
|
||||
}
|
||||
// Write the encoding directly into the output buffer.
|
||||
buf := *f.buf
|
||||
if f.sharp {
|
||||
// Add leading 0x or 0X.
|
||||
buf = append(buf, '0', digits[16])
|
||||
f.buf.WriteByte('0')
|
||||
f.buf.WriteByte(digits[16])
|
||||
}
|
||||
var c byte
|
||||
for i := 0; i < length; i++ {
|
||||
if f.space && i > 0 {
|
||||
// Separate elements with a space.
|
||||
buf = append(buf, ' ')
|
||||
f.buf.WriteByte(' ')
|
||||
if f.sharp {
|
||||
// Add leading 0x or 0X for each element.
|
||||
buf = append(buf, '0', digits[16])
|
||||
f.buf.WriteByte('0')
|
||||
f.buf.WriteByte(digits[16])
|
||||
}
|
||||
}
|
||||
if b != nil {
|
||||
@@ -424,9 +418,9 @@ func (f *fmt) fmtSbx(s string, b []byte, digits string) {
|
||||
c = s[i] // Take a byte from the input string.
|
||||
}
|
||||
// Encode each byte as two hexadecimal digits.
|
||||
buf = append(buf, digits[c>>4], digits[c&0xF])
|
||||
f.buf.WriteByte(digits[c>>4])
|
||||
f.buf.WriteByte(digits[c&0xF])
|
||||
}
|
||||
*f.buf = buf
|
||||
// Handle padding to the right.
|
||||
if f.widPresent && f.wid > width && f.minus {
|
||||
f.writePadding(f.wid - width)
|
||||
75
vendor/github.com/cockroachdb/redact/internal/rfmt/format.go.diff
generated
vendored
Normal file
75
vendor/github.com/cockroachdb/redact/internal/rfmt/format.go.diff
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
--- format.go.orig 2021-06-18 16:45:51.065116000 +0200
|
||||
+++ format.go 2021-06-18 17:30:58.628179000 +0200
|
||||
@@ -1,3 +1,6 @@
|
||||
+// Code generated from the Go standard library. DO NOT EDIT
|
||||
+// GENERATED FILE DO NOT EDIT
|
||||
+//
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
@@ -65,25 +68,17 @@
|
||||
if n <= 0 { // No padding bytes needed.
|
||||
return
|
||||
}
|
||||
- buf := *f.buf
|
||||
- oldLen := len(buf)
|
||||
- newLen := oldLen + n
|
||||
// Make enough room for padding.
|
||||
- if newLen > cap(buf) {
|
||||
- buf = make(buffer, cap(buf)*2+n)
|
||||
- copy(buf, *f.buf)
|
||||
- }
|
||||
+ f.buf.Grow(n)
|
||||
// Decide which byte the padding should be filled with.
|
||||
padByte := byte(' ')
|
||||
if f.zero {
|
||||
padByte = byte('0')
|
||||
}
|
||||
// Fill padding with padByte.
|
||||
- padding := buf[oldLen:newLen]
|
||||
- for i := range padding {
|
||||
- padding[i] = padByte
|
||||
+ for i := 0; i < n; i++ {
|
||||
+ f.buf.writeByte(padByte)
|
||||
}
|
||||
- *f.buf = buf[:newLen]
|
||||
}
|
||||
|
||||
// pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
|
||||
@@ -401,19 +396,20 @@
|
||||
f.writePadding(f.wid - width)
|
||||
}
|
||||
// Write the encoding directly into the output buffer.
|
||||
- buf := *f.buf
|
||||
if f.sharp {
|
||||
// Add leading 0x or 0X.
|
||||
- buf = append(buf, '0', digits[16])
|
||||
+ f.buf.WriteByte('0')
|
||||
+ f.buf.WriteByte(digits[16])
|
||||
}
|
||||
var c byte
|
||||
for i := 0; i < length; i++ {
|
||||
if f.space && i > 0 {
|
||||
// Separate elements with a space.
|
||||
- buf = append(buf, ' ')
|
||||
+ f.buf.WriteByte(' ')
|
||||
if f.sharp {
|
||||
// Add leading 0x or 0X for each element.
|
||||
- buf = append(buf, '0', digits[16])
|
||||
+ f.buf.WriteByte('0')
|
||||
+ f.buf.WriteByte(digits[16])
|
||||
}
|
||||
}
|
||||
if b != nil {
|
||||
@@ -422,9 +418,9 @@
|
||||
c = s[i] // Take a byte from the input string.
|
||||
}
|
||||
// Encode each byte as two hexadecimal digits.
|
||||
- buf = append(buf, digits[c>>4], digits[c&0xF])
|
||||
+ f.buf.WriteByte(digits[c>>4])
|
||||
+ f.buf.WriteByte(digits[c&0xF])
|
||||
}
|
||||
- *f.buf = buf
|
||||
// Handle padding to the right.
|
||||
if f.widPresent && f.wid > width && f.minus {
|
||||
f.writePadding(f.wid - width)
|
||||
160
vendor/github.com/cockroachdb/redact/internal/rfmt/helpers.go
generated
vendored
Normal file
160
vendor/github.com/cockroachdb/redact/internal/rfmt/helpers.go
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
// Copyright 2021 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package rfmt
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
i "github.com/cockroachdb/redact/interfaces"
|
||||
b "github.com/cockroachdb/redact/internal/buffer"
|
||||
"github.com/cockroachdb/redact/internal/escape"
|
||||
m "github.com/cockroachdb/redact/internal/markers"
|
||||
rwrap "github.com/cockroachdb/redact/internal/redact"
|
||||
)
|
||||
|
||||
type overrideMode int
|
||||
|
||||
const (
|
||||
noOverride overrideMode = iota
|
||||
// Consider unsafe values as safe.
|
||||
overrideSafe
|
||||
// Consider safe and pre-redactable values as unsafe.
|
||||
overrideUnsafe
|
||||
)
|
||||
|
||||
func (p *pp) startUnsafe() restorer {
|
||||
prevMode := p.buf.GetMode()
|
||||
if p.override != overrideSafe {
|
||||
p.buf.SetMode(b.UnsafeEscaped)
|
||||
}
|
||||
return restorer{p, prevMode, p.override}
|
||||
}
|
||||
|
||||
func (p *pp) startPreRedactable() restorer {
|
||||
prevMode := p.buf.GetMode()
|
||||
if p.override != overrideUnsafe {
|
||||
p.buf.SetMode(b.PreRedactable)
|
||||
}
|
||||
return restorer{p, prevMode, p.override}
|
||||
}
|
||||
|
||||
func (p *pp) startSafeOverride() restorer {
|
||||
prevMode := p.buf.GetMode()
|
||||
prevOverride := p.override
|
||||
if p.override == noOverride {
|
||||
p.buf.SetMode(b.SafeEscaped)
|
||||
p.override = overrideSafe
|
||||
}
|
||||
return restorer{p, prevMode, prevOverride}
|
||||
}
|
||||
|
||||
func (p *pp) startUnsafeOverride() restorer {
|
||||
prevMode := p.buf.GetMode()
|
||||
prevOverride := p.override
|
||||
if p.override == noOverride {
|
||||
p.buf.SetMode(b.UnsafeEscaped)
|
||||
p.override = overrideUnsafe
|
||||
}
|
||||
return restorer{p, prevMode, prevOverride}
|
||||
}
|
||||
|
||||
type restorer struct {
|
||||
p *pp
|
||||
prevMode b.OutputMode
|
||||
prevOverride overrideMode
|
||||
}
|
||||
|
||||
func (r restorer) restore() {
|
||||
r.p.buf.SetMode(r.prevMode)
|
||||
r.p.override = r.prevOverride
|
||||
}
|
||||
|
||||
func (p *pp) handleSpecialValues(
|
||||
value reflect.Value, t reflect.Type, verb rune, depth int,
|
||||
) (handled bool) {
|
||||
switch t {
|
||||
case safeWrapperType:
|
||||
handled = true
|
||||
defer p.startSafeOverride().restore()
|
||||
p.printValue(value.Field(0), verb, depth+1)
|
||||
|
||||
case unsafeWrapperType:
|
||||
handled = true
|
||||
defer p.startUnsafeOverride().restore()
|
||||
p.printValue(value.Field(0), verb, depth+1)
|
||||
|
||||
case redactableStringType:
|
||||
handled = true
|
||||
defer p.startPreRedactable().restore()
|
||||
p.buf.WriteString(value.String())
|
||||
|
||||
case redactableBytesType:
|
||||
handled = true
|
||||
defer p.startPreRedactable().restore()
|
||||
p.buf.Write(value.Bytes())
|
||||
}
|
||||
|
||||
return handled
|
||||
}
|
||||
|
||||
// Sprintfn produces a RedactableString using the provided
|
||||
// SafeFormat-alike function.
|
||||
func Sprintfn(printer func(w i.SafePrinter)) m.RedactableString {
|
||||
p := newPrinter()
|
||||
printer(p)
|
||||
s := p.buf.TakeRedactableString()
|
||||
p.free()
|
||||
return s
|
||||
}
|
||||
|
||||
// HelperForErrorf is a helper to implement a redaction-aware
|
||||
// fmt.Errorf-compatible function in a different package. It formats
|
||||
// the string according to the given format and arguments in the same
|
||||
// way as Sprintf, but in addition to this if the format contains %w
|
||||
// and an error object in the proper argument position it also returns
|
||||
// that error object.
|
||||
//
|
||||
// Note: This function only works if an error redaction function
|
||||
// has been injected with RegisterRedactErrorFn().
|
||||
func HelperForErrorf(format string, args ...interface{}) (m.RedactableString, error) {
|
||||
p := newPrinter()
|
||||
p.wrapErrs = true
|
||||
p.doPrintf(format, args)
|
||||
e := p.wrappedErr
|
||||
s := p.buf.TakeRedactableString()
|
||||
p.free()
|
||||
return s, e
|
||||
}
|
||||
|
||||
// EscapeBytes escapes markers inside the given byte slice and encloses
|
||||
// the entire byte slice between redaction markers.
|
||||
// EscapeBytes escapes markers inside the given byte slice and encloses
|
||||
// the entire byte slice between redaction markers.
|
||||
func EscapeBytes(s []byte) m.RedactableBytes {
|
||||
buf := make([]byte, 0, len(s)+len(m.StartS)+len(m.EndS))
|
||||
buf = append(buf, m.StartS...)
|
||||
start := len(buf)
|
||||
buf = append(buf, s...)
|
||||
buf = escape.InternalEscapeBytes(buf, start, true /* breakNewLine */, false /* strip */)
|
||||
buf = append(buf, m.EndS...)
|
||||
return m.RedactableBytes(buf)
|
||||
}
|
||||
|
||||
var (
|
||||
unsafeWrapperType = reflect.TypeOf(rwrap.UnsafeWrap{})
|
||||
safeWrapperType = reflect.TypeOf(rwrap.SafeWrapper{})
|
||||
redactableStringType = reflect.TypeOf(m.RedactableString(""))
|
||||
redactableBytesType = reflect.TypeOf(m.RedactableBytes{})
|
||||
)
|
||||
@@ -5,7 +5,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fmt
|
||||
package rfmt
|
||||
|
||||
import (
|
||||
// CUSTOM: needed to avoid a type mismatch on Formatter.
|
||||
@@ -16,8 +16,12 @@ import (
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
|
||||
// CUSTOM: our own import since we can't use internal from go stdlib.
|
||||
"github.com/cockroachdb/redact/internal/fmtsort"
|
||||
// CUSTOM: our own imports.
|
||||
i "github.com/cockroachdb/redact/interfaces"
|
||||
b "github.com/cockroachdb/redact/internal/buffer"
|
||||
m "github.com/cockroachdb/redact/internal/markers"
|
||||
w "github.com/cockroachdb/redact/internal/redact"
|
||||
"github.com/cockroachdb/redact/internal/rfmt/fmtsort"
|
||||
)
|
||||
|
||||
// Strings for use with buffer.WriteString.
|
||||
@@ -54,12 +58,12 @@ type State interface {
|
||||
Flag(c int) bool
|
||||
}
|
||||
|
||||
// Formatter is the interface implemented by values with a custom formatter.
|
||||
// The implementation of Format may call Sprint(f) or Fprint(f) etc.
|
||||
// to generate its output.
|
||||
// Formatter is implemented by any value that has a Format method.
|
||||
// The implementation controls how State and rune are interpreted,
|
||||
// and may call Sprint(f) or Fprint(f) etc. to generate its output.
|
||||
type Formatter interface {
|
||||
// CUSTOM: refer to the original type, not the one defined here.
|
||||
Format(f origFmt.State, c rune)
|
||||
Format(f origFmt.State, verb rune)
|
||||
}
|
||||
|
||||
// Stringer is implemented by any value that has a String method,
|
||||
@@ -79,43 +83,33 @@ type GoStringer interface {
|
||||
GoString() string
|
||||
}
|
||||
|
||||
// Use simple []byte instead of bytes.Buffer to avoid large dependency.
|
||||
type buffer []byte
|
||||
// CUSTOM: smarter buffer.
|
||||
type buffer struct {
|
||||
b.Buffer
|
||||
}
|
||||
|
||||
func (b *buffer) write(p []byte) {
|
||||
*b = append(*b, p...)
|
||||
b.Write(p)
|
||||
}
|
||||
|
||||
func (b *buffer) writeString(s string) {
|
||||
*b = append(*b, s...)
|
||||
b.WriteString(s)
|
||||
}
|
||||
|
||||
func (b *buffer) writeByte(c byte) {
|
||||
*b = append(*b, c)
|
||||
b.WriteByte(c)
|
||||
}
|
||||
|
||||
func (bp *buffer) writeRune(r rune) {
|
||||
if r < utf8.RuneSelf {
|
||||
*bp = append(*bp, byte(r))
|
||||
return
|
||||
}
|
||||
|
||||
b := *bp
|
||||
n := len(b)
|
||||
for n+utf8.UTFMax > cap(b) {
|
||||
b = append(b, 0)
|
||||
}
|
||||
w := utf8.EncodeRune(b[n:n+utf8.UTFMax], r)
|
||||
*bp = b[:n+w]
|
||||
bp.WriteRune(r)
|
||||
}
|
||||
|
||||
// pp is used to store a printer's state and is reused with sync.Pool to avoid allocations.
|
||||
type pp struct {
|
||||
buf buffer
|
||||
|
||||
// CUSTOM: hook fn for the redact package.
|
||||
printArgSubstituteFn func(p *pp, a interface{}, verb rune) (newState int)
|
||||
substituteState int
|
||||
// CUSTOM: override safety in recursive calls.
|
||||
override overrideMode
|
||||
|
||||
// arg holds the current item, as an interface{}.
|
||||
arg interface{}
|
||||
@@ -162,11 +156,11 @@ func (p *pp) free() {
|
||||
// to place back in the pool.
|
||||
//
|
||||
// See https://golang.org/issue/23199
|
||||
if cap(p.buf) > 64<<10 {
|
||||
if p.buf.Cap() > 64<<10 {
|
||||
return
|
||||
}
|
||||
|
||||
p.buf = p.buf[:0]
|
||||
p.buf.Reset()
|
||||
p.arg = nil
|
||||
p.value = reflect.Value{}
|
||||
p.wrappedErr = nil
|
||||
@@ -195,14 +189,16 @@ func (p *pp) Flag(b int) bool {
|
||||
|
||||
// Implement Write so we can call Fprintf on a pp (through State), for
|
||||
// recursive use in custom verbs.
|
||||
func (p *pp) Write(b []byte) (ret int, err error) {
|
||||
p.buf.write(b)
|
||||
return len(b), nil
|
||||
func (p *pp) Write(bs []byte) (ret int, err error) {
|
||||
defer p.startUnsafe().restore()
|
||||
p.buf.write(bs)
|
||||
return len(bs), nil
|
||||
}
|
||||
|
||||
// Implement WriteString so that we can call io.WriteString
|
||||
// on a pp (through state), for efficiency.
|
||||
func (p *pp) WriteString(s string) (ret int, err error) {
|
||||
defer p.startUnsafe().restore()
|
||||
p.buf.writeString(s)
|
||||
return len(s), nil
|
||||
}
|
||||
@@ -214,7 +210,7 @@ func (p *pp) WriteString(s string) (ret int, err error) {
|
||||
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||
p := newPrinter()
|
||||
p.doPrintf(format, a)
|
||||
n, err = w.Write(p.buf)
|
||||
n, err = w.Write([]byte(p.buf.TakeRedactableBytes()))
|
||||
p.free()
|
||||
return
|
||||
}
|
||||
@@ -226,10 +222,10 @@ func Printf(format string, a ...interface{}) (n int, err error) {
|
||||
}
|
||||
|
||||
// Sprintf formats according to a format specifier and returns the resulting string.
|
||||
func Sprintf(format string, a ...interface{}) string {
|
||||
func Sprintf(format string, a ...interface{}) m.RedactableString {
|
||||
p := newPrinter()
|
||||
p.doPrintf(format, a)
|
||||
s := string(p.buf)
|
||||
s := p.buf.TakeRedactableString()
|
||||
p.free()
|
||||
return s
|
||||
}
|
||||
@@ -242,7 +238,7 @@ func Sprintf(format string, a ...interface{}) string {
|
||||
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
p := newPrinter()
|
||||
p.doPrint(a)
|
||||
n, err = w.Write(p.buf)
|
||||
n, err = w.Write([]byte(p.buf.TakeRedactableBytes()))
|
||||
p.free()
|
||||
return
|
||||
}
|
||||
@@ -256,10 +252,10 @@ func Print(a ...interface{}) (n int, err error) {
|
||||
|
||||
// Sprint formats using the default formats for its operands and returns the resulting string.
|
||||
// Spaces are added between operands when neither is a string.
|
||||
func Sprint(a ...interface{}) string {
|
||||
func Sprint(a ...interface{}) m.RedactableString {
|
||||
p := newPrinter()
|
||||
p.doPrint(a)
|
||||
s := string(p.buf)
|
||||
s := p.buf.TakeRedactableString()
|
||||
p.free()
|
||||
return s
|
||||
}
|
||||
@@ -274,7 +270,7 @@ func Sprint(a ...interface{}) string {
|
||||
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
p := newPrinter()
|
||||
p.doPrintln(a)
|
||||
n, err = w.Write(p.buf)
|
||||
n, err = w.Write([]byte(p.buf.TakeRedactableBytes()))
|
||||
p.free()
|
||||
return
|
||||
}
|
||||
@@ -288,10 +284,10 @@ func Println(a ...interface{}) (n int, err error) {
|
||||
|
||||
// Sprintln formats using the default formats for its operands and returns the resulting string.
|
||||
// Spaces are always added between operands and a newline is appended.
|
||||
func Sprintln(a ...interface{}) string {
|
||||
func Sprintln(a ...interface{}) m.RedactableString {
|
||||
p := newPrinter()
|
||||
p.doPrintln(a)
|
||||
s := string(p.buf)
|
||||
s := p.buf.TakeRedactableString()
|
||||
p.free()
|
||||
return s
|
||||
}
|
||||
@@ -363,6 +359,7 @@ func (p *pp) badVerb(verb rune) {
|
||||
func (p *pp) fmtBool(v bool, verb rune) {
|
||||
switch verb {
|
||||
case 't', 'v':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtBoolean(v)
|
||||
default:
|
||||
p.badVerb(verb)
|
||||
@@ -374,6 +371,7 @@ func (p *pp) fmtBool(v bool, verb rune) {
|
||||
func (p *pp) fmt0x64(v uint64, leading0x bool) {
|
||||
sharp := p.fmt.sharp
|
||||
p.fmt.sharp = leading0x
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 16, unsigned, 'v', ldigits)
|
||||
p.fmt.sharp = sharp
|
||||
}
|
||||
@@ -385,27 +383,32 @@ func (p *pp) fmtInteger(v uint64, isSigned bool, verb rune) {
|
||||
if p.fmt.sharpV && !isSigned {
|
||||
p.fmt0x64(v, true)
|
||||
} else {
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
|
||||
}
|
||||
case 'd':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
|
||||
case 'b':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 2, isSigned, verb, ldigits)
|
||||
case 'o', 'O':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 8, isSigned, verb, ldigits)
|
||||
case 'x':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 16, isSigned, verb, ldigits)
|
||||
case 'X':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 16, isSigned, verb, udigits)
|
||||
case 'c':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtC(v)
|
||||
case 'q':
|
||||
if v <= utf8.MaxRune {
|
||||
p.fmt.fmtQc(v)
|
||||
} else {
|
||||
p.badVerb(verb)
|
||||
}
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtQc(v)
|
||||
case 'U':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtUnicode(v)
|
||||
default:
|
||||
p.badVerb(verb)
|
||||
@@ -417,12 +420,16 @@ func (p *pp) fmtInteger(v uint64, isSigned bool, verb rune) {
|
||||
func (p *pp) fmtFloat(v float64, size int, verb rune) {
|
||||
switch verb {
|
||||
case 'v':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtFloat(v, size, 'g', -1)
|
||||
case 'b', 'g', 'G', 'x', 'X':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtFloat(v, size, verb, -1)
|
||||
case 'f', 'e', 'E':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtFloat(v, size, verb, 6)
|
||||
case 'F':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtFloat(v, size, 'f', 6)
|
||||
default:
|
||||
p.badVerb(verb)
|
||||
@@ -453,18 +460,23 @@ func (p *pp) fmtComplex(v complex128, size int, verb rune) {
|
||||
func (p *pp) fmtString(v string, verb rune) {
|
||||
switch verb {
|
||||
case 'v':
|
||||
defer p.startUnsafe().restore()
|
||||
if p.fmt.sharpV {
|
||||
p.fmt.fmtQ(v)
|
||||
} else {
|
||||
p.fmt.fmtS(v)
|
||||
}
|
||||
case 's':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtS(v)
|
||||
case 'x':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtSx(v, ldigits)
|
||||
case 'X':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtSx(v, udigits)
|
||||
case 'q':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtQ(v)
|
||||
default:
|
||||
p.badVerb(verb)
|
||||
@@ -494,17 +506,24 @@ func (p *pp) fmtBytes(v []byte, verb rune, typeString string) {
|
||||
if i > 0 {
|
||||
p.buf.writeByte(' ')
|
||||
}
|
||||
p.fmt.fmtInteger(uint64(c), 10, unsigned, verb, ldigits)
|
||||
func(p *pp, c byte, verb rune) {
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(uint64(c), 10, unsigned, verb, ldigits)
|
||||
}(p, c, verb)
|
||||
}
|
||||
p.buf.writeByte(']')
|
||||
}
|
||||
case 's':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtBs(v)
|
||||
case 'x':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtBx(v, ldigits)
|
||||
case 'X':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtBx(v, udigits)
|
||||
case 'q':
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtQ(string(v))
|
||||
default:
|
||||
p.printValue(reflect.ValueOf(v), verb, 0)
|
||||
@@ -535,6 +554,7 @@ func (p *pp) fmtPointer(value reflect.Value, verb rune) {
|
||||
p.buf.writeByte(')')
|
||||
} else {
|
||||
if u == 0 {
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.padString(nilAngleString)
|
||||
} else {
|
||||
p.fmt0x64(uint64(u), !p.fmt.sharp)
|
||||
@@ -602,10 +622,37 @@ func (p *pp) handleMethods(verb rune) (handled bool) {
|
||||
verb = 'v'
|
||||
}
|
||||
|
||||
if p.override != overrideUnsafe {
|
||||
switch v := p.arg.(type) {
|
||||
case i.SafeFormatter:
|
||||
handled = true
|
||||
defer p.catchPanic(p.arg, verb, "SafeFormat")
|
||||
v.SafeFormat(p, verb)
|
||||
return
|
||||
|
||||
case i.SafeMessager:
|
||||
handled = true
|
||||
defer p.catchPanic(p.arg, verb, "SafeMessager")
|
||||
defer p.startSafeOverride().restore()
|
||||
p.fmtString(v.SafeMessage(), verb)
|
||||
return
|
||||
|
||||
case error:
|
||||
if redactErrorFn != nil {
|
||||
handled = true
|
||||
defer p.catchPanic(p.arg, verb, "SafeFormatter")
|
||||
redactErrorFn(v, p, verb)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Is it a Formatter?
|
||||
if formatter, ok := p.arg.(Formatter); ok {
|
||||
handled = true
|
||||
defer p.catchPanic(p.arg, verb, "Format")
|
||||
// The mode is implicit: the Format() call will
|
||||
// use p.Write() which already sets the mode.
|
||||
formatter.Format(p, verb)
|
||||
return
|
||||
}
|
||||
@@ -616,6 +663,7 @@ func (p *pp) handleMethods(verb rune) (handled bool) {
|
||||
handled = true
|
||||
defer p.catchPanic(p.arg, verb, "GoString")
|
||||
// Print the result of GoString unadorned.
|
||||
defer p.startUnsafe().restore()
|
||||
p.fmt.fmtS(stringer.GoString())
|
||||
return
|
||||
}
|
||||
@@ -647,8 +695,22 @@ func (p *pp) handleMethods(verb rune) (handled bool) {
|
||||
return false
|
||||
}
|
||||
|
||||
// CUSTOM: printArg() renamed to printArgOrig().
|
||||
func (p *pp) printArgOrig(arg interface{}, verb rune) {
|
||||
func (p *pp) printArg(arg interface{}, verb rune) {
|
||||
t := reflect.TypeOf(arg)
|
||||
if safeTypeRegistry[t] {
|
||||
defer p.startSafeOverride().restore()
|
||||
} else if t == safeWrapperType {
|
||||
defer p.startSafeOverride().restore()
|
||||
arg = arg.(w.SafeWrapper).GetValue()
|
||||
} else if t == unsafeWrapperType {
|
||||
defer p.startUnsafeOverride().restore()
|
||||
arg = arg.(w.UnsafeWrap).GetValue()
|
||||
}
|
||||
|
||||
if _, ok := arg.(i.SafeValue); ok {
|
||||
defer p.startSafeOverride().restore()
|
||||
}
|
||||
|
||||
p.arg = arg
|
||||
p.value = reflect.Value{}
|
||||
|
||||
@@ -714,13 +776,35 @@ func (p *pp) printArgOrig(arg interface{}, verb rune) {
|
||||
case reflect.Value:
|
||||
// Handle extractable values with special methods
|
||||
// since printValue does not handle them at depth 0.
|
||||
if f.IsValid() && f.CanInterface() {
|
||||
p.arg = f.Interface()
|
||||
if p.handleMethods(verb) {
|
||||
if f.IsValid() {
|
||||
t := f.Type()
|
||||
if p.handleSpecialValues(f, t, verb, 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if safeTypeRegistry[t] {
|
||||
defer p.startSafeOverride().restore()
|
||||
}
|
||||
|
||||
if f.CanInterface() {
|
||||
p.arg = f.Interface()
|
||||
if _, ok := p.arg.(i.SafeValue); ok {
|
||||
defer p.startSafeOverride().restore()
|
||||
}
|
||||
if p.handleMethods(verb) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
p.printValue(f, verb, 0)
|
||||
case m.RedactableString:
|
||||
defer p.startPreRedactable().restore()
|
||||
p.buf.WriteString(string(f))
|
||||
return
|
||||
case m.RedactableBytes:
|
||||
defer p.startPreRedactable().restore()
|
||||
p.buf.Write([]byte(f))
|
||||
return
|
||||
default:
|
||||
// If the type is not simple, it might have methods.
|
||||
if !p.handleMethods(verb) {
|
||||
@@ -735,11 +819,25 @@ func (p *pp) printArgOrig(arg interface{}, verb rune) {
|
||||
// It does not handle 'p' and 'T' verbs because these should have been already handled by printArg.
|
||||
func (p *pp) printValue(value reflect.Value, verb rune, depth int) {
|
||||
// Handle values with special methods if not already handled by printArg (depth == 0).
|
||||
if depth > 0 && value.IsValid() && value.CanInterface() {
|
||||
p.arg = value.Interface()
|
||||
if p.handleMethods(verb) {
|
||||
if depth > 0 && value.IsValid() {
|
||||
t := value.Type()
|
||||
if p.handleSpecialValues(value, t, verb, depth) {
|
||||
return
|
||||
}
|
||||
|
||||
if safeTypeRegistry[t] {
|
||||
defer p.startSafeOverride().restore()
|
||||
}
|
||||
|
||||
if value.CanInterface() {
|
||||
p.arg = value.Interface()
|
||||
if _, ok := p.arg.(i.SafeValue); ok {
|
||||
defer p.startSafeOverride().restore()
|
||||
}
|
||||
if p.handleMethods(verb) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
p.arg = nil
|
||||
p.value = value
|
||||
@@ -963,7 +1061,9 @@ func parseArgNumber(format string) (index int, wid int, ok bool) {
|
||||
// argNumber returns the next argument to evaluate, which is either the value of the passed-in
|
||||
// argNum or the value of the bracketed integer that begins format[i:]. It also returns
|
||||
// the new value of i, that is, the index of the next byte of the format to process.
|
||||
func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
|
||||
func (p *pp) argNumber(
|
||||
argNum int, format string, i int, numArgs int,
|
||||
) (newArgNum, newi int, found bool) {
|
||||
if len(format) <= i || format[i] != '[' {
|
||||
return argNum, i, false
|
||||
}
|
||||
@@ -989,6 +1089,7 @@ func (p *pp) missingArg(verb rune) {
|
||||
}
|
||||
|
||||
func (p *pp) doPrintf(format string, a []interface{}) {
|
||||
p.buf.SetMode(b.SafeEscaped)
|
||||
end := len(format)
|
||||
argNum := 0 // we process one argument per non-trivial format
|
||||
afterIndex := false // previous item in format was an index like [3].
|
||||
@@ -1164,6 +1265,7 @@ formatLoop:
|
||||
}
|
||||
|
||||
func (p *pp) doPrint(a []interface{}) {
|
||||
p.buf.SetMode(b.SafeEscaped)
|
||||
prevString := false
|
||||
for argNum, arg := range a {
|
||||
isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
|
||||
@@ -1179,6 +1281,7 @@ func (p *pp) doPrint(a []interface{}) {
|
||||
// doPrintln is like doPrint but always adds a space between arguments
|
||||
// and a newline after the last argument.
|
||||
func (p *pp) doPrintln(a []interface{}) {
|
||||
p.buf.SetMode(b.SafeEscaped)
|
||||
for argNum, arg := range a {
|
||||
if argNum > 0 {
|
||||
p.buf.writeByte(' ')
|
||||
489
vendor/github.com/cockroachdb/redact/internal/rfmt/print.go.diff
generated
vendored
Normal file
489
vendor/github.com/cockroachdb/redact/internal/rfmt/print.go.diff
generated
vendored
Normal file
@@ -0,0 +1,489 @@
|
||||
--- print.go.orig 2021-06-18 16:45:56.623967000 +0200
|
||||
+++ print.go 2021-06-19 16:26:32.751061000 +0200
|
||||
@@ -1,16 +1,27 @@
|
||||
+// Code generated from print.go.orig. DO NOT EDIT
|
||||
+// GENERATED FILE DO NOT EDIT
|
||||
+//
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
-package fmt
|
||||
+package rfmt
|
||||
|
||||
import (
|
||||
- "internal/fmtsort"
|
||||
+ // CUSTOM: needed to avoid a type mismatch on Formatter.
|
||||
+ origFmt "fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
+
|
||||
+ // CUSTOM: our own imports.
|
||||
+ i "github.com/cockroachdb/redact/interfaces"
|
||||
+ b "github.com/cockroachdb/redact/internal/buffer"
|
||||
+ m "github.com/cockroachdb/redact/internal/markers"
|
||||
+ w "github.com/cockroachdb/redact/internal/redact"
|
||||
+ "github.com/cockroachdb/redact/internal/rfmt/fmtsort"
|
||||
)
|
||||
|
||||
// Strings for use with buffer.WriteString.
|
||||
@@ -51,7 +62,8 @@
|
||||
// The implementation controls how State and rune are interpreted,
|
||||
// and may call Sprint(f) or Fprint(f) etc. to generate its output.
|
||||
type Formatter interface {
|
||||
- Format(f State, verb rune)
|
||||
+ // CUSTOM: refer to the original type, not the one defined here.
|
||||
+ Format(f origFmt.State, verb rune)
|
||||
}
|
||||
|
||||
// Stringer is implemented by any value that has a String method,
|
||||
@@ -71,40 +83,34 @@
|
||||
GoString() string
|
||||
}
|
||||
|
||||
-// Use simple []byte instead of bytes.Buffer to avoid large dependency.
|
||||
-type buffer []byte
|
||||
+// CUSTOM: smarter buffer.
|
||||
+type buffer struct {
|
||||
+ b.Buffer
|
||||
+}
|
||||
|
||||
func (b *buffer) write(p []byte) {
|
||||
- *b = append(*b, p...)
|
||||
+ b.Write(p)
|
||||
}
|
||||
|
||||
func (b *buffer) writeString(s string) {
|
||||
- *b = append(*b, s...)
|
||||
+ b.WriteString(s)
|
||||
}
|
||||
|
||||
func (b *buffer) writeByte(c byte) {
|
||||
- *b = append(*b, c)
|
||||
+ b.WriteByte(c)
|
||||
}
|
||||
|
||||
func (bp *buffer) writeRune(r rune) {
|
||||
- if r < utf8.RuneSelf {
|
||||
- *bp = append(*bp, byte(r))
|
||||
- return
|
||||
- }
|
||||
-
|
||||
- b := *bp
|
||||
- n := len(b)
|
||||
- for n+utf8.UTFMax > cap(b) {
|
||||
- b = append(b, 0)
|
||||
- }
|
||||
- w := utf8.EncodeRune(b[n:n+utf8.UTFMax], r)
|
||||
- *bp = b[:n+w]
|
||||
+ bp.WriteRune(r)
|
||||
}
|
||||
|
||||
// pp is used to store a printer's state and is reused with sync.Pool to avoid allocations.
|
||||
type pp struct {
|
||||
buf buffer
|
||||
|
||||
+ // CUSTOM: override safety in recursive calls.
|
||||
+ override overrideMode
|
||||
+
|
||||
// arg holds the current item, as an interface{}.
|
||||
arg interface{}
|
||||
|
||||
@@ -150,11 +156,11 @@
|
||||
// to place back in the pool.
|
||||
//
|
||||
// See https://golang.org/issue/23199
|
||||
- if cap(p.buf) > 64<<10 {
|
||||
+ if p.buf.Cap() > 64<<10 {
|
||||
return
|
||||
}
|
||||
|
||||
- p.buf = p.buf[:0]
|
||||
+ p.buf.Reset()
|
||||
p.arg = nil
|
||||
p.value = reflect.Value{}
|
||||
p.wrappedErr = nil
|
||||
@@ -183,14 +189,16 @@
|
||||
|
||||
// Implement Write so we can call Fprintf on a pp (through State), for
|
||||
// recursive use in custom verbs.
|
||||
-func (p *pp) Write(b []byte) (ret int, err error) {
|
||||
- p.buf.write(b)
|
||||
- return len(b), nil
|
||||
+func (p *pp) Write(bs []byte) (ret int, err error) {
|
||||
+ defer p.startUnsafe().restore()
|
||||
+ p.buf.write(bs)
|
||||
+ return len(bs), nil
|
||||
}
|
||||
|
||||
// Implement WriteString so that we can call io.WriteString
|
||||
// on a pp (through state), for efficiency.
|
||||
func (p *pp) WriteString(s string) (ret int, err error) {
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.buf.writeString(s)
|
||||
return len(s), nil
|
||||
}
|
||||
@@ -202,7 +210,7 @@
|
||||
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||
p := newPrinter()
|
||||
p.doPrintf(format, a)
|
||||
- n, err = w.Write(p.buf)
|
||||
+ n, err = w.Write([]byte(p.buf.TakeRedactableBytes()))
|
||||
p.free()
|
||||
return
|
||||
}
|
||||
@@ -214,10 +222,10 @@
|
||||
}
|
||||
|
||||
// Sprintf formats according to a format specifier and returns the resulting string.
|
||||
-func Sprintf(format string, a ...interface{}) string {
|
||||
+func Sprintf(format string, a ...interface{}) m.RedactableString {
|
||||
p := newPrinter()
|
||||
p.doPrintf(format, a)
|
||||
- s := string(p.buf)
|
||||
+ s := p.buf.TakeRedactableString()
|
||||
p.free()
|
||||
return s
|
||||
}
|
||||
@@ -230,7 +238,7 @@
|
||||
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
p := newPrinter()
|
||||
p.doPrint(a)
|
||||
- n, err = w.Write(p.buf)
|
||||
+ n, err = w.Write([]byte(p.buf.TakeRedactableBytes()))
|
||||
p.free()
|
||||
return
|
||||
}
|
||||
@@ -244,10 +252,10 @@
|
||||
|
||||
// Sprint formats using the default formats for its operands and returns the resulting string.
|
||||
// Spaces are added between operands when neither is a string.
|
||||
-func Sprint(a ...interface{}) string {
|
||||
+func Sprint(a ...interface{}) m.RedactableString {
|
||||
p := newPrinter()
|
||||
p.doPrint(a)
|
||||
- s := string(p.buf)
|
||||
+ s := p.buf.TakeRedactableString()
|
||||
p.free()
|
||||
return s
|
||||
}
|
||||
@@ -262,7 +270,7 @@
|
||||
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
p := newPrinter()
|
||||
p.doPrintln(a)
|
||||
- n, err = w.Write(p.buf)
|
||||
+ n, err = w.Write([]byte(p.buf.TakeRedactableBytes()))
|
||||
p.free()
|
||||
return
|
||||
}
|
||||
@@ -276,10 +284,10 @@
|
||||
|
||||
// Sprintln formats using the default formats for its operands and returns the resulting string.
|
||||
// Spaces are always added between operands and a newline is appended.
|
||||
-func Sprintln(a ...interface{}) string {
|
||||
+func Sprintln(a ...interface{}) m.RedactableString {
|
||||
p := newPrinter()
|
||||
p.doPrintln(a)
|
||||
- s := string(p.buf)
|
||||
+ s := p.buf.TakeRedactableString()
|
||||
p.free()
|
||||
return s
|
||||
}
|
||||
@@ -351,6 +359,7 @@
|
||||
func (p *pp) fmtBool(v bool, verb rune) {
|
||||
switch verb {
|
||||
case 't', 'v':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtBoolean(v)
|
||||
default:
|
||||
p.badVerb(verb)
|
||||
@@ -362,6 +371,7 @@
|
||||
func (p *pp) fmt0x64(v uint64, leading0x bool) {
|
||||
sharp := p.fmt.sharp
|
||||
p.fmt.sharp = leading0x
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 16, unsigned, 'v', ldigits)
|
||||
p.fmt.sharp = sharp
|
||||
}
|
||||
@@ -373,23 +383,32 @@
|
||||
if p.fmt.sharpV && !isSigned {
|
||||
p.fmt0x64(v, true)
|
||||
} else {
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
|
||||
}
|
||||
case 'd':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
|
||||
case 'b':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 2, isSigned, verb, ldigits)
|
||||
case 'o', 'O':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 8, isSigned, verb, ldigits)
|
||||
case 'x':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 16, isSigned, verb, ldigits)
|
||||
case 'X':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtInteger(v, 16, isSigned, verb, udigits)
|
||||
case 'c':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtC(v)
|
||||
case 'q':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtQc(v)
|
||||
case 'U':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtUnicode(v)
|
||||
default:
|
||||
p.badVerb(verb)
|
||||
@@ -401,12 +420,16 @@
|
||||
func (p *pp) fmtFloat(v float64, size int, verb rune) {
|
||||
switch verb {
|
||||
case 'v':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtFloat(v, size, 'g', -1)
|
||||
case 'b', 'g', 'G', 'x', 'X':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtFloat(v, size, verb, -1)
|
||||
case 'f', 'e', 'E':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtFloat(v, size, verb, 6)
|
||||
case 'F':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtFloat(v, size, 'f', 6)
|
||||
default:
|
||||
p.badVerb(verb)
|
||||
@@ -437,18 +460,23 @@
|
||||
func (p *pp) fmtString(v string, verb rune) {
|
||||
switch verb {
|
||||
case 'v':
|
||||
+ defer p.startUnsafe().restore()
|
||||
if p.fmt.sharpV {
|
||||
p.fmt.fmtQ(v)
|
||||
} else {
|
||||
p.fmt.fmtS(v)
|
||||
}
|
||||
case 's':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtS(v)
|
||||
case 'x':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtSx(v, ldigits)
|
||||
case 'X':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtSx(v, udigits)
|
||||
case 'q':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtQ(v)
|
||||
default:
|
||||
p.badVerb(verb)
|
||||
@@ -478,17 +506,24 @@
|
||||
if i > 0 {
|
||||
p.buf.writeByte(' ')
|
||||
}
|
||||
- p.fmt.fmtInteger(uint64(c), 10, unsigned, verb, ldigits)
|
||||
+ func(p *pp, c byte, verb rune) {
|
||||
+ defer p.startUnsafe().restore()
|
||||
+ p.fmt.fmtInteger(uint64(c), 10, unsigned, verb, ldigits)
|
||||
+ }(p, c, verb)
|
||||
}
|
||||
p.buf.writeByte(']')
|
||||
}
|
||||
case 's':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtBs(v)
|
||||
case 'x':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtBx(v, ldigits)
|
||||
case 'X':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtBx(v, udigits)
|
||||
case 'q':
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtQ(string(v))
|
||||
default:
|
||||
p.printValue(reflect.ValueOf(v), verb, 0)
|
||||
@@ -519,6 +554,7 @@
|
||||
p.buf.writeByte(')')
|
||||
} else {
|
||||
if u == 0 {
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.padString(nilAngleString)
|
||||
} else {
|
||||
p.fmt0x64(uint64(u), !p.fmt.sharp)
|
||||
@@ -586,10 +622,37 @@
|
||||
verb = 'v'
|
||||
}
|
||||
|
||||
+ if p.override != overrideUnsafe {
|
||||
+ switch v := p.arg.(type) {
|
||||
+ case i.SafeFormatter:
|
||||
+ handled = true
|
||||
+ defer p.catchPanic(p.arg, verb, "SafeFormat")
|
||||
+ v.SafeFormat(p, verb)
|
||||
+ return
|
||||
+
|
||||
+ case i.SafeMessager:
|
||||
+ handled = true
|
||||
+ defer p.catchPanic(p.arg, verb, "SafeMessager")
|
||||
+ defer p.startSafeOverride().restore()
|
||||
+ p.fmtString(v.SafeMessage(), verb)
|
||||
+ return
|
||||
+
|
||||
+ case error:
|
||||
+ if redactErrorFn != nil {
|
||||
+ handled = true
|
||||
+ defer p.catchPanic(p.arg, verb, "SafeFormatter")
|
||||
+ redactErrorFn(v, p, verb)
|
||||
+ return
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
// Is it a Formatter?
|
||||
if formatter, ok := p.arg.(Formatter); ok {
|
||||
handled = true
|
||||
defer p.catchPanic(p.arg, verb, "Format")
|
||||
+ // The mode is implicit: the Format() call will
|
||||
+ // use p.Write() which already sets the mode.
|
||||
formatter.Format(p, verb)
|
||||
return
|
||||
}
|
||||
@@ -600,6 +663,7 @@
|
||||
handled = true
|
||||
defer p.catchPanic(p.arg, verb, "GoString")
|
||||
// Print the result of GoString unadorned.
|
||||
+ defer p.startUnsafe().restore()
|
||||
p.fmt.fmtS(stringer.GoString())
|
||||
return
|
||||
}
|
||||
@@ -632,6 +696,21 @@
|
||||
}
|
||||
|
||||
func (p *pp) printArg(arg interface{}, verb rune) {
|
||||
+ t := reflect.TypeOf(arg)
|
||||
+ if safeTypeRegistry[t] {
|
||||
+ defer p.startSafeOverride().restore()
|
||||
+ } else if t == safeWrapperType {
|
||||
+ defer p.startSafeOverride().restore()
|
||||
+ arg = arg.(w.SafeWrapper).GetValue()
|
||||
+ } else if t == unsafeWrapperType {
|
||||
+ defer p.startUnsafeOverride().restore()
|
||||
+ arg = arg.(w.UnsafeWrap).GetValue()
|
||||
+ }
|
||||
+
|
||||
+ if _, ok := arg.(i.SafeValue); ok {
|
||||
+ defer p.startSafeOverride().restore()
|
||||
+ }
|
||||
+
|
||||
p.arg = arg
|
||||
p.value = reflect.Value{}
|
||||
|
||||
@@ -697,13 +776,35 @@
|
||||
case reflect.Value:
|
||||
// Handle extractable values with special methods
|
||||
// since printValue does not handle them at depth 0.
|
||||
- if f.IsValid() && f.CanInterface() {
|
||||
- p.arg = f.Interface()
|
||||
- if p.handleMethods(verb) {
|
||||
+ if f.IsValid() {
|
||||
+ t := f.Type()
|
||||
+ if p.handleSpecialValues(f, t, verb, 0) {
|
||||
return
|
||||
}
|
||||
+
|
||||
+ if safeTypeRegistry[t] {
|
||||
+ defer p.startSafeOverride().restore()
|
||||
+ }
|
||||
+
|
||||
+ if f.CanInterface() {
|
||||
+ p.arg = f.Interface()
|
||||
+ if _, ok := p.arg.(i.SafeValue); ok {
|
||||
+ defer p.startSafeOverride().restore()
|
||||
+ }
|
||||
+ if p.handleMethods(verb) {
|
||||
+ return
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
p.printValue(f, verb, 0)
|
||||
+ case m.RedactableString:
|
||||
+ defer p.startPreRedactable().restore()
|
||||
+ p.buf.WriteString(string(f))
|
||||
+ return
|
||||
+ case m.RedactableBytes:
|
||||
+ defer p.startPreRedactable().restore()
|
||||
+ p.buf.Write([]byte(f))
|
||||
+ return
|
||||
default:
|
||||
// If the type is not simple, it might have methods.
|
||||
if !p.handleMethods(verb) {
|
||||
@@ -718,11 +819,25 @@
|
||||
// It does not handle 'p' and 'T' verbs because these should have been already handled by printArg.
|
||||
func (p *pp) printValue(value reflect.Value, verb rune, depth int) {
|
||||
// Handle values with special methods if not already handled by printArg (depth == 0).
|
||||
- if depth > 0 && value.IsValid() && value.CanInterface() {
|
||||
- p.arg = value.Interface()
|
||||
- if p.handleMethods(verb) {
|
||||
+ if depth > 0 && value.IsValid() {
|
||||
+ t := value.Type()
|
||||
+ if p.handleSpecialValues(value, t, verb, depth) {
|
||||
return
|
||||
}
|
||||
+
|
||||
+ if safeTypeRegistry[t] {
|
||||
+ defer p.startSafeOverride().restore()
|
||||
+ }
|
||||
+
|
||||
+ if value.CanInterface() {
|
||||
+ p.arg = value.Interface()
|
||||
+ if _, ok := p.arg.(i.SafeValue); ok {
|
||||
+ defer p.startSafeOverride().restore()
|
||||
+ }
|
||||
+ if p.handleMethods(verb) {
|
||||
+ return
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
p.arg = nil
|
||||
p.value = value
|
||||
@@ -946,7 +1061,9 @@
|
||||
// argNumber returns the next argument to evaluate, which is either the value of the passed-in
|
||||
// argNum or the value of the bracketed integer that begins format[i:]. It also returns
|
||||
// the new value of i, that is, the index of the next byte of the format to process.
|
||||
-func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
|
||||
+func (p *pp) argNumber(
|
||||
+ argNum int, format string, i int, numArgs int,
|
||||
+) (newArgNum, newi int, found bool) {
|
||||
if len(format) <= i || format[i] != '[' {
|
||||
return argNum, i, false
|
||||
}
|
||||
@@ -972,6 +1089,7 @@
|
||||
}
|
||||
|
||||
func (p *pp) doPrintf(format string, a []interface{}) {
|
||||
+ p.buf.SetMode(b.SafeEscaped)
|
||||
end := len(format)
|
||||
argNum := 0 // we process one argument per non-trivial format
|
||||
afterIndex := false // previous item in format was an index like [3].
|
||||
@@ -1147,6 +1265,7 @@
|
||||
}
|
||||
|
||||
func (p *pp) doPrint(a []interface{}) {
|
||||
+ p.buf.SetMode(b.SafeEscaped)
|
||||
prevString := false
|
||||
for argNum, arg := range a {
|
||||
isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
|
||||
@@ -1162,6 +1281,7 @@
|
||||
// doPrintln is like doPrint but always adds a space between arguments
|
||||
// and a newline after the last argument.
|
||||
func (p *pp) doPrintln(a []interface{}) {
|
||||
+ p.buf.SetMode(b.SafeEscaped)
|
||||
for argNum, arg := range a {
|
||||
if argNum > 0 {
|
||||
p.buf.writeByte(' ')
|
||||
85
vendor/github.com/cockroachdb/redact/internal/rfmt/printer_adapter.go
generated
vendored
Normal file
85
vendor/github.com/cockroachdb/redact/internal/rfmt/printer_adapter.go
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright 2021 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package rfmt
|
||||
|
||||
import i "github.com/cockroachdb/redact/interfaces"
|
||||
|
||||
// SafeString implements SafePrinter.
|
||||
func (p *pp) SafeString(s i.SafeString) {
|
||||
defer p.startSafeOverride().restore()
|
||||
p.buf.WriteString(string(s))
|
||||
}
|
||||
|
||||
// SafeInt implements SafePrinter.
|
||||
func (p *pp) SafeInt(s i.SafeInt) {
|
||||
defer p.startSafeOverride().restore()
|
||||
p.fmtInteger(uint64(s), signed, 'd')
|
||||
}
|
||||
|
||||
// SafeUint implements SafePrinter.
|
||||
func (p *pp) SafeUint(s i.SafeUint) {
|
||||
defer p.startSafeOverride().restore()
|
||||
p.fmtInteger(uint64(s), unsigned, 'd')
|
||||
}
|
||||
|
||||
// SafeFloat implements SafePrinter.
|
||||
func (p *pp) SafeFloat(s i.SafeFloat) {
|
||||
defer p.startSafeOverride().restore()
|
||||
p.fmtFloat(float64(s), 64, 'v')
|
||||
}
|
||||
|
||||
// SafeRune implements SafePrinter.
|
||||
func (p *pp) SafeRune(r i.SafeRune) {
|
||||
defer p.startSafeOverride().restore()
|
||||
p.buf.WriteRune(rune(r))
|
||||
}
|
||||
|
||||
func (p *pp) Print(args ...interface{}) {
|
||||
defer p.buf.SetMode(p.buf.GetMode())
|
||||
np := newPrinter()
|
||||
np.buf = p.buf
|
||||
np.doPrint(args)
|
||||
p.buf = np.buf
|
||||
np.buf = buffer{}
|
||||
np.free()
|
||||
}
|
||||
|
||||
func (p *pp) Printf(format string, arg ...interface{}) {
|
||||
defer p.buf.SetMode(p.buf.GetMode())
|
||||
np := newPrinter()
|
||||
np.buf = p.buf
|
||||
np.doPrintf(format, arg)
|
||||
p.buf = np.buf
|
||||
np.buf = buffer{}
|
||||
np.free()
|
||||
}
|
||||
|
||||
func (p *pp) UnsafeString(s string) {
|
||||
defer p.startUnsafe().restore()
|
||||
_, _ = p.buf.WriteString(s)
|
||||
}
|
||||
|
||||
func (p *pp) UnsafeByte(bb byte) {
|
||||
defer p.startUnsafe().restore()
|
||||
_ = p.buf.WriteByte(bb)
|
||||
}
|
||||
func (p *pp) UnsafeBytes(bs []byte) {
|
||||
defer p.startUnsafe().restore()
|
||||
_, _ = p.buf.Write(bs)
|
||||
}
|
||||
func (p *pp) UnsafeRune(r rune) {
|
||||
defer p.startUnsafe().restore()
|
||||
_ = p.buf.WriteRune(r)
|
||||
}
|
||||
@@ -5,11 +5,8 @@
|
||||
#
|
||||
set -euxo pipefail
|
||||
|
||||
(
|
||||
echo "// Code generated from the Go standard library. DO NOT EDIT"
|
||||
echo "// GENERATED FILE DO NOT EDIT"
|
||||
cat $GOROOT/src/fmt/format.go
|
||||
) >format.go
|
||||
cp $GOROOT/src/fmt/format.go format.go
|
||||
patch -p0 <format.go.diff
|
||||
|
||||
cp $GOROOT/src/fmt/print.go print.go
|
||||
patch -p0 <print.go.diff
|
||||
46
vendor/github.com/cockroachdb/redact/internal/rfmt/registry.go
generated
vendored
Normal file
46
vendor/github.com/cockroachdb/redact/internal/rfmt/registry.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2020 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package rfmt
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
i "github.com/cockroachdb/redact/interfaces"
|
||||
)
|
||||
|
||||
// RegisterSafeType registers a data type to always be considered safe
|
||||
// during the production of redactable strings.
|
||||
func RegisterSafeType(t reflect.Type) {
|
||||
safeTypeRegistry[t] = true
|
||||
}
|
||||
|
||||
// safeTypeRegistry registers Go data types that are to be always
|
||||
// considered safe, even when they don't implement SafeValue.
|
||||
var safeTypeRegistry = map[reflect.Type]bool{}
|
||||
|
||||
func isSafeValue(a interface{}) bool {
|
||||
return safeTypeRegistry[reflect.TypeOf(a)]
|
||||
}
|
||||
|
||||
// redactErrorFn can be injected from an error library
|
||||
// to render error objects safely.
|
||||
var redactErrorFn func(err error, p i.SafePrinter, verb rune)
|
||||
|
||||
// RegisterRedactErrorFn registers an error redaction function for use
|
||||
// during automatic redaction by this package.
|
||||
// Provided e.g. by cockroachdb/errors.
|
||||
func RegisterRedactErrorFn(fn func(err error, p i.SafePrinter, verb rune)) {
|
||||
redactErrorFn = fn
|
||||
}
|
||||
Reference in New Issue
Block a user