summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-07-14 20:22:14 -0500
committerChristian Cleberg <[email protected]>2026-07-14 20:22:14 -0500
commit8a00f7c55cdbcddcd878c01a79f2db7dc3f080ef (patch)
treefe4c4ef1188986fd3676253048c3014e4de86d07
parent0fdc45a668d95d603a9013f90392f6bc966c72f9 (diff)
downloadskunky-art-8a00f7c55cdbcddcd878c01a79f2db7dc3f080ef.tar.gz
skunky-art-8a00f7c55cdbcddcd878c01a79f2db7dc3f080ef.tar.bz2
skunky-art-8a00f7c55cdbcddcd878c01a79f2db7dc3f080ef.zip
fix(api): harden random-art retry loop
Three bugs in Random(): - The retry loop was unbounded. Only the NSFW path incremented attempt, so a run of DeviantArt errors span forever, hammering the API and risking an egress-IP ban. - string(rand.Intn(999)) converts a rune, not a number: string(65) is "A", not "65". Searches were querying garbage. Use strconv.Itoa. - rand.Intn panics on 0, so an empty result set crashed the handler. Skip empty results. The exhausted-retries error now fires when the loop ends rather than falling through to index an empty slice.
-rwxr-xr-xapp/api.go22
1 files changed, 15 insertions, 7 deletions
diff --git a/app/api.go b/app/api.go
index cd574b8..0398d3c 100755
--- a/app/api.go
+++ b/app/api.go
@@ -3,6 +3,7 @@ package app
import (
"encoding/json"
"math/rand"
+ "strconv"
"strings"
"github.com/zerolabsco/devianter"
@@ -58,25 +59,32 @@ func (a API) sendMedia(d *devianter.Deviation) {
// TODO: сделать фильтры
func (a API) Random() {
- for attempt := 1; ; {
- if attempt > 3 {
- a.Error("Sorry, butt NSFW on this are disabled, and the instance failed to find a random art without NSFW", 500)
- }
+ // Bounded retries: the loop used to be unbounded, and the DeviantArt-error
+ // path never incremented attempt, so a single request could spin forever
+ // hammering the API (and get this instance's egress IP banned).
+ const maxAttempts = 3
- s, daErr, err := devianter.PerformSearch(string(rand.Intn(999)), rand.Intn(30), 'a')
+ for attempt := 0; attempt < maxAttempts; attempt++ {
+ // strconv.Itoa, not string(): string(65) is "A", not "65".
+ s, daErr, err := devianter.PerformSearch(strconv.Itoa(rand.Intn(999)), rand.Intn(30), 'a')
try(err)
if daErr.RAW != nil {
continue
}
- deviation := &s.Results[rand.Intn(len(s.Results))]
+ // rand.Intn panics on 0, so an empty result set must be skipped.
+ if len(s.Results) == 0 {
+ continue
+ }
+ deviation := &s.Results[rand.Intn(len(s.Results))]
if deviation.NSFW && !CFG.Nsfw {
- attempt++
continue
}
a.sendMedia(deviation)
return
}
+
+ a.Error("Sorry, butt NSFW on this are disabled, and the instance failed to find a random art without NSFW", 500)
}