fix(config): warn instead of panicking on an app-id that breaks its anchoring
- commit
- 412bdb00043b8d1ae36e0a56b417112fbc094a51
- author
- brice · · 2026-10-08 19:54 UTC
- parent
- 8f14070
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +8 -1
M internal/adapters/config/config.go +6 -1
| @@ -1035,7 +1035,12 @@ func setRule(r *ports.WindowRule, field, v string) error { | |||
| 1035 | 1035 | return fmt.Errorf("invalid regular expression: %v", err) | |
| 1036 | 1036 | } | |
| 1037 | 1037 | // The whole app ID must match: "steam" does not match "steam_app_1". | |
| 1038 | - | r.AppID = regexp.MustCompile("^(?:" + v + ")$") | |
| 1038 | + | // A value can still break the wrapping ("\Qsteam" quotes the ")"). | |
| 1039 | + | re, err := regexp.Compile("^(?:" + v + ")$") | |
| 1040 | + | if err != nil { | |
| 1041 | + | return fmt.Errorf("invalid regular expression: %v", err) | |
| 1042 | + | } | |
| 1043 | + | r.AppID = re | |
| 1039 | 1044 | case "floating": | |
| 1040 | 1045 | b, err := onOff(v) | |
| 1041 | 1046 | if err != nil { | |
| @@ -1035,7 +1035,12 @@ func setRule(r *ports.WindowRule, field, v string) error { | |||||
| 1035 | return fmt.Errorf("invalid regular expression: %v", err) | 1035 | return fmt.Errorf("invalid regular expression: %v", err) | ||
| 1036 | } | 1036 | } | ||
| 1037 | // The whole app ID must match: "steam" does not match "steam_app_1". | 1037 | // The whole app ID must match: "steam" does not match "steam_app_1". | ||
| 1038 | - | r.AppID = regexp.MustCompile("^(?:" + v + ")$") | 1038 | + | // A value can still break the wrapping ("\Qsteam" quotes the ")"). |
| 1039 | + | re, err := regexp.Compile("^(?:" + v + ")$") | |||
| 1040 | + | if err != nil { | |||
| 1041 | + | return fmt.Errorf("invalid regular expression: %v", err) | |||
| 1042 | + | } | |||
| 1043 | + | r.AppID = re | |||
| 1039 | case "floating": | 1044 | case "floating": | ||
| 1040 | b, err := onOff(v) | 1045 | b, err := onOff(v) | ||
| 1041 | if err != nil { | 1046 | if err != nil { | ||
M internal/adapters/config/rules_test.go +2 -0
| @@ -61,6 +61,8 @@ func TestRuleWarnings(t *testing.T) { | |||
| 61 | 61 | {"bad regex", "rule.a.app-id = (\n", "rule.a.app-id: invalid regular expression", 1, 0}, | |
| 62 | 62 | // Closing the anchoring group would match any app ID. | |
| 63 | 63 | {"anchor breakout", "rule.a.app-id = steam)|(.*\n", "rule.a.app-id: invalid regular expression", 1, 0}, | |
| 64 | + | // Quoting the anchoring group's ")" must warn, not panic. | |
| 65 | + | {"quoted anchor", "rule.a.app-id = \\Qsteam\n", "rule.a.app-id: invalid regular expression", 1, 0}, | |
| 64 | 66 | {"missing app-id", "rule.a.floating = on\n", "rule.a: no app-id, rule ignored", 1, 0}, | |
| 65 | 67 | {"unknown field", "rule.a.app-id = foo\nrule.a.title = x\n", "rule.a.title: unknown key", 2, 1}, | |
| 66 | 68 | {"bad floating", "rule.a.app-id = foo\nrule.a.floating = maybe\n", "rule.a.floating: must be on or off", 2, 0}, | |
| @@ -61,6 +61,8 @@ func TestRuleWarnings(t *testing.T) { | |||||
| 61 | {"bad regex", "rule.a.app-id = (\n", "rule.a.app-id: invalid regular expression", 1, 0}, | 61 | {"bad regex", "rule.a.app-id = (\n", "rule.a.app-id: invalid regular expression", 1, 0}, | ||
| 62 | // Closing the anchoring group would match any app ID. | 62 | // Closing the anchoring group would match any app ID. | ||
| 63 | {"anchor breakout", "rule.a.app-id = steam)|(.*\n", "rule.a.app-id: invalid regular expression", 1, 0}, | 63 | {"anchor breakout", "rule.a.app-id = steam)|(.*\n", "rule.a.app-id: invalid regular expression", 1, 0}, | ||
| 64 | + | // Quoting the anchoring group's ")" must warn, not panic. | |||
| 65 | + | {"quoted anchor", "rule.a.app-id = \\Qsteam\n", "rule.a.app-id: invalid regular expression", 1, 0}, | |||
| 64 | {"missing app-id", "rule.a.floating = on\n", "rule.a: no app-id, rule ignored", 1, 0}, | 66 | {"missing app-id", "rule.a.floating = on\n", "rule.a: no app-id, rule ignored", 1, 0}, | ||
| 65 | {"unknown field", "rule.a.app-id = foo\nrule.a.title = x\n", "rule.a.title: unknown key", 2, 1}, | 67 | {"unknown field", "rule.a.app-id = foo\nrule.a.title = x\n", "rule.a.title: unknown key", 2, 1}, | ||
| 66 | {"bad floating", "rule.a.app-id = foo\nrule.a.floating = maybe\n", "rule.a.floating: must be on or off", 2, 0}, | 68 | {"bad floating", "rule.a.app-id = foo\nrule.a.floating = maybe\n", "rule.a.floating: must be on or off", 2, 0}, | ||