From 3472f6371bf852d5cc04c279dacf3f1259bfc8c8 Mon Sep 17 00:00:00 2001 From: "Madhan Raj Mookkandy (from Dev Box)" Date: Sun, 15 Feb 2026 18:31:00 -0800 Subject: [PATCH] fix: add nil guards to prevent panic in tags package AddTag, AddTagValue, and DeleteTag all dereference the tags pointer without checking for nil. When callers pass nil *common.Tags (e.g., wssdcloudagent/virtualmachineimage/client.go:953 during VM Create), the functions panic with nil pointer dereference. Production telemetry (HostOsPanicLogs, 30-day window) shows 4 panics at tags.go:58 (AddTagValue) across 2 devices. Fix: Add nil guard at the top of AddTag, AddTagValue, and DeleteTag. GetTagValue already handles nil safely via GetTags() proto accessor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- pkg/tags/tags.go | 9 +++++++++ pkg/tags/tags_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/pkg/tags/tags.go b/pkg/tags/tags.go index 0be0ed85..655727ad 100644 --- a/pkg/tags/tags.go +++ b/pkg/tags/tags.go @@ -17,11 +17,17 @@ func InitTag(key, value string) *common.Tag { // AddTag func AddTag(key, value string, tags *common.Tags) { + if tags == nil { + return + } tags.Tags = append(tags.GetTags(), InitTag(key, value)) } // DeleteTag func DeleteTag(key string, tags *common.Tags) { + if tags == nil { + return + } index := -1 tagsList := tags.GetTags() for idx, tag := range tagsList { @@ -49,6 +55,9 @@ func GetTagValue(key string, tags *common.Tags) (string, error) { // AddTagValue func AddTagValue(key, value string, tags *common.Tags) { + if tags == nil { + return + } for _, tag := range tags.GetTags() { if tag.GetKey() == key { tag.Value = value diff --git a/pkg/tags/tags_test.go b/pkg/tags/tags_test.go index 504f46d2..a497f797 100644 --- a/pkg/tags/tags_test.go +++ b/pkg/tags/tags_test.go @@ -102,6 +102,32 @@ func TestAddTagValue(t *testing.T) { t.Logf("%s", value) } +func TestAddTagNilTags(t *testing.T) { + // Verify AddTag does not panic when tags is nil + AddTag("testkey", "testvalue", nil) +} + +func TestAddTagValueNilTags(t *testing.T) { + // Verify AddTagValue does not panic when tags is nil + AddTagValue("testkey", "testvalue", nil) +} + +func TestDeleteTagNilTags(t *testing.T) { + // Verify DeleteTag does not panic when tags is nil + DeleteTag("testkey", nil) +} + +func TestGetTagValueNilTags(t *testing.T) { + // GetTagValue should return NotFound for nil tags + _, err := GetTagValue("testkey", nil) + if err == nil { + t.Errorf("Expected error for nil tags") + } + if !errors.IsNotFound(err) { + t.Errorf("Expected NotFound error for nil tags") + } +} + func TestProtoToMap(t *testing.T) { tags := &common.Tags{} AddTagValue("testkey", "testvalue", tags)