mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-18 08:36:13 +00:00
Extracts the migration-options query-string parsing into a single
parseMigrationOptions helper used by both HandleGetMigrationSummary and
HandleMigrateDevice. The allow-list now covers two families:
- marge / stats / sw_update / bmx (XML method's per-field
self|proxied|original implementation selectors, unchanged)
- marge_url / stats_url / sw_update_url / bmx_url (telnet method's
per-field URL overrides; empty values fall back to the canonical
derivation in setup.telnetURLsFromOptions)
Unknown keys are still dropped, so the manager only sees parameters the
handler explicitly opted into. Tests cover the allow-list, the noise
filter, and the empty-query case.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
72 lines
1.9 KiB
Go
72 lines
1.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/url"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseMigrationOptions_AllowsXMLAndTelnetKeys(t *testing.T) {
|
|
q := url.Values{
|
|
"marge": []string{"self"},
|
|
"stats": []string{"proxied"},
|
|
"sw_update": []string{"original"},
|
|
"bmx": []string{"self"},
|
|
"marge_url": []string{"http://example:8000/marge"},
|
|
"stats_url": []string{"http://example:8000"},
|
|
"sw_update_url": []string{"http://example:8000/updates/soundtouch"},
|
|
"bmx_url": []string{"http://example:8000/bmx/registry/v1/services"},
|
|
}
|
|
|
|
got := parseMigrationOptions(q)
|
|
|
|
want := map[string]string{
|
|
"marge": "self",
|
|
"stats": "proxied",
|
|
"sw_update": "original",
|
|
"bmx": "self",
|
|
"marge_url": "http://example:8000/marge",
|
|
"stats_url": "http://example:8000",
|
|
"sw_update_url": "http://example:8000/updates/soundtouch",
|
|
"bmx_url": "http://example:8000/bmx/registry/v1/services",
|
|
}
|
|
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("parseMigrationOptions = %v\nwant %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestParseMigrationOptions_DropsUnknownKeys(t *testing.T) {
|
|
q := url.Values{
|
|
"marge": []string{"self"},
|
|
"target_url": []string{"http://example:8000"}, // not an option
|
|
"method": []string{"telnet"}, // not an option
|
|
"random": []string{"value"}, // attacker-controlled noise
|
|
}
|
|
|
|
got := parseMigrationOptions(q)
|
|
|
|
if _, ok := got["target_url"]; ok {
|
|
t.Errorf("target_url leaked into options map: %v", got)
|
|
}
|
|
|
|
if _, ok := got["method"]; ok {
|
|
t.Errorf("method leaked into options map: %v", got)
|
|
}
|
|
|
|
if _, ok := got["random"]; ok {
|
|
t.Errorf("random key leaked into options map: %v", got)
|
|
}
|
|
|
|
if got["marge"] != "self" {
|
|
t.Errorf("marge = %q, want self", got["marge"])
|
|
}
|
|
}
|
|
|
|
func TestParseMigrationOptions_EmptyQueryReturnsEmptyMap(t *testing.T) {
|
|
got := parseMigrationOptions(url.Values{})
|
|
if len(got) != 0 {
|
|
t.Errorf("got %v, want empty map", got)
|
|
}
|
|
}
|