aboutsummaryrefslogtreecommitdiff
path: root/internal/net/iac_test.go
blob: 6f91f19796dee3fb765653839ee0df2fa35b61aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package net

import "testing"

// Regression: stripIAC required a third byte, so a trailing 2-byte IAC command
// leaked its option byte into player input.
func TestStripIACDropsTruncatedSequence(t *testing.T) {
	got := stripIAC("abc" + string([]byte{iac, 0xf1}))
	if got != "abc" {
		t.Fatalf("stripIAC(truncated) = %q, want %q", got, "abc")
	}
	// A full subnegotiation is still removed.
	got = stripIAC("x" + string([]byte{iac, sb, 1, 2}) + string([]byte{iac, se}) + "y")
	if got != "xy" {
		t.Fatalf("stripIAC(subnegotiation) = %q, want xy", got)
	}
}

func TestStripIACPreservesInputAfterTwoByteCommand(t *testing.T) {
	// A 2-byte command (NOP) in the middle must not eat the following byte.
	if got := stripIAC("a" + string([]byte{iac, 0xf1}) + "b"); got != "ab" {
		t.Fatalf("stripIAC(mid two-byte command) = %q, want %q", got, "ab")
	}
	// A 3-byte negotiation command consumes its option byte.
	if got := stripIAC("a" + string([]byte{iac, will, echo}) + "b"); got != "ab" {
		t.Fatalf("stripIAC(three-byte command) = %q, want %q", got, "ab")
	}
	// IAC IAC is an escaped literal 0xFF, not a command.
	if got := stripIAC("a" + string([]byte{iac, iac}) + "b"); got != "a"+string([]byte{iac})+"b" {
		t.Fatalf("stripIAC(escaped IAC) = %q, want literal 0xFF", got)
	}
}