Documentation
¶
Overview ¶
Example (Mixed_writes) ¶
testCases := []struct {
startMode, endMode OutputMode
}{
{UnsafeEscaped, SafeEscaped},
{SafeEscaped, UnsafeEscaped},
{UnsafeEscaped, SafeRaw},
{SafeRaw, UnsafeEscaped},
{SafeEscaped, SafeRaw},
{SafeRaw, SafeEscaped},
}
doWritesFn := []func(*Buffer){
// Noop
func(b *Buffer) {},
func(b *Buffer) { b.WriteByte('a') },
func(b *Buffer) { b.WriteRune('a') },
func(b *Buffer) { b.WriteString("hello\nworld") },
func(b *Buffer) { b.Write([]byte("hello\nworld")) },
func(b *Buffer) { b.WriteString("safe‹unsafe›") },
}
for i, tc := range testCases {
if i > 0 {
fmt.Println()
}
fmt.Println(tc.startMode, " -> ", tc.endMode)
for j, doWrites := range doWritesFn {
var b Buffer
b.SetMode(tc.startMode)
doWrites(&b)
for k, doWrites2 := range doWritesFn {
copy := b
copy.SetMode(tc.endMode)
doWrites2(©)
fmt.Printf("fn%d+fn%d: %q\n", j, k, copy.RedactableString())
}
}
}
Output: 0 -> 1 fn0+fn0: "" fn0+fn1: "a" fn0+fn2: "a" fn0+fn3: "hello\nworld" fn0+fn4: "hello\nworld" fn0+fn5: "safe?unsafe?" fn1+fn0: "‹a›" fn1+fn1: "‹a›a" fn1+fn2: "‹a›a" fn1+fn3: "‹a›hello\nworld" fn1+fn4: "‹a›hello\nworld" fn1+fn5: "‹a›safe?unsafe?" fn2+fn0: "‹a›" fn2+fn1: "‹a›a" fn2+fn2: "‹a›a" fn2+fn3: "‹a›hello\nworld" fn2+fn4: "‹a›hello\nworld" fn2+fn5: "‹a›safe?unsafe?" fn3+fn0: "‹hello›\n‹world›" fn3+fn1: "‹hello›\n‹world›a" fn3+fn2: "‹hello›\n‹world›a" fn3+fn3: "‹hello›\n‹world›hello\nworld" fn3+fn4: "‹hello›\n‹world›hello\nworld" fn3+fn5: "‹hello›\n‹world›safe?unsafe?" fn4+fn0: "‹hello›\n‹world›" fn4+fn1: "‹hello›\n‹world›a" fn4+fn2: "‹hello›\n‹world›a" fn4+fn3: "‹hello›\n‹world›hello\nworld" fn4+fn4: "‹hello›\n‹world›hello\nworld" fn4+fn5: "‹hello›\n‹world›safe?unsafe?" fn5+fn0: "‹safe?unsafe?›" fn5+fn1: "‹safe?unsafe?›a" fn5+fn2: "‹safe?unsafe?›a" fn5+fn3: "‹safe?unsafe?›hello\nworld" fn5+fn4: "‹safe?unsafe?›hello\nworld" fn5+fn5: "‹safe?unsafe?›safe?unsafe?" 1 -> 0 fn0+fn0: "" fn0+fn1: "‹a›" fn0+fn2: "‹a›" fn0+fn3: "‹hello›\n‹world›" fn0+fn4: "‹hello›\n‹world›" fn0+fn5: "‹safe?unsafe?›" fn1+fn0: "a" fn1+fn1: "a‹a›" fn1+fn2: "a‹a›" fn1+fn3: "a‹hello›\n‹world›" fn1+fn4: "a‹hello›\n‹world›" fn1+fn5: "a‹safe?unsafe?›" fn2+fn0: "a" fn2+fn1: "a‹a›" fn2+fn2: "a‹a›" fn2+fn3: "a‹hello›\n‹world›" fn2+fn4: "a‹hello›\n‹world›" fn2+fn5: "a‹safe?unsafe?›" fn3+fn0: "hello\nworld" fn3+fn1: "hello\nworld‹a›" fn3+fn2: "hello\nworld‹a›" fn3+fn3: "hello\nworld‹hello›\n‹world›" fn3+fn4: "hello\nworld‹hello›\n‹world›" fn3+fn5: "hello\nworld‹safe?unsafe?›" fn4+fn0: "hello\nworld" fn4+fn1: "hello\nworld‹a›" fn4+fn2: "hello\nworld‹a›" fn4+fn3: "hello\nworld‹hello›\n‹world›" fn4+fn4: "hello\nworld‹hello›\n‹world›" fn4+fn5: "hello\nworld‹safe?unsafe?›" fn5+fn0: "safe?unsafe?" fn5+fn1: "safe?unsafe?‹a›" fn5+fn2: "safe?unsafe?‹a›" fn5+fn3: "safe?unsafe?‹hello›\n‹world›" fn5+fn4: "safe?unsafe?‹hello›\n‹world›" fn5+fn5: "safe?unsafe?‹safe?unsafe?›" 0 -> 2 fn0+fn0: "" fn0+fn1: "a" fn0+fn2: "a" fn0+fn3: "hello\nworld" fn0+fn4: "hello\nworld" fn0+fn5: "safe‹unsafe›" fn1+fn0: "‹a›" fn1+fn1: "‹a›a" fn1+fn2: "‹a›a" fn1+fn3: "‹a›hello\nworld" fn1+fn4: "‹a›hello\nworld" fn1+fn5: "‹a›safe‹unsafe›" fn2+fn0: "‹a›" fn2+fn1: "‹a›a" fn2+fn2: "‹a›a" fn2+fn3: "‹a›hello\nworld" fn2+fn4: "‹a›hello\nworld" fn2+fn5: "‹a›safe‹unsafe›" fn3+fn0: "‹hello›\n‹world›" fn3+fn1: "‹hello›\n‹world›a" fn3+fn2: "‹hello›\n‹world›a" fn3+fn3: "‹hello›\n‹world›hello\nworld" fn3+fn4: "‹hello›\n‹world›hello\nworld" fn3+fn5: "‹hello›\n‹world›safe‹unsafe›" fn4+fn0: "‹hello›\n‹world›" fn4+fn1: "‹hello›\n‹world›a" fn4+fn2: "‹hello›\n‹world›a" fn4+fn3: "‹hello›\n‹world›hello\nworld" fn4+fn4: "‹hello›\n‹world›hello\nworld" fn4+fn5: "‹hello›\n‹world›safe‹unsafe›" fn5+fn0: "‹safe?unsafe?›" fn5+fn1: "‹safe?unsafe?›a" fn5+fn2: "‹safe?unsafe?›a" fn5+fn3: "‹safe?unsafe?›hello\nworld" fn5+fn4: "‹safe?unsafe?›hello\nworld" fn5+fn5: "‹safe?unsafe?›safe‹unsafe›" 2 -> 0 fn0+fn0: "" fn0+fn1: "‹a›" fn0+fn2: "‹a›" fn0+fn3: "‹hello›\n‹world›" fn0+fn4: "‹hello›\n‹world›" fn0+fn5: "‹safe?unsafe?›" fn1+fn0: "a" fn1+fn1: "a‹a›" fn1+fn2: "a‹a›" fn1+fn3: "a‹hello›\n‹world›" fn1+fn4: "a‹hello›\n‹world›" fn1+fn5: "a‹safe?unsafe?›" fn2+fn0: "a" fn2+fn1: "a‹a›" fn2+fn2: "a‹a›" fn2+fn3: "a‹hello›\n‹world›" fn2+fn4: "a‹hello›\n‹world›" fn2+fn5: "a‹safe?unsafe?›" fn3+fn0: "hello\nworld" fn3+fn1: "hello\nworld‹a›" fn3+fn2: "hello\nworld‹a›" fn3+fn3: "hello\nworld‹hello›\n‹world›" fn3+fn4: "hello\nworld‹hello›\n‹world›" fn3+fn5: "hello\nworld‹safe?unsafe?›" fn4+fn0: "hello\nworld" fn4+fn1: "hello\nworld‹a›" fn4+fn2: "hello\nworld‹a›" fn4+fn3: "hello\nworld‹hello›\n‹world›" fn4+fn4: "hello\nworld‹hello›\n‹world›" fn4+fn5: "hello\nworld‹safe?unsafe?›" fn5+fn0: "safe‹unsafe›" fn5+fn1: "safe‹unsafe›‹a›" fn5+fn2: "safe‹unsafe›‹a›" fn5+fn3: "safe‹unsafe›‹hello›\n‹world›" fn5+fn4: "safe‹unsafe›‹hello›\n‹world›" fn5+fn5: "safe‹unsafe›‹safe?unsafe?›" 1 -> 2 fn0+fn0: "" fn0+fn1: "a" fn0+fn2: "a" fn0+fn3: "hello\nworld" fn0+fn4: "hello\nworld" fn0+fn5: "safe‹unsafe›" fn1+fn0: "a" fn1+fn1: "aa" fn1+fn2: "aa" fn1+fn3: "ahello\nworld" fn1+fn4: "ahello\nworld" fn1+fn5: "asafe‹unsafe›" fn2+fn0: "a" fn2+fn1: "aa" fn2+fn2: "aa" fn2+fn3: "ahello\nworld" fn2+fn4: "ahello\nworld" fn2+fn5: "asafe‹unsafe›" fn3+fn0: "hello\nworld" fn3+fn1: "hello\nworlda" fn3+fn2: "hello\nworlda" fn3+fn3: "hello\nworldhello\nworld" fn3+fn4: "hello\nworldhello\nworld" fn3+fn5: "hello\nworldsafe‹unsafe›" fn4+fn0: "hello\nworld" fn4+fn1: "hello\nworlda" fn4+fn2: "hello\nworlda" fn4+fn3: "hello\nworldhello\nworld" fn4+fn4: "hello\nworldhello\nworld" fn4+fn5: "hello\nworldsafe‹unsafe›" fn5+fn0: "safe?unsafe?" fn5+fn1: "safe?unsafe?a" fn5+fn2: "safe?unsafe?a" fn5+fn3: "safe?unsafe?hello\nworld" fn5+fn4: "safe?unsafe?hello\nworld" fn5+fn5: "safe?unsafe?safe‹unsafe›" 2 -> 1 fn0+fn0: "" fn0+fn1: "a" fn0+fn2: "a" fn0+fn3: "hello\nworld" fn0+fn4: "hello\nworld" fn0+fn5: "safe?unsafe?" fn1+fn0: "a" fn1+fn1: "aa" fn1+fn2: "aa" fn1+fn3: "ahello\nworld" fn1+fn4: "ahello\nworld" fn1+fn5: "asafe?unsafe?" fn2+fn0: "a" fn2+fn1: "aa" fn2+fn2: "aa" fn2+fn3: "ahello\nworld" fn2+fn4: "ahello\nworld" fn2+fn5: "asafe?unsafe?" fn3+fn0: "hello\nworld" fn3+fn1: "hello\nworlda" fn3+fn2: "hello\nworlda" fn3+fn3: "hello\nworldhello\nworld" fn3+fn4: "hello\nworldhello\nworld" fn3+fn5: "hello\nworldsafe?unsafe?" fn4+fn0: "hello\nworld" fn4+fn1: "hello\nworlda" fn4+fn2: "hello\nworlda" fn4+fn3: "hello\nworldhello\nworld" fn4+fn4: "hello\nworldhello\nworld" fn4+fn5: "hello\nworldsafe?unsafe?" fn5+fn0: "safe‹unsafe›" fn5+fn1: "safe‹unsafe›a" fn5+fn2: "safe‹unsafe›a" fn5+fn3: "safe‹unsafe›hello\nworld" fn5+fn4: "safe‹unsafe›hello\nworld" fn5+fn5: "safe‹unsafe›safe?unsafe?"
Index ¶
- Variables
- type Buffer
- func (b *Buffer) Cap() int
- func (b *Buffer) GetMode() OutputMode
- func (b *Buffer) Grow(n int)
- func (b *Buffer) Len() int
- func (b Buffer) RedactableBytes() m.RedactableBytes
- func (b Buffer) RedactableString() m.RedactableString
- func (b *Buffer) Reset()
- func (b *Buffer) SetMode(newMode OutputMode)
- func (b Buffer) String() string
- func (b *Buffer) TakeRedactableBytes() m.RedactableBytes
- func (b *Buffer) TakeRedactableString() m.RedactableString
- func (b *Buffer) Write(p []byte) (n int, err error)
- func (b *Buffer) WriteByte(s byte) error
- func (b *Buffer) WriteRune(s rune) error
- func (b *Buffer) WriteString(s string) (n int, err error)
- type OutputMode
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrTooLarge = origFmt.Errorf("redact.Buffer: too large")
ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer.
Functions ¶
This section is empty.
Types ¶
type Buffer ¶
type Buffer struct {
// contains filtered or unexported fields
}
Buffer is a variable-sized buffer of bytes with a Write method. Writes are escaped in different ways depending on the output mode.
func (*Buffer) Cap ¶
Cap returns the capacity of the buffer's underlying byte slice, that is, the total space allocated for the buffer's data.
func (*Buffer) Grow ¶
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 (Buffer) RedactableBytes ¶
func (b Buffer) RedactableBytes() m.RedactableBytes
RedactableBytes returns the bytes in the buffer.
func (Buffer) RedactableString ¶
func (b Buffer) RedactableString() m.RedactableString
RedactableString returns the bytes in the buffer.
func (*Buffer) Reset ¶
func (b *Buffer) Reset()
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 (*Buffer) SetMode ¶
func (b *Buffer) SetMode(newMode OutputMode)
SetMode changes the output mode.
func (*Buffer) TakeRedactableBytes ¶
func (b *Buffer) TakeRedactableBytes() m.RedactableBytes
TakeRedactableBytes returns the buffer contents and reinitializes the buffer. This saves a memory allocation compared to RedactableBytes().
func (*Buffer) TakeRedactableString ¶
func (b *Buffer) TakeRedactableString() m.RedactableString
TakeRedactableString returns the buffer contents and reinitializes the buffer. This saves a memory allocation compared to RedactableString().
func (*Buffer) Write ¶
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 (*Buffer) WriteString ¶
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.
type OutputMode ¶
type OutputMode int
OutputMode determines how writes are processed in the Buffer.
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 )