fs: fix bandwidth limits below 1 KiB being multiplied by 1024 - fixes #9958

BwPair.String printed a sub-KiB bandwidth as a bare number, and Set
reads a bare number as KiB, so a rate under 1 KiB grew by a factor of
1024 whenever it went through a string. rc core/bwlimit reports the
current rate in that format and accepts it back, so reading the limit
and setting it again raised it.

63c4fef27 fixed the same corruption for config values by suffixing bare
numbers with B inside Option.String. Move that into a SizeSuffix method
and use it from BwPair.String as well.
This commit is contained in:
Roland authored and Nick Craig-Wood committed 2026-09-25 17:09:52 +01:00
1 parent 14a1359c96
commit 60bdc6d454
4 files changed
+39 -12

No files matched your search

+2 -2
View File
@@ -18,10 +18,10 @@ type BwPair struct {
// String returns a printable representation of a BwPair
func (bp *BwPair) String() string {
var out strings.Builder
out.WriteString(bp.Tx.String())
out.WriteString(bp.Tx.stringRoundTrip())
if bp.Rx != bp.Tx {
out.WriteRune(':')
out.WriteString(bp.Rx.String())
out.WriteString(bp.Rx.stringRoundTrip())
}
return out.String()
}
+23
View File
@@ -339,6 +339,29 @@ func TestBwTimetableSetReplaces(t *testing.T) {
}
}
func TestBwTimetableStringRoundTrip(t *testing.T) {
for _, in := range []string{
"1B",
"500B",
"1023B",
"1B:2B",
"Mon-10:00,500B",
"08:00,512B 12:00,10M 23:00,off",
"1M",
"1M:100k",
"off",
"0",
} {
var tt BwTimetable
require.NoError(t, tt.Set(in), in)
printed := tt.String()
var got BwTimetable
require.NoError(t, got.Set(printed), "%q printed as %q", in, printed)
assert.Equal(t, tt, got, "%q printed as %q", in, printed)
}
}
func TestBwTimetableSetErrorKeepsPrevious(t *testing.T) {
for _, in := range []string{
"Mon-11:00,333 bad",
+1 -10
View File
@@ -305,16 +305,7 @@ func (o *Option) String() string {
// The default Go encoding can't be decoded uniquely
return CommaSepList(x).String()
case SizeSuffix:
str := x.String()
// Suffix bare numbers with "B" unless they are 0
//
// This makes sure that fs.SizeSuffix roundtrips through string
if len(str) > 0 && str != "0" {
if lastDigit := str[len(str)-1]; lastDigit >= '0' && lastDigit <= '9' {
str += "B"
}
}
return str
return x.stringRoundTrip()
}
return fmt.Sprint(v)
}
+13
View File
@@ -76,6 +76,19 @@ func (x SizeSuffix) String() string {
return val + suffix
}
// stringRoundTrip turns SizeSuffix into a string which Set parses back to the
// same value. A bare number is read by Set as KiB, so values below 1 KiB get a
// "B" suffix to stop them being scaled up.
func (x SizeSuffix) stringRoundTrip() string {
str := x.String()
if len(str) > 0 && str != "0" {
if lastDigit := str[len(str)-1]; lastDigit >= '0' && lastDigit <= '9' {
str += "B"
}
}
return str
}
// Unit turns SizeSuffix into a string with a unit
func (x SizeSuffix) unit(unit string) string {
val, suffix := x.string()