aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vmime/exception.hpp1
-rw-r--r--src/vmime/messageParser.cpp19
-rw-r--r--src/vmime/net/imap/IMAPConnection.cpp50
-rw-r--r--src/vmime/net/imap/IMAPConnection.hpp2
-rw-r--r--src/vmime/net/imap/IMAPFolder.cpp21
-rw-r--r--src/vmime/net/imap/IMAPMessage.cpp19
-rw-r--r--src/vmime/net/imap/IMAPMessagePartContentHandler.cpp14
-rw-r--r--src/vmime/net/imap/IMAPParser.hpp6
-rw-r--r--src/vmime/net/imap/IMAPStore.cpp14
-rw-r--r--src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp15
-rw-r--r--src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp2
-rw-r--r--src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp14
-rw-r--r--src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp2
13 files changed, 134 insertions, 45 deletions
diff --git a/src/vmime/exception.hpp b/src/vmime/exception.hpp
index da0ec246..83f6c9c0 100644
--- a/src/vmime/exception.hpp
+++ b/src/vmime/exception.hpp
@@ -34,6 +34,7 @@
namespace vmime {
+typedef std::exception_ptr exception_ptr;
/** Base class for VMime exceptions.
*/
diff --git a/src/vmime/messageParser.cpp b/src/vmime/messageParser.cpp
index 21ac09bb..d7dd592a 100644
--- a/src/vmime/messageParser.cpp
+++ b/src/vmime/messageParser.cpp
@@ -82,12 +82,18 @@ void messageParser::parse(const shared_ptr <const message>& msg) {
// Date
shared_ptr <const headerField> recv = msg->getHeader()->findField(fields::RECEIVED);
+ static const datetime unsetDate;
+
+ m_date = unsetDate;
if (recv) {
m_date = recv->getValue <relay>()->getDate();
- } else {
+ }
+
+ // RECEIVED may in some cases contain no date at all
+ if (unsetDate == m_date) {
shared_ptr <const headerField> date = msg->getHeader()->findField(fields::DATE);
@@ -204,7 +210,16 @@ bool messageParser::findSubTextParts(
} else {
- // No "Content-type" field.
+ // No "Content-type" field. RFC2045 section 5.2 assumes this is TEXT/PLAIN
+ try {
+ shared_ptr <textPart> txtPart = textPartFactory::getInstance()->create(mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN));
+ txtPart->parse(msg, part, p);
+
+ m_textParts.push_back(txtPart);
+ }
+ catch (exceptions::no_factory_available& e) {
+ // Content-type not recognized.
+ }
}
}
diff --git a/src/vmime/net/imap/IMAPConnection.cpp b/src/vmime/net/imap/IMAPConnection.cpp
index df3da1c3..0e4020f1 100644
--- a/src/vmime/net/imap/IMAPConnection.cpp
+++ b/src/vmime/net/imap/IMAPConnection.cpp
@@ -51,14 +51,13 @@
#include <sstream>
-
// Helpers for service properties
#define GET_PROPERTY(type, prop) \
- (m_store.lock()->getInfos().getPropertyValue <type>(getSession(), \
- dynamic_cast <const IMAPServiceInfos&>(m_store.lock()->getInfos()).getProperties().prop))
+ (getStoreOrThrow()->getInfos().getPropertyValue <type>(getSession(), \
+ dynamic_cast <const IMAPServiceInfos&>(getStoreOrThrow()->getInfos()).getProperties().prop))
#define HAS_PROPERTY(prop) \
- (m_store.lock()->getInfos().hasProperty(getSession(), \
- dynamic_cast <const IMAPServiceInfos&>(m_store.lock()->getInfos()).getProperties().prop))
+ (getStoreOrThrow()->getInfos().hasProperty(getSession(), \
+ dynamic_cast <const IMAPServiceInfos&>(getStoreOrThrow()->getInfos()).getProperties().prop))
namespace vmime {
@@ -127,6 +126,10 @@ void IMAPConnection::connect() {
shared_ptr <IMAPStore> store = m_store.lock();
+ if (!store) {
+ throw exceptions::illegal_state("Store not found");
+ }
+
// Create the time-out handler
if (store->getTimeoutHandlerFactory()) {
m_timeoutHandler = store->getTimeoutHandlerFactory()->create();
@@ -244,6 +247,17 @@ void IMAPConnection::connect() {
setState(STATE_AUTHENTICATED);
}
+shared_ptr <IMAPStore> IMAPConnection::getStoreOrThrow() {
+
+ auto store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store not found");
+ }
+
+ return store;
+}
+
void IMAPConnection::authenticate() {
@@ -529,9 +543,15 @@ void IMAPConnection::startTLS() {
throw exceptions::command_error("STARTTLS", resp->getErrorLog(), "bad response");
}
+ auto store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store not found");
+ }
+
shared_ptr <tls::TLSSession> tlsSession = tls::TLSSession::create(
- m_store.lock()->getCertificateVerifier(),
- m_store.lock()->getSession()->getTLSProperties()
+ store->getCertificateVerifier(),
+ store->getSession()->getTLSProperties()
);
shared_ptr <tls::TLSSocket> tlsSocket = tlsSession->getSocket(m_socket);
@@ -701,11 +721,11 @@ shared_ptr <connectionInfos> IMAPConnection::getConnectionInfos() const {
void IMAPConnection::disconnect() {
- if (!isConnected()) {
+ bool wasConnected = isConnected();
+ internalDisconnect();
+ if (!wasConnected) {
throw exceptions::not_connected();
}
-
- internalDisconnect();
}
@@ -714,7 +734,9 @@ void IMAPConnection::internalDisconnect() {
if (isConnected()) {
IMAPCommand::LOGOUT()->send(dynamicCast <IMAPConnection>(shared_from_this()));
+ }
+ if (m_socket) {
m_socket->disconnect();
m_socket = null;
}
@@ -836,7 +858,13 @@ shared_ptr <IMAPStore> IMAPConnection::getStore() {
shared_ptr <session> IMAPConnection::getSession() {
- return m_store.lock()->getSession();
+ auto store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store not found");
+ }
+
+ return store->getSession();
}
diff --git a/src/vmime/net/imap/IMAPConnection.hpp b/src/vmime/net/imap/IMAPConnection.hpp
index 99750d49..d229d0f7 100644
--- a/src/vmime/net/imap/IMAPConnection.hpp
+++ b/src/vmime/net/imap/IMAPConnection.hpp
@@ -114,6 +114,8 @@ public:
private:
+ shared_ptr <IMAPStore> getStoreOrThrow();
+
void authenticate();
#if VMIME_HAVE_SASL_SUPPORT
void authenticateSASL();
diff --git a/src/vmime/net/imap/IMAPFolder.cpp b/src/vmime/net/imap/IMAPFolder.cpp
index 98bc05d8..f6c02697 100644
--- a/src/vmime/net/imap/IMAPFolder.cpp
+++ b/src/vmime/net/imap/IMAPFolder.cpp
@@ -80,7 +80,11 @@ IMAPFolder::~IMAPFolder() {
if (store) {
if (m_open) {
- close(false);
+ try {
+ close(false);
+ } catch (...) {
+ // Ignore exception here to make sure unregisterFolder is called
+ }
}
store->unregisterFolder(this);
@@ -290,9 +294,17 @@ void IMAPFolder::close(const bool expunge) {
shared_ptr <IMAPStore> store = m_store.lock();
if (!store) {
+ if (m_connection && m_connection->isConnected())
+ m_connection->disconnect();
+ m_connection = nullptr;
+ m_open = false;
throw exceptions::illegal_state("Store disconnected");
}
+ if (!m_connection || !m_connection->isConnected()) {
+ throw exceptions::illegal_state("Folder not connected");
+ }
+
if (!isOpen()) {
throw exceptions::illegal_state("Folder not open");
}
@@ -314,7 +326,7 @@ void IMAPFolder::close(const bool expunge) {
oldConnection->disconnect();
// Now use default store connection
- m_connection = m_store.lock()->connection();
+ m_connection = store->connection();
m_open = false;
m_mode = -1;
@@ -546,7 +558,6 @@ bool IMAPFolder::isOpen() const {
return m_open;
}
-
shared_ptr <message> IMAPFolder::getMessage(const size_t num) {
if (!isOpen()) {
@@ -1421,6 +1432,10 @@ void IMAPFolder::noop() {
throw exceptions::illegal_state("Store disconnected");
}
+ if (!m_connection || !m_connection->isConnected()) {
+ throw exceptions::illegal_state("Store disconnected");
+ }
+
IMAPCommand::NOOP()->send(m_connection);
scoped_ptr <IMAPParser::response> resp(m_connection->readResponse());
diff --git a/src/vmime/net/imap/IMAPMessage.cpp b/src/vmime/net/imap/IMAPMessage.cpp
index f74a4a4b..534727d4 100644
--- a/src/vmime/net/imap/IMAPMessage.cpp
+++ b/src/vmime/net/imap/IMAPMessage.cpp
@@ -318,6 +318,14 @@ size_t IMAPMessage::extractImpl(
shared_ptr <const IMAPFolder> folder = m_folder.lock();
+ if (!folder) {
+ throw exceptions::folder_not_found();
+ }
+
+ if (!folder->isOpen()) {
+ throw exceptions::illegal_state("Folder not open");
+ }
+
IMAPMessage_literalHandler literalHandler(os, progress);
if (length == 0) {
@@ -474,7 +482,6 @@ size_t IMAPMessage::extractImpl(
return literalHandler.getTarget()->getBytesWritten();
}
-
int IMAPMessage::processFetchResponse(
const fetchAttributes& options,
const IMAPParser::message_data& msgData
@@ -553,7 +560,7 @@ int IMAPMessage::processFetchResponse(
IMAPUtils::convertAddressList(*(env->env_reply_to), replyTo);
if (!replyTo.isEmpty()) {
- hdr->ReplyTo()->setValue(*(replyTo.getMailboxAt(0)));
+ hdr->ReplyTo()->setValue(replyTo.toAddressList());
}
// Cc
@@ -717,10 +724,16 @@ shared_ptr <vmime::message> IMAPMessage::getParsedMessage() {
} catch (exceptions::unfetched_object&) {
+ auto folder = m_folder.lock();
+
+ if (!folder) {
+ throw exceptions::folder_not_found();
+ }
+
std::vector <shared_ptr <message> > msgs;
msgs.push_back(dynamicCast <IMAPMessage>(shared_from_this()));
- m_folder.lock()->fetchMessages(
+ folder->fetchMessages(
msgs, fetchAttributes(fetchAttributes::STRUCTURE), /* progress */ NULL
);
diff --git a/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp b/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp
index 85f6cb6e..040d2ab0 100644
--- a/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp
+++ b/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp
@@ -36,7 +36,6 @@
#include "vmime/utility/outputStreamAdapter.hpp"
#include "vmime/utility/inputStreamStringAdapter.hpp"
-
namespace vmime {
namespace net {
namespace imap {
@@ -71,6 +70,9 @@ void IMAPMessagePartContentHandler::generate(
shared_ptr <IMAPMessage> msg = m_message.lock();
shared_ptr <messagePart> part = m_part.lock();
+ if (!msg || !part)
+ throw exceptions::message_not_found();
+
// Data is already encoded
if (isEncoded()) {
@@ -140,6 +142,9 @@ void IMAPMessagePartContentHandler::extract(
shared_ptr <IMAPMessage> msg = m_message.lock();
shared_ptr <messagePart> part = m_part.lock();
+ if (!msg || !part)
+ throw exceptions::message_not_found();
+
// No decoding to perform
if (!isEncoded()) {
@@ -172,12 +177,17 @@ void IMAPMessagePartContentHandler::extractRaw(
shared_ptr <IMAPMessage> msg = m_message.lock();
shared_ptr <messagePart> part = m_part.lock();
+ if (!msg || !part)
+ throw exceptions::message_not_found();
+
msg->extractPart(part, os, progress);
}
size_t IMAPMessagePartContentHandler::getLength() const {
-
+ shared_ptr <messagePart> part = m_part.lock();
+ if (!part)
+ throw exceptions::message_not_found();
return m_part.lock()->getSize();
}
diff --git a/src/vmime/net/imap/IMAPParser.hpp b/src/vmime/net/imap/IMAPParser.hpp
index 409362da..2a37b9cd 100644
--- a/src/vmime/net/imap/IMAPParser.hpp
+++ b/src/vmime/net/imap/IMAPParser.hpp
@@ -4912,6 +4912,9 @@ public:
shared_ptr <timeoutHandler> toh = m_timeoutHandler.lock();
shared_ptr <socket> sok = m_socket.lock();
+ if (!sok)
+ throw exceptions::illegal_state("Store disconnected");
+
if (toh) {
toh->resetTimeOut();
}
@@ -4957,6 +4960,9 @@ public:
shared_ptr <timeoutHandler> toh = m_timeoutHandler.lock();
shared_ptr <socket> sok = m_socket.lock();
+ if (!sok)
+ throw exceptions::illegal_state("Store disconnected");
+
if (m_progress) {
m_progress->start(count);
}
diff --git a/src/vmime/net/imap/IMAPStore.cpp b/src/vmime/net/imap/IMAPStore.cpp
index eafa4442..be5c4de7 100644
--- a/src/vmime/net/imap/IMAPStore.cpp
+++ b/src/vmime/net/imap/IMAPStore.cpp
@@ -179,9 +179,7 @@ shared_ptr <IMAPConnection> IMAPStore::getConnection() {
void IMAPStore::disconnect() {
- if (!isConnected()) {
- throw exceptions::not_connected();
- }
+ bool wasConnected = isConnected();
for (std::list <IMAPFolder*>::iterator it = m_folders.begin() ;
it != m_folders.end() ; ++it) {
@@ -191,10 +189,14 @@ void IMAPStore::disconnect() {
m_folders.clear();
+ if (m_connection) {
+ m_connection->disconnect();
+ m_connection = null;
+ }
- m_connection->disconnect();
-
- m_connection = null;
+ if (!wasConnected) {
+ throw exceptions::not_connected();
+ }
}
diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp
index 53e4eaee..97466fc5 100644
--- a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp
+++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp
@@ -66,7 +66,7 @@ TLSSocket_GnuTLS::TLSSocket_GnuTLS(
: m_session(session),
m_wrapped(sok),
m_connected(false),
- m_ex(NULL),
+ m_ex(nullptr),
m_status(0),
m_errno(0) {
@@ -407,7 +407,7 @@ ssize_t TLSSocket_GnuTLS::gnutlsPushFunc(
// Workaround for non-portable behaviour when throwing C++ exceptions
// from C functions (GNU TLS)
- sok->m_ex = e.clone();
+ sok->m_ex = std::current_exception();
return -1;
}
}
@@ -440,7 +440,7 @@ ssize_t TLSSocket_GnuTLS::gnutlsPullFunc(
// Workaround for non-portable behaviour when throwing C++ exceptions
// from C functions (GNU TLS)
- sok->m_ex = e.clone();
+ sok->m_ex = std::current_exception();
return -1;
}
}
@@ -525,18 +525,15 @@ shared_ptr <security::cert::certificateChain> TLSSocket_GnuTLS::getPeerCertifica
void TLSSocket_GnuTLS::throwException() {
- if (m_ex) {
- throw *m_ex;
+ if (!!m_ex) {
+ std::rethrow_exception(m_ex);
}
}
void TLSSocket_GnuTLS::resetException() {
- if (m_ex) {
- delete m_ex;
- m_ex = NULL;
- }
+ m_ex = nullptr;
}
diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp
index 0ac3e700..a90379fd 100644
--- a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp
+++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp
@@ -109,7 +109,7 @@ private:
byte_t m_buffer[65536];
- exception* m_ex;
+ exception_ptr m_ex;
unsigned int m_status;
int m_errno;
diff --git a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp
index 978f0ca6..bbda81b3 100644
--- a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp
+++ b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp
@@ -104,7 +104,7 @@ TLSSocket_OpenSSL::TLSSocket_OpenSSL(
m_connected(false),
m_ssl(0),
m_status(0),
- m_ex() {
+ m_ex(nullptr) {
}
@@ -309,7 +309,7 @@ size_t TLSSocket_OpenSSL::receiveRaw(byte_t* buffer, const size_t count) {
ERR_clear_error();
int rc = SSL_read(m_ssl, buffer, static_cast <int>(count));
- if (m_ex.get()) {
+ if (!!m_ex) {
internalThrow();
}
@@ -379,7 +379,7 @@ size_t TLSSocket_OpenSSL::sendRawNonBlocking(const byte_t* buffer, const size_t
ERR_clear_error();
int rc = SSL_write(m_ssl, buffer, static_cast <int>(count));
- if (m_ex.get()) {
+ if (!!m_ex) {
internalThrow();
}
@@ -511,8 +511,8 @@ shared_ptr <security::cert::certificateChain> TLSSocket_OpenSSL::getPeerCertific
void TLSSocket_OpenSSL::internalThrow() {
- if (m_ex.get()) {
- throw *m_ex;
+ if (!!m_ex) {
+ std::rethrow_exception(m_ex);
}
}
@@ -630,7 +630,7 @@ int TLSSocket_OpenSSL::bio_write(BIO* bio, const char* buf, int len) {
} catch (exception& e) {
// Workaround for passing C++ exceptions from C BIO functions
- sok->m_ex.reset(e.clone());
+ sok->m_ex = std::current_exception();
return -1;
}
}
@@ -667,7 +667,7 @@ int TLSSocket_OpenSSL::bio_read(BIO* bio, char* buf, int len) {
} catch (exception& e) {
// Workaround for passing C++ exceptions from C BIO functions
- sok->m_ex.reset(e.clone());
+ sok->m_ex = std::current_exception();
return -1;
}
}
diff --git a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp
index e30df680..62fd5f0d 100644
--- a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp
+++ b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp
@@ -125,7 +125,7 @@ private:
unsigned int m_status;
// Last exception thrown from C BIO functions
- scoped_ptr <exception> m_ex;
+ exception_ptr m_ex;
};