fix nil panic in AddToList()

This commit is contained in:
kim 2024-09-11 23:30:36 +01:00
commit af1be28c2b
2 changed files with 34 additions and 6 deletions

View file

@ -52,8 +52,8 @@ func (p *Processor) AddToList(ctx context.Context, account *gtsmodel.Account, li
return gtserror.NewErrorInternalError(err)
}
// Convert the follows to a map keyed by the target account ID.
followsMap := util.KeyBy(follows, func(follow *gtsmodel.Follow) string {
// Convert the follows to a hash set containing the target account IDs.
inFollows := util.ToSetFunc(follows, func(follow *gtsmodel.Follow) string {
return follow.TargetAccountID
})
@ -65,14 +65,30 @@ func (p *Processor) AddToList(ctx context.Context, account *gtsmodel.Account, li
// Iterate all the account IDs in given target list.
for _, targetAccountID := range targetAccountIDs {
// Look for existing follow targetting ID.
follow, ok := followsMap[targetAccountID]
if ok {
// Look for follow to target account.
if inFollows.Has(targetAccountID) {
text := fmt.Sprintf("account %s is already in list %s", targetAccountID, listID)
return gtserror.NewErrorUnprocessableEntity(errors.New(text), text)
}
// Get the actual follow to target.
follow, err := p.state.DB.GetFollow(
// We don't need any sub-models.
gtscontext.SetBarebones(ctx),
account.ID,
targetAccountID,
)
if err != nil && !errors.Is(err, db.ErrNoEntries) {
err := gtserror.Newf("db error getting follow: %w", err)
return gtserror.NewErrorInternalError(err)
}
if follow == nil {
text := fmt.Sprintf("account %s not currently followed", targetAccountID)
return gtserror.NewErrorUnprocessableEntity(errors.New(text), text)
}
// Generate new entry for this follow in list.
entries = append(entries, &gtsmodel.ListEntry{
ID: id.NewULID(),

View file

@ -42,6 +42,18 @@ func ToSet[T comparable](in []T) Set[T] {
return set
}
// ToSetFunc creates a Set[T] from input slice, keys provided by func.
func ToSetFunc[S any, T comparable](in []S, key func(S) T) Set[T] {
if key == nil {
panic("nil func")
}
set := make(Set[T], len(in))
for _, v := range in {
set[key(v)] = struct{}{}
}
return set
}
// FromSet extracts the values from set to slice.
func FromSet[T comparable](in Set[T]) []T {
out := make([]T, len(in))