fix(query): accept Kitty primary attributes response
- commit
- 49ed8a6f7dd108d8cf4d8286fa320325a620f4ba
- author
- brice · · 2026-08-26 11:02 UTC
- parent
- 16f5a24
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +5 -2
M protocol/terminalquery/query.go +4 -2
| @@ -176,7 +176,7 @@ func validDA1Response(data []byte) bool { | |||
| 176 | 176 | // not sufficient for a direct graphics declaration. The parameter body is | |
| 177 | 177 | // a non-empty semicolon-separated list of decimal numbers. | |
| 178 | 178 | body := data[3 : len(data)-1] | |
| 179 | - | if len(body) == 0 || body[0] == ';' || body[len(body)-1] == ';' { | |
| 179 | + | if len(body) == 0 || body[0] == ';' { | |
| 180 | 180 | return false | |
| 181 | 181 | } | |
| 182 | 182 | previousSeparator := false | |
| @@ -193,7 +193,9 @@ func validDA1Response(data []byte) bool { | |||
| 193 | 193 | return false | |
| 194 | 194 | } | |
| 195 | 195 | } | |
| 196 | - | return !previousSeparator | |
| 196 | + | // Kitty terminates its DA1 parameter list with a separator. DEC treats the | |
| 197 | + | // resulting empty final parameter as zero, so both forms are valid. | |
| 198 | + | return true | |
| 197 | 199 | } | |
| 198 | 200 | ||
| 199 | 201 | func suffixPrefixLen(data []byte) int { | |
| @@ -176,7 +176,7 @@ func validDA1Response(data []byte) bool { | |||||
| 176 | // not sufficient for a direct graphics declaration. The parameter body is | 176 | // not sufficient for a direct graphics declaration. The parameter body is | ||
| 177 | // a non-empty semicolon-separated list of decimal numbers. | 177 | // a non-empty semicolon-separated list of decimal numbers. | ||
| 178 | body := data[3 : len(data)-1] | 178 | body := data[3 : len(data)-1] | ||
| 179 | - | if len(body) == 0 || body[0] == ';' || body[len(body)-1] == ';' { | 179 | + | if len(body) == 0 || body[0] == ';' { |
| 180 | return false | 180 | return false | ||
| 181 | } | 181 | } | ||
| 182 | previousSeparator := false | 182 | previousSeparator := false | ||
| @@ -193,7 +193,9 @@ func validDA1Response(data []byte) bool { | |||||
| 193 | return false | 193 | return false | ||
| 194 | } | 194 | } | ||
| 195 | } | 195 | } | ||
| 196 | - | return !previousSeparator | 196 | + | // Kitty terminates its DA1 parameter list with a separator. DEC treats the |
| 197 | + | // resulting empty final parameter as zero, so both forms are valid. | |||
| 198 | + | return true | |||
| 197 | } | 199 | } | ||
| 198 | 200 | ||||
| 199 | func suffixPrefixLen(data []byte) int { | 201 | func suffixPrefixLen(data []byte) int { | ||
M protocol/terminalquery/query_test.go +1 -0
| @@ -15,6 +15,7 @@ func TestProbeRequiresKittyAndDA1(t *testing.T) { | |||
| 15 | 15 | unrelated string | |
| 16 | 16 | }{ | |
| 17 | 17 | {name: "both and input", data: "x\x1b[?1;2c" + "\x1b_Gi=31;OK\x1b\\y", kitty: true, da1: true, unrelated: "xy"}, | |
| 18 | + | {name: "kitty DA1 with trailing separator", data: "\x1b_Gi=31;OK\x1b\\\x1b[?62;52;c", kitty: true, da1: true}, | |
| 18 | 19 | {name: "secondary DA is insufficient", data: "\x1b[>1;2c\x1b_Gi=31;OK\x1b\\", kitty: true, unrelated: "\x1b[>1;2c"}, | |
| 19 | 20 | {name: "ordinary input", data: "hello", unrelated: "hello"}, | |
| 20 | 21 | } { | |
| @@ -15,6 +15,7 @@ func TestProbeRequiresKittyAndDA1(t *testing.T) { | |||||
| 15 | unrelated string | 15 | unrelated string | ||
| 16 | }{ | 16 | }{ | ||
| 17 | {name: "both and input", data: "x\x1b[?1;2c" + "\x1b_Gi=31;OK\x1b\\y", kitty: true, da1: true, unrelated: "xy"}, | 17 | {name: "both and input", data: "x\x1b[?1;2c" + "\x1b_Gi=31;OK\x1b\\y", kitty: true, da1: true, unrelated: "xy"}, | ||
| 18 | + | {name: "kitty DA1 with trailing separator", data: "\x1b_Gi=31;OK\x1b\\\x1b[?62;52;c", kitty: true, da1: true}, | |||
| 18 | {name: "secondary DA is insufficient", data: "\x1b[>1;2c\x1b_Gi=31;OK\x1b\\", kitty: true, unrelated: "\x1b[>1;2c"}, | 19 | {name: "secondary DA is insufficient", data: "\x1b[>1;2c\x1b_Gi=31;OK\x1b\\", kitty: true, unrelated: "\x1b[>1;2c"}, | ||
| 19 | {name: "ordinary input", data: "hello", unrelated: "hello"}, | 20 | {name: "ordinary input", data: "hello", unrelated: "hello"}, | ||
| 20 | } { | 21 | } { | ||