package winpwn import "testing" // TestCyclicMatchesPwntools pins Cyclic(20) against pwntools' own // cyclic(20) output (b'aaaabaaacaaadaaaeaaa') -- if this ever drifts, every // offset a player calculates by hand using pwntools docs/muscle memory // would silently be wrong. func TestCyclicMatchesPwntools(t *testing.T) { got := string(Cyclic(20)) want := "aaaabaaacaaadaaaeaaa" if got != want { t.Fatalf("Cyclic(20) = %q, want %q", got, want) } } func TestCyclicFindRoundTrip(t *testing.T) { buf := Cyclic(200) for _, off := range []int{0, 4, 17, 100, 196} { sub := buf[off : off+4] if got := CyclicFind(sub); got != off { t.Errorf("CyclicFind(%q) = %d, want %d", sub, got, off) } } } func TestCyclicFindNotFound(t *testing.T) { if got := CyclicFind([]byte{0, 1, 2, 3}); got != -1 { t.Errorf("CyclicFind(non-alphabet bytes) = %d, want -1", got) } } // TestCyclicN8StaysBounded guards against eagerly materializing the full // de Bruijn period (26^8 ~ 2*10^11 bytes) when only a small prefix is // requested -- a real bug caught in this package's own test run (OOM // crash) before deBruijnEach was made to stop early via its yield callback. func TestCyclicN8StaysBounded(t *testing.T) { buf := CyclicN(64, 8) if len(buf) != 64 { t.Fatalf("CyclicN(64, 8) returned %d bytes, want 64", len(buf)) } sub := buf[16:24] if off := CyclicFindN(sub, 8); off != 16 { t.Errorf("CyclicFindN = %d, want 16", off) } } func TestCyclicNZeroLength(t *testing.T) { if got := CyclicN(0, 4); len(got) != 0 { t.Errorf("CyclicN(0, 4) = %v, want empty", got) } }