From fa94c7d6a528d0942e8426178fcdf3799d2a57ec Mon Sep 17 00:00:00 2001
From: Peter Kosyh
Date: Thu, 22 Nov 2018 09:53:55 +0300
Subject: [PATCH] mail: IMAP fix recv forever loop on server close connection
When reading stream from closed (by server) TCP socket throw StreamException (not ParseException).
This fixes forever loop in Protocol::HandleResponse on server disconnect.
This patch fixes #14710
Change-Id: I29e9830b360cb56cb1ef037c0378d64422075c4d
Reviewed-on: https://review.haiku-os.org/724
Reviewed-by: waddlesplash
---
.../inbound_protocols/imap/imap_lib/Response.cpp | 11 ++++++-----
.../inbound_protocols/imap/imap_lib/Response.h | 5 +++--
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.cpp b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.cpp
index 81abd61fb6..8322c24e3c 100644
--- a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.cpp
+++ b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.cpp
@@ -450,7 +450,8 @@ Response::~Response()
void
-Response::Parse(BDataIO& stream, LiteralHandler* handler) throw(ParseException)
+Response::Parse(BDataIO& stream, LiteralHandler* handler)
+ throw(ParseException, StreamException)
{
MakeEmpty();
fLiteralHandler = handler;
@@ -604,7 +605,7 @@ Response::ParseLiteral(ArgumentList& arguments, BDataIO& stream)
ssize_t bytesRead = stream.Read(buffer + totalRead,
size - totalRead);
if (bytesRead == 0)
- throw ParseException("Unexpected end of literal");
+ throw StreamException(B_IO_ERROR);
if (bytesRead < 0)
throw StreamException(bytesRead);
@@ -706,7 +707,7 @@ Response::Read(BDataIO& stream)
}
if (bytesRead == 0)
- throw ParseException("Unexpected end of stream");
+ throw StreamException(B_IO_ERROR);
throw StreamException(bytesRead);
}
@@ -721,7 +722,7 @@ Response::_SkipLiteral(BDataIO& stream, size_t size)
size_t toRead = std::min(sizeof(buffer), size - totalRead);
ssize_t bytesRead = stream.Read(buffer, toRead);
if (bytesRead == 0)
- throw ParseException("Unexpected end of literal");
+ throw StreamException(B_IO_ERROR);
if (bytesRead < 0)
throw StreamException(bytesRead);
@@ -762,7 +763,7 @@ ResponseParser::SetLiteralHandler(LiteralHandler* handler)
status_t
ResponseParser::NextResponse(Response& response, bigtime_t timeout)
- throw(ParseException)
+ throw(ParseException, StreamException)
{
response.Parse(*fStream, fLiteralHandler);
return B_OK;
diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.h b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.h
index 143817100d..28305d9b70 100644
--- a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.h
+++ b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.h
@@ -145,7 +145,7 @@ public:
~Response();
void Parse(BDataIO& stream, LiteralHandler* handler)
- throw(ParseException);
+ throw(ParseException, StreamException);
bool IsUntagged() const { return fTag == 0; }
uint32 Tag() const { return fTag; }
@@ -194,7 +194,8 @@ public:
void SetLiteralHandler(LiteralHandler* handler);
status_t NextResponse(Response& response,
- bigtime_t timeout) throw(ParseException);
+ bigtime_t timeout)
+ throw(ParseException, StreamException);
private:
ResponseParser(const ResponseParser& other);