From b3568f03e4103dd46db2ccc680fbab0a6454d604 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Tue, 15 Sep 2026 13:56:10 -0400 Subject: fix: telnet buffer reuse, bank stack handling, transport casino gate, and admin cache invalidation --- internal/net/conn.go | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'internal/net/conn.go') diff --git a/internal/net/conn.go b/internal/net/conn.go index e46031b..2fff0bc 100644 --- a/internal/net/conn.go +++ b/internal/net/conn.go @@ -24,21 +24,46 @@ type tcpConn struct { func newTCPConn(conn net.Conn) *tcpConn { return &tcpConn{ conn: conn, - reader: bufio.NewReader(conn), + reader: bufio.NewReaderSize(conn, maxLineLength*4), } } +// maxLineLength bounds how much of an incoming line is accepted. Longer +// lines are drained from the socket and truncated so a client cannot grow +// the read buffer without limit. +const maxLineLength = 1024 + func (t *tcpConn) ReadMessage() (string, error) { - line, err := t.reader.ReadString('\n') - if err != nil { + line, err := t.reader.ReadSlice('\n') + if err == bufio.ErrBufferFull { + // Copy the bounded prefix out of the reusable read buffer BEFORE + // draining the rest of the oversized line; further reads overwrite the + // buffer the slice points into. + prefixLen := len(line) + if prefixLen > maxLineLength { + prefixLen = maxLineLength + } + prefix := make([]byte, prefixLen) + copy(prefix, line[:prefixLen]) + for { + _, err = t.reader.ReadSlice('\n') + if err == nil { + break + } + if err != bufio.ErrBufferFull { + return "", err + } + } + line = prefix + } else if err != nil { return "", err } - line = strings.TrimRight(line, "\r\n") - line = stripIAC(line) + text := strings.TrimRight(string(line), "\r\n") + text = stripIAC(text) if t.echoOff { t.conn.Write([]byte("\r\n")) } - return line, nil + return text, nil } func (t *tcpConn) Write(b []byte) (int, error) { -- cgit v1.2.3