report configuration failures instead of crashing
Return errors from the save path rather than panicking. Every write panicked on failure, so a read-only or missing configuration directory killed a running client. The parent directory is created when absent, and callers now show the failure in the output window and carry on. Write through an unpredictable temporary file. The old fixed ".tmp" name next to the configuration was a symlink target an attacker could plant in advance. Serialize configuration reads and writes. Hotkey handlers, the audio thread, and the connection callbacks all touch the same structure, so saves could interleave with updates. Parse addresses with SplitHostPort. Splitting on every colon broke IPv6 addresses and panicked outright on an address with no port. Both now fall back to Mumble's default port. Fail immediately when an explicitly requested config file is missing or is not a regular file. Silently falling back to defaults hid a mistyped -config path. Supply defaults for the clear-output and scroll-to-top and -bottom hotkeys. The UI registered listeners for them but the configuration never filled the keys in, so the bindings were nil and the keys did nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7e1faba06b
commit
17173b779b
@@ -114,6 +114,8 @@ func main() {
|
||||
fifo := flag.String("fifo", "", "path of a FIFO from which to read commands")
|
||||
serverSet := false
|
||||
usernameSet := false
|
||||
configSet := false
|
||||
certificateSet := false
|
||||
buffers := flag.Int("buffers", 16, "number of audio buffers to use")
|
||||
audioInterval := flag.Int("audio-interval", 10, "outgoing audio packet duration in ms (10, 20, 40, or 60)")
|
||||
jitterBuffer := flag.Int("jitter-buffer", 40, "incoming per-user audio buffer in ms (0, 20, 40, or 60)")
|
||||
@@ -165,19 +167,24 @@ func main() {
|
||||
}()
|
||||
}
|
||||
|
||||
userConfig := config.NewConfig(cfgfn)
|
||||
|
||||
certificateSet := false
|
||||
flag.CommandLine.Visit(func(theFlag *flag.Flag) {
|
||||
switch theFlag.Name {
|
||||
case "server":
|
||||
serverSet = true
|
||||
case "username":
|
||||
usernameSet = true
|
||||
case "config":
|
||||
configSet = true
|
||||
case "certificate":
|
||||
certificateSet = true
|
||||
}
|
||||
})
|
||||
if configSet {
|
||||
if err := config.RequireConfigFile(*cfgfn); err != nil {
|
||||
handle_raw_error(err)
|
||||
}
|
||||
}
|
||||
userConfig := config.NewConfig(cfgfn)
|
||||
|
||||
if !serverSet {
|
||||
server = userConfig.GetDefaultServer()
|
||||
@@ -229,13 +236,19 @@ func main() {
|
||||
b.Config.IncomingAudioBuffer = selectedJitterBuffer
|
||||
|
||||
b.Hotkeys = b.UserConfig.GetHotkeys()
|
||||
b.UserConfig.SaveConfig()
|
||||
if err := b.UserConfig.SaveConfig(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not save configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Configure noise suppression
|
||||
enabled := b.UserConfig.GetNoiseSuppressionEnabled()
|
||||
if *noiseSuppressionEnabled {
|
||||
enabled = true
|
||||
b.UserConfig.SetNoiseSuppressionEnabled(true)
|
||||
if err := b.UserConfig.SetNoiseSuppressionEnabled(true); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not save configuration: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
b.NoiseSuppressor.SetEnabled(enabled)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user