此代码可能泄漏内存中变量的值
我认为fmt.XprintY
可能不会重置缓冲区,但是我的调试尝试是徒劳的。
package main
import (
"bytes"
"fmt"
"io"
"text/template"
)
type SecWriter struct {
w io.Writer
}
func (s *SecWriter) Write(p []byte) (n int, err error) {
fmt.Println(string(p), len(p), cap(p))
// here
tmp := fmt.Sprintln("info{SSSSSSSSSSSSSSSSSSSSSSSSSSS}")
if tmp == ""{}
s.w.Write(p[:64])
return 64, nil
}
func index() {
exp := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA{{1}}"
b := &bytes.Buffer{}
s := &SecWriter{
w: b,
}
t := template.Must(template.New("index").Parse(exp))
t.Execute(s, nil)
fmt.Println("buf: ", b.String())
}
func main() {
index()
}
我的环境:
set GOARCH=amd64
set GOOS=windows
go版本
go version go1.12.5 windows/amd64
输出是
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 64 64
1 1 128
buf: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1nfo{SSSSSSSSSSSSSSSSSSSSSSSSSSS} AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
如您所见,内存中变量的值泄漏到缓冲区中
在Go中,表达式s.w.Write(p[:64])
可以将切片扩展到其长度以上而没有错误(直到切片的容量)。在这种情况下,提供的缓冲区长度仅为1,但是您将其扩展为64(如输出的第二行所示)。额外的63个字节中的内容是未定义的,并且碰巧是某些fmt
方法的输出。
解决方案是检查切片的长度。如果要使切片变得万无一失,并确保无法看到超出其长度的内容,则可以对切片使用三个索引语法来设置其容量,例如p = p[::len(p)]
。