FetchCommand.Collect/Close/Next stuck when no result is returned
IsSkyfalls opened this issue · comments
Lines 170 to 175 in dffd45a
Both
FetchCommand.Collect
and FetchCommand.Close
calls Next
. When Fetch
/UIDFetch
didn't return any result, cmd.prev
will still be nil. Then the channel read will block indefinitely. Discovered when passing nil UIDSet
accidentally on v2.0.0-alpha.7.Then the channel read will block indefinitely.
This shouldn't be the case:
Line 468 in dffd45a
Is this a real bug you're hitting, or just some concern while reading the code? If it's a real bug, can you obtain a backtrace?
Sorry, I'm new to this library and haven't looked at a lot of code yet. I was able to reproduce reliably with the code below. But when I set a breakpoint in Client.completeCommand
it works as expected, so deadlock/race condition?
func main() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
options := imapclient.Options{
DebugWriter: os.Stderr,
}
client, _ := imapclient.DialTLS("imap.example.com:993", &options)
client.Login("------", "----").Wait()
//client.Select("INBOX", nil).Wait() // not required
client.UIDFetch(imap.SeqSetNum(), &imap.FetchOptions{}).Collect()
}
T1 LOGIN "----" "-----"
* OK IMAP Server is ready
T2 CAPABILITY
T1 OK LOGIN completed.
T3 CAPABILITY
* CAPABILITY IMAP4rev1 LITERAL+ CHILDREN I18NLEVEL=1 NAMESPACE IDLE ENABLE CONDSTORE QRESYNC ANNOTATION AUTH=PLAIN SASL-IR RIGHTS= WITHIN ESEARCH ESORT SEARCHRES SORT MOVE UIDPLUS UNSELECT COMPRESS=DEFLATE
T2 OK CAPABILITY completed.
* CAPABILITY IMAP4rev1 LITERAL+ CHILDREN I18NLEVEL=1 NAMESPACE IDLE ENABLE CONDSTORE QRESYNC ANNOTATION AUTH=PLAIN SASL-IR RIGHTS= WITHIN ESEARCH ESORT SEARCHRES SORT MOVE UIDPLUS UNSELECT COMPRESS=DEFLATE
T3 OK CAPABILITY completed.
related backtrace:
goroutine 1 [chan receive]:
github.com/emersion/go-imap/v2/imapclient.(*FetchCommand).Next(0xc000304000)
/home/skyfalls/go/pkg/mod/github.com/emersion/go-imap/v2@v2.0.0-alpha.7/imapclient/fetch.go:174 +0x71
github.com/emersion/go-imap/v2/imapclient.(*FetchCommand).Collect(0xc000304000)
/home/skyfalls/go/pkg/mod/github.com/emersion/go-imap/v2@v2.0.0-alpha.7/imapclient/fetch.go:200 +0x105
main.main()
/home/skyfalls/Projects/asterisk/main.go:154 +0x1c5
goroutine 9 [IO wait]:
internal/poll.runtime_pollWait(0xb0c880?, 0x72)
/usr/lib/go/src/runtime/netpoll.go:343 +0x3c
internal/poll.(*pollDesc).wait(0xc000136220, 0x72, 0x0)
/usr/lib/go/src/internal/poll/fd_poll_runtime.go:84 +0x7e
internal/poll.(*pollDesc).waitRead(0xc000136220, 0x0)
/usr/lib/go/src/internal/poll/fd_poll_runtime.go:89 +0x31
internal/poll.(*FD).Read(0xc000136200, {0xc00021b500, 0x1500, 0x1500})
/usr/lib/go/src/internal/poll/fd_unix.go:164 +0x40f
net.(*netFD).Read(0xc000136200, {0xc00021b500, 0x1500, 0x1500})
/usr/lib/go/src/net/fd_posix.go:55 +0x73
net.(*conn).Read(0xc000044088, {0xc00021b500, 0x1500, 0x1500})
/usr/lib/go/src/net/net.go:179 +0x9d
crypto/tls.(*atLeastReader).Read(0xc000316018, {0xc00021b500, 0x1500, 0x1500})
/usr/lib/go/src/crypto/tls/conn.go:805 +0xc2
bytes.(*Buffer).ReadFrom(0xc00012c9a8, {0x961500, 0xc000316018})
/usr/lib/go/src/bytes/buffer.go:211 +0x13c
crypto/tls.(*Conn).readFromUntil(0xc00012c700, {0x9615c0, 0xc000044088}, 0x5)
/usr/lib/go/src/crypto/tls/conn.go:827 +0x169
crypto/tls.(*Conn).readRecordOrCCS(0xc00012c700, 0x0)
/usr/lib/go/src/crypto/tls/conn.go:625 +0x259
crypto/tls.(*Conn).readRecord(0xc00012c700)
/usr/lib/go/src/crypto/tls/conn.go:587 +0x25
crypto/tls.(*Conn).Read(0xc00012c700, {0xc000225000, 0x1000, 0x1000})
/usr/lib/go/src/crypto/tls/conn.go:1369 +0x1ea
io.(*teeReader).Read(0xc000017060, {0xc000225000, 0x1000, 0x1000})
/usr/lib/go/src/io/io.go:620 +0x83
bufio.(*Reader).fill(0xc00007f860)
/usr/lib/go/src/bufio/bufio.go:113 +0x271
bufio.(*Reader).ReadByte(0xc00007f860)
/usr/lib/go/src/bufio/bufio.go:272 +0x9f
github.com/emersion/go-imap/v2/internal/imapwire.(*Decoder).EOF(0xc0001e2630)
/home/skyfalls/go/pkg/mod/github.com/emersion/go-imap/v2@v2.0.0-alpha.7/internal/imapwire/decoder.go:108 +0x37
github.com/emersion/go-imap/v2/imapclient.(*Client).read(0xc0001800f0)
/home/skyfalls/go/pkg/mod/github.com/emersion/go-imap/v2@v2.0.0-alpha.7/imapclient/client.go:517 +0x125
created by github.com/emersion/go-imap/v2/imapclient.New in goroutine 1
/home/skyfalls/go/pkg/mod/github.com/emersion/go-imap/v2@v2.0.0-alpha.7/imapclient/client.go:167 +0x425
Hm right. So the issue here is that the encoder refuses to write the invalid seqset:
go-imap/internal/imapwire/encoder.go
Line 164 in dffd45a
Later this is caught here:
Line 1000 in dffd45a
However this codepath doesn't close the channel.