Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] runtime error: slice bounds out of range [:2] with capacity 1 #2878

Closed
douglarek opened this issue Sep 22, 2021 · 4 comments
Closed

[BUG] runtime error: slice bounds out of range [:2] with capacity 1 #2878

douglarek opened this issue Sep 22, 2021 · 4 comments
Labels

Comments

@douglarek
Copy link

douglarek commented Sep 22, 2021

  • With issues:
    • Use the search tool before opening a new issue.
    • Please provide source code and commit sha if you found a bug.
    • Review existing issues and provide feedback or react to them.

Description

How to reproduce

package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	r.GET("/:p/a.gif", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.POST("/:p/a.gif", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.GET("/:p/b.gif", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.POST("/:p/b.gif", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.GET("/:p/c.gif", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.POST("/:p/c.gif", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.GET("/:p/all.gif", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.POST("/:p/all.gif", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

Expectations

$ curl -X GET localhost:8080/a/p.gif
404 not found

Actual result

$ curl -X GET localhost:8080/a/p.gif
curl: (52) Empty reply from server

Gin traceback:

[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /:p/a.gif                 --> main.main.func1 (3 handlers)
[GIN-debug] POST   /:p/a.gif                 --> main.main.func2 (3 handlers)
[GIN-debug] GET    /:p/b.gif                 --> main.main.func3 (3 handlers)
[GIN-debug] POST   /:p/b.gif                 --> main.main.func4 (3 handlers)
[GIN-debug] GET    /:p/c.gif                 --> main.main.func5 (3 handlers)
[GIN-debug] POST   /:p/c.gif                 --> main.main.func6 (3 handlers)
[GIN-debug] GET    /:p/all.gif               --> main.main.func7 (3 handlers)
[GIN-debug] POST   /:p/all.gif               --> main.main.func8 (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
2021/09/22 18:27:14 http: panic serving 127.0.0.1:60804: runtime error: slice bounds out of range [:2] with capacity 1
goroutine 20 [running]:
net/http.(*conn).serve.func1()
	/Users/xinlingchao/sdk/go1.17.1/src/net/http/server.go:1801 +0xb9
panic({0x136afa0, 0xc000312240})
	/Users/xinlingchao/sdk/go1.17.1/src/runtime/panic.go:1047 +0x266
github.com/gin-gonic/gin.(*node).getValue(0x600, {0xc00031222c, 0x203000}, 0xc000128840, 0x0)
	/Users/xinlingchao/.go/pkg/mod/github.com/gin-gonic/gin@v1.7.4/tree.go:481 +0xd70
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc000328d00, 0xc0001c0c00)
	/Users/xinlingchao/.go/pkg/mod/github.com/gin-gonic/gin@v1.7.4/gin.go:482 +0x195
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc000328d00, {0x1415bf0, 0xc0003401c0}, 0xc0001c0b00)
	/Users/xinlingchao/.go/pkg/mod/github.com/gin-gonic/gin@v1.7.4/gin.go:445 +0x1c5
net/http.serverHandler.ServeHTTP({0xc0003440f0}, {0x1415bf0, 0xc0003401c0}, 0xc0001c0b00)
	/Users/xinlingchao/sdk/go1.17.1/src/net/http/server.go:2878 +0x43b
net/http.(*conn).serve(0xc00031ae60, {0x1418be0, 0xc000344000})
	/Users/xinlingchao/sdk/go1.17.1/src/net/http/server.go:1929 +0xb08
created by net/http.(*Server).Serve
	/Users/xinlingchao/sdk/go1.17.1/src/net/http/server.go:3033 +0x4e8

Environment

  • go version: 1.17.1
  • gin version (or commit ref): 1.7.4
  • operating system: Mac 0S 11.6
@handsomedeveloper
Copy link

Is it resolved?
I have the same problem.

@jjba23
Copy link
Contributor

jjba23 commented Sep 27, 2021

I too am having the same issue, in my case with server.go:3159: http: panic serving 127.0.0.1:53599: runtime error: slice bounds out of range [:6] with capacity 5.
Strangely, the issue only occurs on routes that have a dash in them, as an example /:locale/blog-news fails, but /:locale/careers works perfectly fine.

As an update, interestingly, reverting back to gin 1.7.2 resolves the issue both on Go 1.16 and Go 1.17

This only happens in macOS machines, as far as I can see since the bug is not present in my FreeBSD and Ubuntu servers.

@apvail
Copy link

apvail commented Oct 14, 2021

I too am having the same issue, in my case with server.go:3159: http: panic serving 127.0.0.1:53599: runtime error: slice bounds out of range [:6] with capacity 5. Strangely, the issue only occurs on routes that have a dash in them, as an example /:locale/blog-news fails, but /:locale/careers works perfectly fine.

As an update, interestingly, reverting back to gin 1.7.2 resolves the issue both on Go 1.16 and Go 1.17

This only happens in macOS machines, as far as I can see since the bug is not present in my FreeBSD and Ubuntu servers.

I am also seeing this issue when upgrading from gin 1.7.2 to 1.7.4 (it is also present in 1.7.3). Unlike @averageflow I am not seeing any differences in operating systems. Definitely seeing it on multiple operating systems. Ubuntu, MacOS, and centos (in a docker container) all have the same issue.

Similar to the original post, I can trigger it with the following

package main

import (
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	r.GET("/A/:paramOne/B", func(c *gin.Context) { c.String(200, "OK") })
	r.GET("/A/:paramOne/C", func(c *gin.Context) { c.String(200, "OK") })

	r.Run()
}
curl -Ss -X GET http://127.0.0.1:8080/A/mockParam/NOPE
2021/10/14 16:05:25 http: panic serving 127.0.0.1:37742: runtime error: slice bounds out of range [:2] with capacity 1
goroutine 36 [running]:
net/http.(*conn).serve.func1()
        /home/MYUSER/.gvm/gos/go1.17/src/net/http/server.go:1801 +0xb9
panic({0x763680, 0xc000412138})
        /home/MYUSER/.gvm/gos/go1.17/src/runtime/panic.go:1047 +0x266
github.com/gin-gonic/gin.(*node).getValue(0xc000439810, {0xc0004261e4, 0x11}, 0xc000416198, 0x0)
        /home/MYUSER/code/gin/tree.go:533 +0x288d
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc00044a340, 0xc000414200)
        /home/MYUSER/code/gin/gin.go:542 +0x195
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc00044a340, {0x8129f0, 0xc00045a380}, 0xc000414400)
        /home/MYUSER/code/gin/gin.go:505 +0x1c5
net/http.serverHandler.ServeHTTP({0xc000402d80}, {0x8129f0, 0xc00045a380}, 0xc000414400)
        /home/MYUSER/.gvm/gos/go1.17/src/net/http/server.go:2878 +0x43b
net/http.(*conn).serve(0xc000420780, {0x8155a0, 0xc000402a50})
        /home/MYUSER/.gvm/gos/go1.17/src/net/http/server.go:1929 +0xb08
created by net/http.(*Server).Serve
        /home/MYUSER/.gvm/gos/go1.17/src/net/http/server.go:3033 +0x4e8

That's as small as I've been able to get it. You seem to need to have two or more routes with partial shared paths that include at least one param. Did a little digging while trying to figure this all out. I don't fully understand the routing code, but seems to be because the big loop in tree.go is running infinitely and will eventually overcome the capacity of the params slice it is expanding and throw this panic.

There was a case which I could reproduce in my actual code (which I'm not allowed to share) which caused the loop to run infinitely and not fill anything in the params slice. It just kept looping with no sign of stopping. I let it run for like a minute or something. But I cannot seem to get that to happen with this minimal example I've posted.

@appleboy appleboy added the bug label Oct 15, 2021
@appleboy
Copy link
Member

See solution #2897 already merged in the master branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants