From 514a391161d15565e27b36d8da9ecbed6428dbc3 Mon Sep 17 00:00:00 2001 From: Charlie Tonneslan Date: Mon, 18 May 2026 15:25:47 -0400 Subject: [PATCH] Return error from Registry.Get when store.New returns a nil session If a Store's New method returns (nil, err), Registry.Get used to dereference session.name on the nil pointer and panic. Return the error directly when New gives back no session. Fixes #288 Signed-off-by: Charlie Tonneslan --- sessions.go | 3 +++ sessions_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/sessions.go b/sessions.go index c052b28..e08bd70 100644 --- a/sessions.go +++ b/sessions.go @@ -137,6 +137,9 @@ func (s *Registry) Get(store Store, name string) (session *Session, err error) { session, err = info.s, info.e } else { session, err = store.New(s.request, name) + if session == nil { + return nil, err + } session.name = name s.sessions[name] = sessionInfo{s: session, e: err} } diff --git a/sessions_test.go b/sessions_test.go index 9476c22..364a757 100644 --- a/sessions_test.go +++ b/sessions_test.go @@ -7,6 +7,7 @@ package sessions import ( "bytes" "encoding/gob" + "fmt" "net/http" "net/http/httptest" "strings" @@ -214,6 +215,42 @@ func TestCookieStoreMapPanic(t *testing.T) { } } +// failingStore is a Store whose New always returns (nil, err). It exists to +// exercise the nil-session path in Registry.Get without panicking. +type failingStore struct{} + +func (failingStore) Get(*http.Request, string) (*Session, error) { + return nil, fmt.Errorf("get not implemented") +} + +func (failingStore) New(*http.Request, string) (*Session, error) { + return nil, fmt.Errorf("nope") +} + +func (failingStore) Save(*http.Request, http.ResponseWriter, *Session) error { + return nil +} + +func TestRegistry_GetWithFailingStore(t *testing.T) { + req, err := http.NewRequest("GET", "http://example.com", nil) + if err != nil { + t.Fatal(err) + } + reg := GetRegistry(req) + defer func() { + if r := recover(); r != nil { + t.Fatalf("Registry.Get panicked: %v", r) + } + }() + s, err := reg.Get(failingStore{}, "session-name") + if err == nil { + t.Fatal("expected error from failing store, got nil") + } + if s != nil { + t.Fatalf("expected nil session, got %+v", s) + } +} + func init() { gob.Register(FlashMessage{}) }