diff options
| author | Christian Cleberg <[email protected]> | 2026-07-14 20:22:14 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-07-14 20:22:14 -0500 |
| commit | 8a00f7c55cdbcddcd878c01a79f2db7dc3f080ef (patch) | |
| tree | fe4c4ef1188986fd3676253048c3014e4de86d07 /app | |
| parent | 0fdc45a668d95d603a9013f90392f6bc966c72f9 (diff) | |
| download | skunky-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.
Diffstat (limited to 'app')
| -rwxr-xr-x | app/api.go | 22 |
1 files changed, 15 insertions, 7 deletions
@@ -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) } |
