Fixing to have the proper version of go-imap from foxcpp.

This commit is contained in:
2025-12-08 22:52:36 +02:00
parent d8ddb6be71
commit 226c7e6cf0
207 changed files with 15166 additions and 15437 deletions

500
read_test.go Normal file
View File

@@ -0,0 +1,500 @@
package imap_test
import (
"bytes"
"io"
"io/ioutil"
"reflect"
"testing"
"github.com/emersion/go-imap"
)
func TestParseNumber(t *testing.T) {
tests := []struct {
f interface{}
n uint32
err bool
}{
{f: "42", n: 42},
{f: "0", n: 0},
{f: "-1", err: true},
{f: "1.2", err: true},
{f: nil, err: true},
{f: bytes.NewBufferString("cc"), err: true},
}
for _, test := range tests {
n, err := imap.ParseNumber(test.f)
if err != nil {
if !test.err {
t.Errorf("Cannot parse number %v", test.f)
}
} else {
if test.err {
t.Errorf("Parsed invalid number %v", test.f)
} else if n != test.n {
t.Errorf("Invalid parsed number: got %v but expected %v", n, test.n)
}
}
}
}
func TestParseStringList(t *testing.T) {
tests := []struct {
field interface{}
list []string
}{
{
field: []interface{}{"a", "b", "c", "d"},
list: []string{"a", "b", "c", "d"},
},
{
field: []interface{}{"a"},
list: []string{"a"},
},
{
field: []interface{}{},
list: []string{},
},
{
field: []interface{}{"a", 42, "c", "d"},
list: nil,
},
{
field: []interface{}{"a", nil, "c", "d"},
list: nil,
},
{
field: "Asuka FTW",
list: nil,
},
}
for _, test := range tests {
list, err := imap.ParseStringList(test.field)
if err != nil {
if test.list != nil {
t.Errorf("Cannot parse string list: %v", err)
}
} else if !reflect.DeepEqual(list, test.list) {
t.Errorf("Invalid parsed string list: got \n%+v\n but expected \n%+v", list, test.list)
}
}
}
func newReader(s string) (b *bytes.Buffer, r *imap.Reader) {
b = bytes.NewBuffer([]byte(s))
r = imap.NewReader(b)
return
}
func TestReader_ReadSp(t *testing.T) {
b, r := newReader(" ")
if err := r.ReadSp(); err != nil {
t.Error(err)
}
if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
b, r = newReader("")
if err := r.ReadSp(); err == nil {
t.Error("Invalid read didn't fail")
}
}
func TestReader_ReadCrlf(t *testing.T) {
b, r := newReader("\r\n")
if err := r.ReadCrlf(); err != nil {
t.Error(err)
}
if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
b, r = newReader("")
if err := r.ReadCrlf(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("\n")
if err := r.ReadCrlf(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("\r")
if err := r.ReadCrlf(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("\r42")
if err := r.ReadCrlf(); err == nil {
t.Error("Invalid read didn't fail")
}
}
func TestReader_ReadAtom(t *testing.T) {
b, r := newReader("NIL\r\n")
if atom, err := r.ReadAtom(); err != nil {
t.Error(err)
} else if atom != nil {
t.Error("NIL atom is not nil:", atom)
} else {
if err := r.ReadCrlf(); err != nil && err != io.EOF {
t.Error("Cannot read CRLF after atom:", err)
}
if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
}
b, r = newReader("atom\r\n")
if atom, err := r.ReadAtom(); err != nil {
t.Error(err)
} else if s, ok := atom.(string); !ok || s != "atom" {
t.Error("String atom has not the expected value:", atom)
} else {
if err := r.ReadCrlf(); err != nil && err != io.EOF {
t.Error("Cannot read CRLF after atom:", err)
}
if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
}
_, r = newReader("")
if _, err := r.ReadAtom(); err == nil {
t.Error("Invalid read didn't fail")
}
_, r = newReader("(hi there)\r\n")
if _, err := r.ReadAtom(); err == nil {
t.Error("Invalid read didn't fail")
}
_, r = newReader("{42}\r\n")
if _, err := r.ReadAtom(); err == nil {
t.Error("Invalid read didn't fail")
}
_, r = newReader("\"\r\n")
if _, err := r.ReadAtom(); err == nil {
t.Error("Invalid read didn't fail")
}
_, r = newReader("abc]")
if _, err := r.ReadAtom(); err == nil {
t.Error("Invalid read didn't fail")
}
_, r = newReader("[abc]def]ghi")
if _, err := r.ReadAtom(); err == nil {
t.Error("Invalid read didn't fail")
}
}
func TestReader_ReadLiteral(t *testing.T) {
b, r := newReader("{7}\r\nabcdefg")
if literal, err := r.ReadLiteral(); err != nil {
t.Error(err)
} else if literal.Len() != 7 {
t.Error("Invalid literal length:", literal.Len())
} else {
if contents, err := ioutil.ReadAll(literal); err != nil {
t.Error(err)
} else if string(contents) != "abcdefg" {
t.Error("Literal has not the expected value:", string(contents))
} else if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
}
b, r = newReader("")
if _, err := r.ReadLiteral(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("[7}\r\nabcdefg")
if _, err := r.ReadLiteral(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("{7]\r\nabcdefg")
if _, err := r.ReadLiteral(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("{7.4}\r\nabcdefg")
if _, err := r.ReadLiteral(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("{7}abcdefg")
if _, err := r.ReadLiteral(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("{7}\rabcdefg")
if _, err := r.ReadLiteral(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("{7}\nabcdefg")
if _, err := r.ReadLiteral(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("{7}\r\nabcd")
if _, err := r.ReadLiteral(); err == nil {
t.Error("Invalid read didn't fail")
}
}
func TestReader_ReadQuotedString(t *testing.T) {
b, r := newReader("\"hello gopher\"\r\n")
if s, err := r.ReadQuotedString(); err != nil {
t.Error(err)
} else if s != "hello gopher" {
t.Error("Quoted string has not the expected value:", s)
} else {
if err := r.ReadCrlf(); err != nil && err != io.EOF {
t.Error("Cannot read CRLF after quoted string:", err)
}
if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
}
b, r = newReader("\"here's a backslash: \\\\, and here's a double quote: \\\" !\"\r\n")
if s, err := r.ReadQuotedString(); err != nil {
t.Error(err)
} else if s != "here's a backslash: \\, and here's a double quote: \" !" {
t.Error("Quoted string has not the expected value:", s)
}
b, r = newReader("")
if _, err := r.ReadQuotedString(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("hello gopher\"\r\n")
if _, err := r.ReadQuotedString(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("\"hello gopher\r\n")
if _, err := r.ReadQuotedString(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("\"hello \\gopher\"\r\n")
if _, err := r.ReadQuotedString(); err == nil {
t.Error("Invalid read didn't fail")
}
}
func TestReader_ReadFields(t *testing.T) {
b, r := newReader("field1 \"field2\"\r\n")
if fields, err := r.ReadFields(); err != nil {
t.Error(err)
} else if len(fields) != 2 {
t.Error("Expected 2 fields, but got", len(fields))
} else if s, ok := fields[0].(string); !ok || s != "field1" {
t.Error("Field 1 has not the expected value:", fields[0])
} else if s, ok := fields[1].(string); !ok || s != "field2" {
t.Error("Field 2 has not the expected value:", fields[1])
} else {
if err := r.ReadCrlf(); err != nil && err != io.EOF {
t.Error("Cannot read CRLF after fields:", err)
}
if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
}
b, r = newReader("")
if _, err := r.ReadFields(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("fi\"eld1 \"field2\"\r\n")
if _, err := r.ReadFields(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("field1 ")
if _, err := r.ReadFields(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("field1 (")
if _, err := r.ReadFields(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("field1\"field2\"\r\n")
if _, err := r.ReadFields(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("\"field1\"\"field2\"\r\n")
if _, err := r.ReadFields(); err == nil {
t.Error("Invalid read didn't fail")
}
}
func TestReader_ReadList(t *testing.T) {
b, r := newReader("(field1 \"field2\" {6}\r\nfield3 field4)")
if fields, err := r.ReadList(); err != nil {
t.Error(err)
} else if len(fields) != 4 {
t.Error("Expected 2 fields, but got", len(fields))
} else if s, ok := fields[0].(string); !ok || s != "field1" {
t.Error("Field 1 has not the expected value:", fields[0])
} else if s, ok := fields[1].(string); !ok || s != "field2" {
t.Error("Field 2 has not the expected value:", fields[1])
} else if literal, ok := fields[2].(imap.Literal); !ok {
t.Error("Field 3 has not the expected value:", fields[2])
} else if contents, err := ioutil.ReadAll(literal); err != nil {
t.Error(err)
} else if string(contents) != "field3" {
t.Error("Field 3 has not the expected value:", string(contents))
} else if s, ok := fields[3].(string); !ok || s != "field4" {
t.Error("Field 4 has not the expected value:", fields[3])
} else if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
b, r = newReader("()")
if fields, err := r.ReadList(); err != nil {
t.Error(err)
} else if len(fields) != 0 {
t.Error("Expected 0 fields, but got", len(fields))
} else if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
b, r = newReader("")
if _, err := r.ReadList(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("[field1 field2 field3)")
if _, err := r.ReadList(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("(field1 fie\"ld2 field3)")
if _, err := r.ReadList(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("(field1 field2 field3\r\n")
if _, err := r.ReadList(); err == nil {
t.Error("Invalid read didn't fail")
}
}
func TestReader_ReadLine(t *testing.T) {
b, r := newReader("field1 field2\r\n")
if fields, err := r.ReadLine(); err != nil {
t.Error(err)
} else if len(fields) != 2 {
t.Error("Expected 2 fields, but got", len(fields))
} else if s, ok := fields[0].(string); !ok || s != "field1" {
t.Error("Field 1 has not the expected value:", fields[0])
} else if s, ok := fields[1].(string); !ok || s != "field2" {
t.Error("Field 2 has not the expected value:", fields[1])
} else if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
b, r = newReader("")
if _, err := r.ReadLine(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("field1 field2\rabc")
if _, err := r.ReadLine(); err == nil {
t.Error("Invalid read didn't fail")
}
}
func TestReader_ReadRespCode(t *testing.T) {
b, r := newReader("[CAPABILITY NOOP STARTTLS]")
if code, fields, err := r.ReadRespCode(); err != nil {
t.Error(err)
} else if code != imap.CodeCapability {
t.Error("Response code has not the expected value:", code)
} else if len(fields) != 2 {
t.Error("Expected 2 fields, but got", len(fields))
} else if s, ok := fields[0].(string); !ok || s != "NOOP" {
t.Error("Field 1 has not the expected value:", fields[0])
} else if s, ok := fields[1].(string); !ok || s != "STARTTLS" {
t.Error("Field 2 has not the expected value:", fields[1])
} else if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
b, r = newReader("")
if _, _, err := r.ReadRespCode(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("{CAPABILITY NOOP STARTTLS]")
if _, _, err := r.ReadRespCode(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("[CAPABILITY NO\"OP STARTTLS]")
if _, _, err := r.ReadRespCode(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("[]")
if _, _, err := r.ReadRespCode(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("[{3}\r\nabc]")
if _, _, err := r.ReadRespCode(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("[CAPABILITY NOOP STARTTLS\r\n")
if _, _, err := r.ReadRespCode(); err == nil {
t.Error("Invalid read didn't fail")
}
}
func TestReader_ReadInfo(t *testing.T) {
b, r := newReader("I love potatoes.\r\n")
if info, err := r.ReadInfo(); err != nil {
t.Error(err)
} else if info != "I love potatoes." {
t.Error("Info has not the expected value:", info)
} else if b.Len() > 0 {
t.Error("Buffer is not empty after read")
}
b, r = newReader("I love potatoes.")
if _, err := r.ReadInfo(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("I love potatoes.\r")
if _, err := r.ReadInfo(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("I love potatoes.\n")
if _, err := r.ReadInfo(); err == nil {
t.Error("Invalid read didn't fail")
}
b, r = newReader("I love potatoes.\rabc")
if _, err := r.ReadInfo(); err == nil {
t.Error("Invalid read didn't fail")
}
}