Go1.13標準庫http包重大bug

2019年11月21日,golang的官方github倉庫提交了一個https://github.com/golang/go/issues/35750,該issue指出如果初始化 http.Server 結構體時指定了一個非空的 ConnContext 成員函數,且如果在該函數內使用了 context.Value 方法寫入數據到上下文並返回,則 Context 將會以鏈表的方式泄漏

據官方開發人員表示,該bug於1.13版本引進,目前已經在1.13.5修復。

ConnContext

ConnContext optionally specifies a function that modifies the context used for a new connection c.

ConnContext是用於更改新連接的context而設置的一個方法。然而,它把新context賦值給了被所有連接共享的一個變量。

代碼如下:

type Server struct {
    ...
	// ConnContext optionally specifies a function that modifies
	// the context used for a new connection c. The provided ctx
	// is derived from the base context and has a ServerContextKey
	// value.
	ConnContext func(ctx context.Context, c net.Conn) context.Context
    ...
}

func (srv *Server) Serve(l net.Listener) error {
        ...
	baseCtx := context.Background()
        ...
	ctx := context.WithValue(baseCtx, ServerContextKey, srv)
	for {
		rw, e := l.Accept()
	        ...
		if cc := srv.ConnContext; cc != nil {
			ctx = cc(ctx, rw)
			if ctx == nil {
				panic("ConnContext returned nil")
			}
		}
                ...
		go c.serve(ctx)
	}
}

問題出在ctx = cc(ctx, rw),這一行錯誤的將cc方法生成的新context賦值給了全局的ctx變量。

修復方式

pull request diff 如下:
pull request

總結
通過此bug來看,對於開源代碼,在使用之前還是應該瞭解其實現細節,即使是github的明星項目(甚至go官方sdk)都不能盲目相信。

參考來源:

  1. https://github.com/golang/go/issues/35750
  2. https://go-review.googlesource.com/c/go/+/208318/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章