gin/gin_test_issue_4818.go
liuyuyan2717 c7a67900ae fix: reset skippedNodes in HandleMethodNotAllowed loop to prevent panic
Fixes #4818

When HandleMethodNotAllowed is enabled, the handleHTTPRequest method
loops through all method trees calling getValue() with the same
skippedNodes slice. Since getValue() appends to skippedNodes without
clearing it, and the slice cannot grow beyond its initial capacity
(engine.maxSections), accumulated entries from previous iterations
can cause a slice bounds panic when the reslice operation exceeds
capacity.

This fix resets skippedNodes to length 0 before each getValue() call
in the HandleMethodNotAllowed loop, preventing accumulation across
multiple method trees.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-08-29 17:54:34 +08:00

38 lines
957 B
Go

package gin
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestHandleMethodNotAllowedSkippedNodesPanic(t *testing.T) {
SetMode(ReleaseMode)
router := New()
router.HandleMethodNotAllowed = true
h := func(c *Context) {}
router.OPTIONS("/:p0/:p1/a/:p2", h)
router.GET("/:p0/:p1/a/:p2", h)
router.PATCH("/b/:p0/:p1/c", h)
router.DELETE("/b/:p0/:p1/d/:p3", h)
router.GET("/b/:p0/:p1/e/f", h)
router.POST("/b/:p0/:p1/g/:p4/h", h)
router.OPTIONS("/b/:p0/:p1/g/:p4/h", h)
router.DELETE("/b/cache", h)
router.GET("/b/clients/:p1/g", h)
router.POST("/b/clients/:p1/g", h)
router.PATCH("/b/clients/:p1/g/:p4", h)
router.OPTIONS("/b/clients/:p1/g/:p4", h)
req := httptest.NewRequest(http.MethodPost, "/b/clients/42", nil)
w := httptest.NewRecorder()
// This should return 405 Method Not Allowed, not panic
router.ServeHTTP(w, req)
if w.Code != http.StatusMethodNotAllowed {
t.Errorf("Expected status 405, got %d", w.Code)
}
}