Harden stub manager nil receivers
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run

This commit is contained in:
Snider 2026-04-18 08:32:45 +01:00
parent 6f9285a48d
commit a39edfde83
6 changed files with 64 additions and 0 deletions

View file

@ -18,6 +18,9 @@ type BrowserManager struct {
// manager.OpenURL("https://lthn.io")
// _ = manager.LastURL // "https://lthn.io"
func (bm *BrowserManager) OpenURL(url string) error {
if bm == nil {
return nil
}
bm.mu.Lock()
bm.LastURL = url
bm.mu.Unlock()
@ -29,6 +32,9 @@ func (bm *BrowserManager) OpenURL(url string) error {
// manager.OpenFile("/home/user/report.pdf")
// _ = manager.LastFile // "/home/user/report.pdf"
func (bm *BrowserManager) OpenFile(path string) error {
if bm == nil {
return nil
}
bm.mu.Lock()
bm.LastFile = path
bm.mu.Unlock()

View file

@ -59,3 +59,12 @@ func TestBrowserManager_OpenFile_Ugly(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "/tmp/\x00report.txt", manager.LastFile)
}
func TestBrowserManager_NilReceiver_IsSafe(t *testing.T) {
var manager *BrowserManager
assert.NotPanics(t, func() {
assert.NoError(t, manager.OpenURL("https://example.com"))
assert.NoError(t, manager.OpenFile("/tmp/report.txt"))
})
}

View file

@ -17,6 +17,9 @@ type Clipboard struct {
//
// cb.SetText("copied content")
func (c *Clipboard) SetText(text string) bool {
if c == nil {
return false
}
c.mu.Lock()
c.text = text
c.set = true
@ -29,6 +32,9 @@ func (c *Clipboard) SetText(text string) bool {
// text, ok := cb.Text()
// if !ok { text = "" }
func (c *Clipboard) Text() (string, bool) {
if c == nil {
return "", false
}
c.mu.RLock()
defer c.mu.RUnlock()
return c.text, c.set
@ -48,6 +54,9 @@ type ClipboardManager struct {
//
// manager.SetText("some text")
func (cm *ClipboardManager) SetText(text string) bool {
if cm == nil {
return false
}
return cm.getClipboard().SetText(text)
}
@ -55,11 +64,17 @@ func (cm *ClipboardManager) SetText(text string) bool {
//
// text, ok := manager.Text()
func (cm *ClipboardManager) Text() (string, bool) {
if cm == nil {
return "", false
}
return cm.getClipboard().Text()
}
// getClipboard returns the clipboard instance, creating it if needed.
func (cm *ClipboardManager) getClipboard() *Clipboard {
if cm == nil {
return &Clipboard{}
}
cm.mu.Lock()
defer cm.mu.Unlock()
if cm.clipboard == nil {

View file

@ -71,3 +71,14 @@ func TestClipboardManager_Text_Ugly(t *testing.T) {
assert.True(t, present)
assert.Equal(t, raw, text)
}
func TestClipboardManager_NilReceiver_IsSafe(t *testing.T) {
var manager *ClipboardManager
assert.NotPanics(t, func() {
assert.False(t, manager.SetText("hello"))
text, present := manager.Text()
assert.Empty(t, text)
assert.False(t, present)
})
}

View file

@ -23,6 +23,9 @@ type KeyBindingManager struct {
//
// manager.Add("CmdOrCtrl+Shift+P", func(w Window) { launchCommandPalette(w) })
func (m *KeyBindingManager) Add(accelerator string, callback func(window Window)) {
if m == nil {
return
}
m.mu.Lock()
defer m.mu.Unlock()
if m.bindings == nil {
@ -35,6 +38,9 @@ func (m *KeyBindingManager) Add(accelerator string, callback func(window Window)
//
// manager.Remove("CmdOrCtrl+Shift+P")
func (m *KeyBindingManager) Remove(accelerator string) {
if m == nil {
return
}
m.mu.Lock()
defer m.mu.Unlock()
delete(m.bindings, accelerator)
@ -44,6 +50,9 @@ func (m *KeyBindingManager) Remove(accelerator string) {
//
// if manager.Process("CmdOrCtrl+K", window) { return }
func (m *KeyBindingManager) Process(accelerator string, window Window) (handled bool) {
if m == nil {
return false
}
m.mu.RLock()
callback, exists := m.bindings[accelerator]
m.mu.RUnlock()
@ -64,6 +73,9 @@ func (m *KeyBindingManager) Process(accelerator string, window Window) (handled
//
// for _, kb := range manager.GetAll() { log(kb.Accelerator) }
func (m *KeyBindingManager) GetAll() []*KeyBinding {
if m == nil {
return nil
}
m.mu.RLock()
defer m.mu.RUnlock()
bindings := make([]*KeyBinding, 0, len(m.bindings))

View file

@ -79,3 +79,14 @@ func TestKeyBindingManager_Remove_Ugly(t *testing.T) {
assert.Empty(t, manager.GetAll())
}
func TestKeyBindingManager_NilReceiver_IsSafe(t *testing.T) {
var manager *KeyBindingManager
assert.NotPanics(t, func() {
manager.Add("CmdOrCtrl+K", func(Window) {})
manager.Remove("CmdOrCtrl+K")
assert.False(t, manager.Process("CmdOrCtrl+K", nil))
assert.Nil(t, manager.GetAll())
})
}