diff --git a/.golangci.yml b/.golangci.yml index 318eb811..f0898565 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -18,15 +18,8 @@ linters: - wastedassign settings: gosec: - includes: - - G102 - - G106 - - G108 - - G109 - - G111 - - G112 - - G201 - - G203 + excludes: + - G115 perfsprint: int-conversion: true err-error: true diff --git a/context.go b/context.go index 059e85a8..112f0ee0 100644 --- a/context.go +++ b/context.go @@ -55,6 +55,14 @@ const ContextRequestKey ContextKeyType = 0 // abortIndex represents a typical value used in abort functions. const abortIndex int8 = math.MaxInt8 >> 1 +// safeInt8 converts int to int8 safely, capping at math.MaxInt8 +func safeInt8(n int) int8 { + if n > math.MaxInt8 { + return math.MaxInt8 + } + return int8(n) +} + // Context is the most important part of gin. It allows us to pass variables between middleware, // manage the flow, validate the JSON of a request and render a JSON response for example. type Context struct { @@ -186,7 +194,7 @@ func (c *Context) FullPath() string { // See example in GitHub. func (c *Context) Next() { c.index++ - for c.index < int8(len(c.handlers)) { + for c.index < safeInt8(len(c.handlers)) { if c.handlers[c.index] != nil { c.handlers[c.index](c) } diff --git a/gin.go b/gin.go index 38361a4b..4d0c7ec0 100644 --- a/gin.go +++ b/gin.go @@ -23,10 +23,12 @@ import ( "golang.org/x/net/http2/h2c" ) -const defaultMultipartMemory = 32 << 20 // 32 MB -const escapedColon = "\\:" -const colon = ":" -const backslash = "\\" +const ( + defaultMultipartMemory = 32 << 20 // 32 MB + escapedColon = "\\:" + colon = ":" + backslash = "\\" +) var ( default404Body = []byte("404 page not found") @@ -46,8 +48,10 @@ var defaultTrustedCIDRs = []*net.IPNet{ }, } -var regSafePrefix = regexp.MustCompile("[^a-zA-Z0-9/-]+") -var regRemoveRepeatedChar = regexp.MustCompile("/{2,}") +var ( + regSafePrefix = regexp.MustCompile("[^a-zA-Z0-9/-]+") + regRemoveRepeatedChar = regexp.MustCompile("/{2,}") +) // HandlerFunc defines the handler used by gin middleware as return value. type HandlerFunc func(*Context) @@ -537,7 +541,11 @@ func (engine *Engine) Run(addr ...string) (err error) { engine.updateRouteTrees() address := resolveAddress(addr) debugPrint("Listening and serving HTTP on %s\n", address) - err = http.ListenAndServe(address, engine.Handler()) + server := &http.Server{ // #nosec G112 + Addr: address, + Handler: engine.Handler(), + } + err = server.ListenAndServe() return } @@ -553,7 +561,11 @@ func (engine *Engine) RunTLS(addr, certFile, keyFile string) (err error) { "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.") } - err = http.ListenAndServeTLS(addr, certFile, keyFile, engine.Handler()) + server := &http.Server{ // #nosec G112 + Addr: addr, + Handler: engine.Handler(), + } + err = server.ListenAndServeTLS(certFile, keyFile) return } @@ -576,7 +588,10 @@ func (engine *Engine) RunUnix(file string) (err error) { defer listener.Close() defer os.Remove(file) - err = http.Serve(listener, engine.Handler()) + server := &http.Server{ // #nosec G112 + Handler: engine.Handler(), + } + err = server.Serve(listener) return } @@ -630,7 +645,10 @@ func (engine *Engine) RunListener(listener net.Listener) (err error) { "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.") } - err = http.Serve(listener, engine.Handler()) + server := &http.Server{ // #nosec G112 + Handler: engine.Handler(), + } + err = server.Serve(listener) return } diff --git a/tree.go b/tree.go index bcc83502..eff07734 100644 --- a/tree.go +++ b/tree.go @@ -5,6 +5,7 @@ package gin import ( + "math" "net/url" "strings" "unicode" @@ -77,14 +78,22 @@ func (n *node) addChild(child *node) { } } +// safeUint16 converts int to uint16 safely, capping at math.MaxUint16 +func safeUint16(n int) uint16 { + if n > math.MaxUint16 { + return math.MaxUint16 + } + return uint16(n) +} + func countParams(path string) uint16 { colons := strings.Count(path, ":") stars := strings.Count(path, "*") - return uint16(colons + stars) + return safeUint16(colons + stars) } func countSections(path string) uint16 { - return uint16(strings.Count(path, "/")) + return safeUint16(strings.Count(path, "/")) } type nodeType uint8