fix: do not corrupt state when Add/Set overshoots max

Add64 checked currentNum > max only after already mutating currentNum
and currentBytes, so a single call that overshoots max returned an
error but left the bar stuck: currentNum frozen above max, percent
stuck above 100%, and every later Add/Set call failing with the same
error forever, since the top-of-function currentNum < max guard could
never pass again.

Check the bound before mutating state instead, so an overshooting call
is rejected as a whole and leaves currentNum/currentBytes/currentPercent
exactly as they were. The now-unreachable post-hoc check is removed.

Add TestAddExceedsMaxDoesNotCorruptState covering the corrupted-state
case and that the bar keeps accepting valid progress afterwards.
This commit is contained in:
dualfroz committed 2026-09-04 08:23:03 +02:00
1 parent ab40861d8a
commit 18ce81580f
3 files changed
+116 -3

No files matched your search

+4 -3
View File
@@ -741,6 +741,10 @@ func (p *ProgressBar) Add64(num int64) error {
return errors.New("max must be greater than 0")
}
if !p.config.ignoreLength && p.state.currentNum+num > p.config.max {
return errors.New("current number exceeds max")
}
if p.state.currentNum < p.config.max {
if p.config.ignoreLength {
p.state.currentNum = (p.state.currentNum + num) % p.config.max
@@ -774,9 +778,6 @@ func (p *ProgressBar) Add64(num int64) error {
updateBar := p.state.currentPercent != p.state.lastPercent && p.state.currentPercent > 0
p.state.lastPercent = p.state.currentPercent
if p.state.currentNum > p.config.max {
return errors.New("current number exceeds max")
}
// always update if show bytes/second or its/second
if updateBar || p.config.showIterationsPerSecond || p.config.showIterationsCount {