andygrunwald / andygrunwald/go-jira

Nil pointer panic in GetWatchersWithContext when watchers lack AccountID

Đang mở
#743 1 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Go
Star
1.6k
Fork
500
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

## Description

`IssueService.GetWatchersWithContext()` panics with a nil pointer dereference when processing watchers that don't have an `AccountID` field. This commonly occurs with legacy Jira Server installations or watchers migrated from older Jira versions.

## Version

- **go-jira version**: v1.17.0 (bug also exists in v1.12.0)
- **Go version**: go1.25.4
- **Jira**: Cloud/Server (any version with legacy watchers)

## Steps to Reproduce

1. Call `GetWatchersWithContext()` on an issue that has watchers without `AccountID`
2. Observe panic

### Minimal Reproducible Example

```go
package main

import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"

jira "github.com/andygrunwald/go-jira"
)

func main() {
// Mock server returns watcher without AccountID (legacy format)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/rest/api/2/issue/TEST-123/watchers" {
response := map[string]interface{}{
"self": "https://example.atlassian.net/rest/api/2/issue/TEST-123/watchers",
"watchCount": 1,
"watchers": []map[string]interface{}{
{
"name": "olduser",
"displayName": "Old User",
"active": true,
// No accountId field
},
},
}
json.NewEncoder(w).Encode(response)
return
}
http.NotFound(w, r)
}))
defer server.Close()

client, _ := jira.NewClient(server.Client(), server.URL)

// This panics:
_, _, _ = client.Issue.GetWatchersWithContext(context.Background(), "TEST-123")
}
```

## Expected Behavior

The function should either:
- Skip watchers without `AccountID` gracefully, or
- Return an error, or
- Return the watcher data available (name, displayName)

## Actual Behavior

```
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x756eb3]

goroutine 1 [running]:
github.com/andygrunwald/go-jira.(*IssueService).GetWatchersWithContext(...)
.../go-jira@v1.17.0/issue.go:1575
```

## Root Cause

In `issue.go` at line ~1575:

```go
func (s *IssueService) GetWatchersWithContext(ctx context.Context, issueID string) (*[]User, *Response, error) {
// ...
result := []User{}
for _, watcher := range watches.Watchers {
var user *User
if watcher.AccountID != "" {
user, resp, err = s.client.User.GetByAccountID(watcher.AccountID)
if err != nil {
return nil, resp, NewJiraError(resp, err)
}
}
result = append(result, *user) // ← PANIC: user is nil if AccountID is empty
}
return &result, resp, nil
}
```

When `watcher.AccountID` is empty, `user` remains `nil`, and dereferencing `*user` causes a panic.

## Suggested Fix

### Option 1: Skip watchers without AccountID

```go
for _, watcher := range watches.Watchers {
if watcher.AccountID == "" {
continue // Skip legacy watchers
}
user, resp, err := s.client.User.GetByAccountID(watcher.AccountID)
if err != nil {
return nil, resp, NewJiraError(resp, err)
}
if user != nil {
result = append(result, *user)
}
}
```

### Option 2: Handle both legacy and modern formats

```go
for _, watcher := range watches.Watchers {
var user *User
var err error

if watcher.AccountID != "" {
user, resp, err = s.client.User.GetByAccountID(watcher.AccountID)
if err != nil {
return nil, resp, NewJiraError(resp, err)
}
} else if watcher.Name != "" {
// Fallback for legacy watchers - use watcher data directly
user = &User{
Name: watcher.Name,
DisplayName: watcher.DisplayName,
Active: watcher.Active,
}
}

if user != nil {
result = append(result, *user)
}
}
```

## Additional Context

This issue affects environments with:
- Legacy Jira Server installations
- Migrated Jira Cloud instances with old watchers
- Any scenario where watchers were added before AccountID became mandatory

Probably related: https://github.com/andygrunwald/go-jira/issues/272

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.