From 60b0e78392236a5b0d049c606520287601b1b598 Mon Sep 17 00:00:00 2001 From: Daniel Cormier Date: Wed, 27 Dec 2023 14:26:35 -0500 Subject: [PATCH] Return public `net/textproto` error types To allow for checking returned error types, types from the standard library's `net/textproto` must be used instead of types from the private `textproto` fork. --- inspect_test.go | 2 +- internal/textproto/reader.go | 21 +++++++++++---------- internal/textproto/reader_email.go | 7 ++++--- internal/textproto/reader_test.go | 3 ++- internal/textproto/textproto.go | 19 ------------------- 5 files changed, 18 insertions(+), 34 deletions(-) diff --git a/inspect_test.go b/inspect_test.go index 58f22ad9..e65a83ba 100644 --- a/inspect_test.go +++ b/inspect_test.go @@ -4,12 +4,12 @@ import ( "bytes" "io" "net/mail" + "net/textproto" "strings" "testing" "github.com/jhillyerd/enmime" "github.com/jhillyerd/enmime/internal/test" - "github.com/jhillyerd/enmime/internal/textproto" ) func TestDecodeRFC2047(t *testing.T) { diff --git a/internal/textproto/reader.go b/internal/textproto/reader.go index 010396df..f36f0747 100644 --- a/internal/textproto/reader.go +++ b/internal/textproto/reader.go @@ -11,6 +11,7 @@ import ( "fmt" "io" "math" + "net/textproto" "strconv" "strings" "sync" @@ -198,20 +199,20 @@ func (r *Reader) readCodeLine(expectCode int) (code int, continued bool, message func parseCodeLine(line string, expectCode int) (code int, continued bool, message string, err error) { if len(line) < 4 || line[3] != ' ' && line[3] != '-' { - err = ProtocolError("short response: " + line) + err = textproto.ProtocolError("short response: " + line) return } continued = line[3] == '-' code, err = strconv.Atoi(line[0:3]) if err != nil || code < 100 { - err = ProtocolError("invalid response code: " + line) + err = textproto.ProtocolError("invalid response code: " + line) return } message = line[4:] if 1 <= expectCode && expectCode < 10 && code/100 != expectCode || 10 <= expectCode && expectCode < 100 && code/10 != expectCode || 100 <= expectCode && expectCode < 1000 && code != expectCode { - err = &Error{code, message} + err = &textproto.Error{code, message} } return } @@ -236,7 +237,7 @@ func parseCodeLine(line string, expectCode int) (code int, continued bool, messa func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err error) { code, continued, message, err := r.readCodeLine(expectCode) if err == nil && continued { - err = ProtocolError("unexpected multi-line response: " + message) + err = textproto.ProtocolError("unexpected multi-line response: " + message) } return } @@ -288,7 +289,7 @@ func (r *Reader) ReadResponse(expectCode int) (code int, message string, err err } if err != nil && multi && message != "" { // replace one line error message with all lines (full message) - err = &Error{code, message} + err = &textproto.Error{code, message} } return } @@ -506,7 +507,7 @@ func readMIMEHeader(r *Reader, lim int64) (MIMEHeader, error) { if err != nil { return m, err } - return m, ProtocolError("malformed MIME header initial line: " + string(line)) + return m, textproto.ProtocolError("malformed MIME header initial line: " + string(line)) } for { @@ -518,15 +519,15 @@ func readMIMEHeader(r *Reader, lim int64) (MIMEHeader, error) { // Key ends at first colon. k, v, ok := bytes.Cut(kv, colon) if !ok { - return m, ProtocolError("malformed MIME header line: " + string(kv)) + return m, textproto.ProtocolError("malformed MIME header line: " + string(kv)) } key, ok := canonicalMIMEHeaderKey(k) if !ok { - return m, ProtocolError("malformed MIME header line: " + string(kv)) + return m, textproto.ProtocolError("malformed MIME header line: " + string(kv)) } for _, c := range v { if !validHeaderValueByte(c) { - return m, ProtocolError("malformed MIME header line: " + string(kv)) + return m, textproto.ProtocolError("malformed MIME header line: " + string(kv)) } } @@ -578,7 +579,7 @@ func noValidation(_ []byte) error { return nil } // contain a colon. func mustHaveFieldNameColon(line []byte) error { if bytes.IndexByte(line, ':') < 0 { - return ProtocolError(fmt.Sprintf("malformed MIME header: missing colon: %q", line)) + return textproto.ProtocolError(fmt.Sprintf("malformed MIME header: missing colon: %q", line)) } return nil } diff --git a/internal/textproto/reader_email.go b/internal/textproto/reader_email.go index 0cc8e362..0b49509f 100644 --- a/internal/textproto/reader_email.go +++ b/internal/textproto/reader_email.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "math" + "net/textproto" ) // ReadEmailMIMEHeader reads a MIME-style header from r. @@ -32,7 +33,7 @@ func readEmailMIMEHeader(r *Reader, lim int64) (MIMEHeader, error) { if err != nil { return m, err } - return m, ProtocolError("malformed MIME header initial line: " + string(line)) + return m, textproto.ProtocolError("malformed MIME header initial line: " + string(line)) } for { @@ -44,11 +45,11 @@ func readEmailMIMEHeader(r *Reader, lim int64) (MIMEHeader, error) { // Key ends at first colon. k, v, ok := bytes.Cut(kv, colon) if !ok { - return m, ProtocolError("malformed MIME header line: " + string(kv)) + return m, textproto.ProtocolError("malformed MIME header line: " + string(kv)) } key, ok := canonicalEmailMIMEHeaderKey(k) if !ok { - return m, ProtocolError("malformed MIME header line: " + string(kv)) + return m, textproto.ProtocolError("malformed MIME header line: " + string(kv)) } // for _, c := range v { // if !validHeaderValueByte(c) { diff --git a/internal/textproto/reader_test.go b/internal/textproto/reader_test.go index 2c7d2aa4..f6c728da 100644 --- a/internal/textproto/reader_test.go +++ b/internal/textproto/reader_test.go @@ -9,6 +9,7 @@ import ( "bytes" "io" "net" + "net/textproto" "reflect" "strings" "sync" @@ -69,7 +70,7 @@ func TestReadCodeLine(t *testing.T) { if code != 345 || msg != "no way" || err == nil { t.Fatalf("Line 3: %d, %s, %v", code, msg, err) } - if e, ok := err.(*Error); !ok || e.Code != code || e.Msg != msg { + if e, ok := err.(*textproto.Error); !ok || e.Code != code || e.Msg != msg { t.Fatalf("Line 3: wrong error %v\n", err) } code, msg, err = r.ReadCodeLine(1) diff --git a/internal/textproto/textproto.go b/internal/textproto/textproto.go index 70038d58..0d92bf26 100644 --- a/internal/textproto/textproto.go +++ b/internal/textproto/textproto.go @@ -26,29 +26,10 @@ package textproto import ( "bufio" - "fmt" "io" "net" ) -// An Error represents a numeric error response from a server. -type Error struct { - Code int - Msg string -} - -func (e *Error) Error() string { - return fmt.Sprintf("%03d %s", e.Code, e.Msg) -} - -// A ProtocolError describes a protocol violation such -// as an invalid response or a hung-up connection. -type ProtocolError string - -func (p ProtocolError) Error() string { - return string(p) -} - // A Conn represents a textual network protocol connection. // It consists of a Reader and Writer to manage I/O // and a Pipeline to sequence concurrent requests on the connection.