Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return public net/textproto error types #316

Merged
merged 1 commit into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion inspect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
21 changes: 11 additions & 10 deletions internal/textproto/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"fmt"
"io"
"math"
"net/textproto"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -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: code, Msg: message}
}
return
}
Expand All @@ -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
}
Expand Down Expand Up @@ -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: code, Msg: message}
}
return
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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))
}
}

Expand Down Expand Up @@ -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
}
Expand Down
7 changes: 4 additions & 3 deletions internal/textproto/reader_email.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"math"
"net/textproto"
)

// ReadEmailMIMEHeader reads a MIME-style header from r.
Expand Down Expand Up @@ -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 {
Expand All @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion internal/textproto/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"bytes"
"io"
"net"
"net/textproto"
"reflect"
"strings"
"sync"
Expand Down Expand Up @@ -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)
Expand Down
19 changes: 0 additions & 19 deletions internal/textproto/textproto.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down