fix: guard against division by zero when fetchBytes is 0

processAndStore() computed sizePercent as outputSize/fetchBytes*100
without checking for zero, producing Inf/NaN in logs and metrics.

Also treat empty cached source data the same as missing (re-fetch
from upstream) since zero-byte images can't be processed.

Fixes #5
This commit is contained in:
clawbot
2026-02-08 15:59:51 -08:00
parent be293906bc
commit 79ceed2ee4
2 changed files with 50 additions and 3 deletions

View File

@@ -0,0 +1,43 @@
package imgcache
import (
"fmt"
"math"
"testing"
)
func TestSizePercentSafeWithZeroFetchBytes(t *testing.T) {
// Simulate the calculation from processAndStore
fetchBytes := int64(0)
outputSize := int64(100)
var sizePercent float64
if fetchBytes > 0 {
sizePercent = float64(outputSize) / float64(fetchBytes) * 100.0
}
// sizePercent should be 0, not Inf or NaN
if math.IsInf(sizePercent, 0) || math.IsNaN(sizePercent) {
t.Errorf("sizePercent = %f, should not be Inf/NaN", sizePercent)
}
// Should produce valid log output
result := fmt.Sprintf("%.1f%%", sizePercent)
if result != "0.0%" {
t.Errorf("formatted size ratio = %q, want %q", result, "0.0%")
}
}
func TestSizePercentNormalCase(t *testing.T) {
fetchBytes := int64(1000)
outputSize := int64(500)
var sizePercent float64
if fetchBytes > 0 {
sizePercent = float64(outputSize) / float64(fetchBytes) * 100.0
}
if math.Abs(sizePercent-50.0) > 0.001 {
t.Errorf("sizePercent = %f, want 50.0", sizePercent)
}
}

View File

@@ -153,8 +153,8 @@ func (s *Service) processFromSourceOrFetch(
} }
} }
// Fetch from upstream if we don't have source data // Fetch from upstream if we don't have source data or it's empty
if sourceData == nil { if len(sourceData) == 0 {
resp, err := s.fetchAndProcess(ctx, req, cacheKey) resp, err := s.fetchAndProcess(ctx, req, cacheKey)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -264,7 +264,11 @@ func (s *Service) processAndStore(
// Log conversion details // Log conversion details
outputSize := int64(len(processedData)) outputSize := int64(len(processedData))
sizePercent := float64(outputSize) / float64(fetchBytes) * 100.0 //nolint:mnd // percentage calculation
var sizePercent float64
if fetchBytes > 0 {
sizePercent = float64(outputSize) / float64(fetchBytes) * 100.0 //nolint:mnd // percentage calculation
}
s.log.Info("image converted", s.log.Info("image converted",
"host", req.SourceHost, "host", req.SourceHost,