Validate audio configuration values

This commit is contained in:
Brandon McGinty (chatgpt)
2026-08-09 14:22:46 -04:00
committed by Brandon McGinty
parent 82440b7670
commit 626608c997
4 changed files with 43 additions and 3 deletions
+3 -3
View File
@@ -182,20 +182,20 @@ Priority 2: protocol and data correctness
is 2x/4x/6x too high. Calculate bits per frame divided by the actual
Config.AudioInterval, or set the bitrate once when configuration changes.
23. AudioInterval accepts invalid values
[x] 23. AudioInterval accepts invalid values
File: gumble/gumble/config.go
AudioFrameSize truncates arbitrary intervals to a count of 10 ms frames,
while the ticker still uses the original interval. Validate and reject
values other than 10/20/40/60 ms (and validate AudioDataBytes/Buffers).
24. Legacy/custom varint has a MinInt64 recursion failure
[x] 24. Legacy/custom varint has a MinInt64 recursion failure
File: gumble/gumble/varint/write.go
Encoding math.MinInt64 evaluates -value to the same negative number and
recursively encodes forever until panic. Handle MinInt64 explicitly or
encode negatives using an unsigned magnitude without overflow. Validate
output buffer capacity in the exported encoder too.
25. Mumble version layout documentation is wrong
[x] 25. Mumble version layout documentation is wrong
File: gumble/gumble/version.go
The comment says major uses bits 0-15, but SemanticVersion and ClientVersion
use bits 16-31. Correct the documentation and add known version tests.
+3
View File
@@ -110,6 +110,9 @@ func Dial(config *Config) (*Client, error) {
// min(time.Now() + dialer.Timeout, dialer.Deadline), or if the server rejects
// the client.
func DialWithDialer(dialer *net.Dialer, config *Config, tlsConfig *tls.Config) (*Client, error) {
if err := config.Validate(); err != nil {
return nil, err
}
start := time.Now()
conn, err := tls.DialWithDialer(dialer, "tcp", config.Address, tlsConfig)
+17
View File
@@ -1,6 +1,7 @@
package gumble
import (
"fmt"
"time"
)
@@ -43,6 +44,22 @@ func NewConfig() *Config {
}
}
// Validate checks values that are used by the audio ticker and encoder.
func (c *Config) Validate() error {
switch c.AudioInterval {
case 10 * time.Millisecond, 20 * time.Millisecond, 40 * time.Millisecond, 60 * time.Millisecond:
default:
return fmt.Errorf("gumble: AudioInterval must be 10ms, 20ms, 40ms, or 60ms")
}
if c.AudioDataBytes <= 0 {
return fmt.Errorf("gumble: AudioDataBytes must be positive")
}
if c.Buffers <= 0 {
return fmt.Errorf("gumble: Buffers must be positive")
}
return nil
}
// Attach is an alias of c.Listeners.Attach.
func (c *Config) Attach(l EventListener) Detacher {
return c.Listeners.Attach(l)
+20
View File
@@ -0,0 +1,20 @@
package gumble
import (
"testing"
"time"
)
// Regression: arbitrary intervals were truncated to 10 ms frames while the
// ticker kept the original duration, producing malformed audio timing.
func TestConfigValidateRejectsUnsupportedAudioInterval(t *testing.T) {
config := NewConfig()
config.AudioInterval = 15 * time.Millisecond
if err := config.Validate(); err == nil {
t.Fatal("invalid audio interval was accepted")
}
config.AudioInterval = 60 * time.Millisecond
if err := config.Validate(); err != nil {
t.Fatalf("valid audio interval rejected: %v", err)
}
}