net/tls: Refactored re-throwing exceptions so that the original exception class is retained. With the old code, a socket_exception was re-thrown as vmime::exception.
IMAPFolder.cpp: Fixed a use-after-free in case of an exception in close().
This commit is contained in:
parent
47c6f35f5a
commit
39a0cfbcc3
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
namespace vmime {
|
namespace vmime {
|
||||||
|
|
||||||
|
typedef std::exception_ptr exception_ptr;
|
||||||
|
|
||||||
/** Base class for VMime exceptions.
|
/** Base class for VMime exceptions.
|
||||||
*/
|
*/
|
||||||
|
@ -80,7 +80,11 @@ IMAPFolder::~IMAPFolder() {
|
|||||||
if (store) {
|
if (store) {
|
||||||
|
|
||||||
if (m_open) {
|
if (m_open) {
|
||||||
|
try {
|
||||||
close(false);
|
close(false);
|
||||||
|
} catch (...) {
|
||||||
|
// Ignore exception here to make sure unregisterFolder is called
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
store->unregisterFolder(this);
|
store->unregisterFolder(this);
|
||||||
|
@ -66,7 +66,7 @@ TLSSocket_GnuTLS::TLSSocket_GnuTLS(
|
|||||||
: m_session(session),
|
: m_session(session),
|
||||||
m_wrapped(sok),
|
m_wrapped(sok),
|
||||||
m_connected(false),
|
m_connected(false),
|
||||||
m_ex(NULL),
|
m_ex(nullptr),
|
||||||
m_status(0),
|
m_status(0),
|
||||||
m_errno(0) {
|
m_errno(0) {
|
||||||
|
|
||||||
@ -407,7 +407,7 @@ ssize_t TLSSocket_GnuTLS::gnutlsPushFunc(
|
|||||||
|
|
||||||
// Workaround for non-portable behaviour when throwing C++ exceptions
|
// Workaround for non-portable behaviour when throwing C++ exceptions
|
||||||
// from C functions (GNU TLS)
|
// from C functions (GNU TLS)
|
||||||
sok->m_ex = e.clone();
|
sok->m_ex = std::current_exception();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,7 +440,7 @@ ssize_t TLSSocket_GnuTLS::gnutlsPullFunc(
|
|||||||
|
|
||||||
// Workaround for non-portable behaviour when throwing C++ exceptions
|
// Workaround for non-portable behaviour when throwing C++ exceptions
|
||||||
// from C functions (GNU TLS)
|
// from C functions (GNU TLS)
|
||||||
sok->m_ex = e.clone();
|
sok->m_ex = std::current_exception();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -525,18 +525,15 @@ shared_ptr <security::cert::certificateChain> TLSSocket_GnuTLS::getPeerCertifica
|
|||||||
|
|
||||||
void TLSSocket_GnuTLS::throwException() {
|
void TLSSocket_GnuTLS::throwException() {
|
||||||
|
|
||||||
if (m_ex) {
|
if (!!m_ex) {
|
||||||
throw *m_ex;
|
std::rethrow_exception(m_ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TLSSocket_GnuTLS::resetException() {
|
void TLSSocket_GnuTLS::resetException() {
|
||||||
|
|
||||||
if (m_ex) {
|
m_ex = nullptr;
|
||||||
delete m_ex;
|
|
||||||
m_ex = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ private:
|
|||||||
|
|
||||||
byte_t m_buffer[65536];
|
byte_t m_buffer[65536];
|
||||||
|
|
||||||
exception* m_ex;
|
exception_ptr m_ex;
|
||||||
|
|
||||||
unsigned int m_status;
|
unsigned int m_status;
|
||||||
int m_errno;
|
int m_errno;
|
||||||
|
@ -104,7 +104,7 @@ TLSSocket_OpenSSL::TLSSocket_OpenSSL(
|
|||||||
m_connected(false),
|
m_connected(false),
|
||||||
m_ssl(0),
|
m_ssl(0),
|
||||||
m_status(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();
|
ERR_clear_error();
|
||||||
int rc = SSL_read(m_ssl, buffer, static_cast <int>(count));
|
int rc = SSL_read(m_ssl, buffer, static_cast <int>(count));
|
||||||
|
|
||||||
if (m_ex.get()) {
|
if (!!m_ex) {
|
||||||
internalThrow();
|
internalThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,7 +379,7 @@ size_t TLSSocket_OpenSSL::sendRawNonBlocking(const byte_t* buffer, const size_t
|
|||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
int rc = SSL_write(m_ssl, buffer, static_cast <int>(count));
|
int rc = SSL_write(m_ssl, buffer, static_cast <int>(count));
|
||||||
|
|
||||||
if (m_ex.get()) {
|
if (!!m_ex) {
|
||||||
internalThrow();
|
internalThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,8 +511,8 @@ shared_ptr <security::cert::certificateChain> TLSSocket_OpenSSL::getPeerCertific
|
|||||||
|
|
||||||
void TLSSocket_OpenSSL::internalThrow() {
|
void TLSSocket_OpenSSL::internalThrow() {
|
||||||
|
|
||||||
if (m_ex.get()) {
|
if (!!m_ex) {
|
||||||
throw *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) {
|
} catch (exception& e) {
|
||||||
|
|
||||||
// Workaround for passing C++ exceptions from C BIO functions
|
// Workaround for passing C++ exceptions from C BIO functions
|
||||||
sok->m_ex.reset(e.clone());
|
sok->m_ex = std::current_exception();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -667,7 +667,7 @@ int TLSSocket_OpenSSL::bio_read(BIO* bio, char* buf, int len) {
|
|||||||
} catch (exception& e) {
|
} catch (exception& e) {
|
||||||
|
|
||||||
// Workaround for passing C++ exceptions from C BIO functions
|
// Workaround for passing C++ exceptions from C BIO functions
|
||||||
sok->m_ex.reset(e.clone());
|
sok->m_ex = std::current_exception();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ private:
|
|||||||
unsigned int m_status;
|
unsigned int m_status;
|
||||||
|
|
||||||
// Last exception thrown from C BIO functions
|
// Last exception thrown from C BIO functions
|
||||||
scoped_ptr <exception> m_ex;
|
exception_ptr m_ex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user