From f92bf7f1a25777bcdaa28a142b1cd1a54b74c8f4 Mon Sep 17 00:00:00 2001 From: Anatoliy Shipticyn Date: Wed, 24 Mar 2021 16:14:39 +0500 Subject: [PATCH] Disable lineLimitReader when handle BDAT data References: https://github.com/emersion/go-smtp/issues/81#issuecomment-801659120 --- conn.go | 23 +++++++++++++++-------- lengthlimit_reader.go | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/conn.go b/conn.go index cc52488..f033423 100644 --- a/conn.go +++ b/conn.go @@ -40,10 +40,11 @@ type Conn struct { locker sync.Mutex binarymime bool - bdatPipe *io.PipeWriter - bdatStatus *statusCollector // used for BDAT on LMTP - dataResult chan error - bytesReceived int // counts total size of chunks when BDAT is used + lineLimitReader *lineLimitReader + bdatPipe *io.PipeWriter + bdatStatus *statusCollector // used for BDAT on LMTP + dataResult chan error + bytesReceived int // counts total size of chunks when BDAT is used fromReceived bool recipients []string @@ -60,15 +61,16 @@ func newConn(c net.Conn, s *Server) *Conn { } func (c *Conn) init() { + c.lineLimitReader = &lineLimitReader{ + R: c.conn, + LineLimit: c.server.MaxLineLength, + } rwc := struct { io.Reader io.Writer io.Closer }{ - Reader: &lineLimitReader{ - R: c.conn, - LineLimit: c.server.MaxLineLength, - }, + Reader: c.lineLimitReader, Writer: c.conn, Closer: c.conn, } @@ -741,6 +743,8 @@ func (c *Conn) handleBdat(arg string) { }() } + c.lineLimitReader.LineLimit = 0 + chunk := io.LimitReader(c.text.R, int64(size)) _, err = io.Copy(c.bdatPipe, chunk) if err != nil { @@ -755,12 +759,15 @@ func (c *Conn) handleBdat(arg string) { } c.reset() + c.lineLimitReader.LineLimit = c.server.MaxLineLength return } c.bytesReceived += int(size) if last { + c.lineLimitReader.LineLimit = c.server.MaxLineLength + c.bdatPipe.Close() err := <-c.dataResult diff --git a/lengthlimit_reader.go b/lengthlimit_reader.go index d35d92c..695bc76 100644 --- a/lengthlimit_reader.go +++ b/lengthlimit_reader.go @@ -19,7 +19,7 @@ type lineLimitReader struct { } func (r *lineLimitReader) Read(b []byte) (int, error) { - if r.curLineLength > r.LineLimit { + if r.curLineLength > r.LineLimit && r.LineLimit > 0 { return 0, ErrTooLongLine }