Skip to content

Commit

Permalink
Fix uncaught exception in FrameReader
Browse files Browse the repository at this point in the history
  • Loading branch information
Fanda Vacek authored and fvacek committed Oct 22, 2024
1 parent 7b052a3 commit 52b8c27
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 79 deletions.
7 changes: 2 additions & 5 deletions libshvchainpack/include/shv/chainpack/abstractstreamreader.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,16 @@

namespace shv::chainpack {

class SHVCHAINPACK_DECL_EXPORT ParseException : public std::exception
class SHVCHAINPACK_DECL_EXPORT ParseException : public std::runtime_error
{
using Super = std::exception;
using Super = std::runtime_error;
public:
ParseException(int err_code, const std::string &msg, long long pos, const std::string &dump);

const char *what() const noexcept override;
int errCode() const;
long long pos() const;
const std::string& msg() const;
private:
int m_errCode;
std::string m_msg;
long long m_pos = -1;
};

Expand Down
7 changes: 2 additions & 5 deletions libshvchainpack/include/shv/chainpack/exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@

namespace shv::chainpack {

class SHVCHAINPACK_DECL_EXPORT Exception : public std::exception
class SHVCHAINPACK_DECL_EXPORT Exception : public std::runtime_error
{
using Super = std::runtime_error;
public:
static constexpr bool Throw = true;
public:
Expand All @@ -22,17 +23,13 @@ class SHVCHAINPACK_DECL_EXPORT Exception : public std::exception
std::string message() const;
std::string where() const;
shv::chainpack::RpcValue data() const;
const char* what() const noexcept override;
static void setAbortOnException(bool on);
static bool isAbortOnException();
protected:
void makeWhat();
protected:
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static bool s_abortOnException;
std::string m_msg;
shv::chainpack::RpcValue m_data;
std::string m_what;
std::string m_where;
};

Expand Down
28 changes: 11 additions & 17 deletions libshvchainpack/src/abstractstreamreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@ size_t unpack_underflow_handler(ccpcp_unpack_context *ctx)
}

ParseException::ParseException(int err_code, const std::string &msg, long long pos, const std::string &dump)
: m_errCode(err_code), m_msg(msg), m_pos(pos)
: Super([&msg, &dump, err_code, pos](){
auto res = std::string("Parse error: ") + std::to_string(err_code) + " " + ccpcp_error_string(err_code)
+ " at pos: " + std::to_string(pos)
+ " - " + msg;
if (!dump.empty()) {
res += " near to:\n" + dump;
}
return res;
}())
, m_errCode(err_code)
, m_pos(pos)
{
m_msg = std::string("Parse error: ") + std::to_string(m_errCode) + " " + ccpcp_error_string(m_errCode)
+ " at pos: " + std::to_string(m_pos)
+ " - " + m_msg;
if (!dump.empty()) {
m_msg += " near to:\n" + dump;
}
}

int ParseException::errCode() const
Expand All @@ -38,16 +42,6 @@ long long ParseException::pos() const
return m_pos;
}

const std::string& ParseException::msg() const
{
return m_msg;
}

const char *ParseException::what() const noexcept
{
return m_msg.data();
}

AbstractStreamReader::AbstractStreamReader(std::istream &in)
: m_in(in)
{
Expand Down
37 changes: 14 additions & 23 deletions libshvchainpack/src/exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,22 @@ Exception::Exception(const std::string& _msg, const std::string& _where, const c
{
}

Exception::Exception(const std::string &_msg, const RpcValue &_data, const std::string &_where, const char *_log_topic)
: m_msg(_msg)
, m_data(_data)
, m_where(_where)
Exception::Exception(const std::string &msg, const RpcValue &data, const std::string &where, const char *log_topic)
: Super([&msg, &data](){
if(data.isValid()) {
return msg + " data: " + data.toCpon();
}
return msg;
}())
, m_msg(msg)
, m_data(data)
, m_where(where)
{
makeWhat();
if(isAbortOnException() || !_where.empty() || (_log_topic && *_log_topic)) {
if(_log_topic && *_log_topic)
nCError(_log_topic) << "SHV_EXCEPTION:" << _where << m_what;
if(isAbortOnException() || !where.empty() || (log_topic && *log_topic)) {
if(log_topic && *log_topic)
nCError(log_topic) << "SHV_EXCEPTION:" << where << what();
else
nError() << "SHV_EXCEPTION:" << _where << m_what;
nError() << "SHV_EXCEPTION:" << where << what();
}
if(isAbortOnException())
std::abort();
Expand All @@ -50,12 +55,6 @@ shv::chainpack::RpcValue Exception::data() const
return m_data;
}


const char *Exception::what() const noexcept
{
return m_what.c_str();
}

void Exception::Exception::setAbortOnException(bool on)
{
s_abortOnException = on;
Expand All @@ -66,12 +65,4 @@ bool Exception::Exception::isAbortOnException()
return s_abortOnException;
}

void Exception::makeWhat()
{
m_what = m_msg;
if(m_data.isValid()) {
m_what += " data: " + m_data.toCpon();
}
}

} // namespace shv
2 changes: 1 addition & 1 deletion libshvchainpack/src/rpcdriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void RpcDriver::onFrameDataRead(const std::string &frame_data)
onRpcFrameReceived(std::move(frame));
}
catch (const ParseException &e) {
logRpcDataW() << "ERROR - Rpc frame data corrupted:" << e.msg();
logRpcDataW() << "ERROR - Rpc frame data corrupted:" << e.what();
//logRpcDataW() << "The error occured in data:\n" << shv::chainpack::utils::hexDump(m_readData.data(), 1024);
onParseDataException(e);
return;
Expand Down
3 changes: 0 additions & 3 deletions libshvcore/include/shv/core/exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
#include <shv/core/shvcoreglobal.h>
#include <shv/core/utils.h>

#include <stdexcept>
#include <string>

#include <shv/chainpack/exception.h>

namespace shv::core {
Expand Down
2 changes: 1 addition & 1 deletion libshvcoreqt/include/shv/coreqt/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ auto findLongestPrefix(const QMap<QString, Value>& map, QString value) -> typena

return map.end();
}
}

}
} // namespace coreqt
} // namespace shv

19 changes: 13 additions & 6 deletions libshviotqt/src/rpc/localsocket.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <shv/iotqt/rpc/localsocket.h>

#include <shv/chainpack/utils.h>
#include <shv/iotqt/rpc/serialportsocket.h>

#include <QLocalSocket>
Expand Down Expand Up @@ -142,13 +143,19 @@ void LocalSocket::ignoreSslErrors()
void LocalSocket::onDataReadyRead()
{
auto ba = m_socket->readAll();
std::string_view escaped_data(ba.constData(), ba.size());
for (auto rqid : m_frameReader->addData(escaped_data)) {
emit responseMetaReceived(rqid);
try {
std::string_view escaped_data(ba.constData(), ba.size());
for (auto rqid : m_frameReader->addData(escaped_data)) {
emit responseMetaReceived(rqid);
}
emit dataChunkReceived();
if (!m_frameReader->isEmpty()) {
emit readyRead();
}
}
emit dataChunkReceived();
if (!m_frameReader->isEmpty()) {
emit readyRead();
catch (const std::runtime_error &e) {
shvWarning() << "Corrupted meta data received:\n" << shv::chainpack::utils::hexDump(std::string_view(ba.constData(), std::min(ba.size(), static_cast<decltype(ba.size())>(64))));
emit error(QAbstractSocket::SocketError::UnknownSocketError);
}
}

Expand Down
18 changes: 12 additions & 6 deletions libshviotqt/src/rpc/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,13 +317,19 @@ void TcpSocket::ignoreSslErrors()
void TcpSocket::onDataReadyRead()
{
auto ba = m_socket->readAll();
std::string_view data(ba.constData(), ba.size());
for (auto rqid : m_frameReader->addData(data)) {
emit responseMetaReceived(rqid);
try {
std::string_view data(ba.constData(), ba.size());
for (auto rqid : m_frameReader->addData(data)) {
emit responseMetaReceived(rqid);
}
emit dataChunkReceived();
if (!m_frameReader->isEmpty()) {
emit readyRead();
}
}
emit dataChunkReceived();
if (!m_frameReader->isEmpty()) {
emit readyRead();
catch (const std::runtime_error &e) {
shvWarning() << "Corrupted meta data received:\n" << shv::chainpack::utils::hexDump(std::string_view(ba.constData(), std::min(ba.size(), static_cast<decltype(ba.size())>(64))));
emit error(QAbstractSocket::SocketError::UnknownSocketError);
}
}

Expand Down
35 changes: 23 additions & 12 deletions libshviotqt/src/rpc/websocket.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <shv/iotqt/rpc/websocket.h>

#include <shv/chainpack/utils.h>
#include <shv/coreqt/log.h>

#include <QWebSocket>
Expand Down Expand Up @@ -83,25 +84,35 @@ void WebSocket::flushWriteBuffer()
void WebSocket::onTextMessageReceived(const QString &message)
{
shvDebug() << "text message received:" << message;
auto ba = message.toUtf8();
for (auto rqid : m_frameReader->addData(std::string_view(ba.constData(), ba.size()))) {
emit responseMetaReceived(rqid);
auto data = message.toUtf8();
try {
for (auto rqid : m_frameReader->addData(std::string_view(data.constData(), data.size()))) {
emit responseMetaReceived(rqid);
}
emit dataChunkReceived();
if (!m_frameReader->isEmpty()) {
emit readyRead();
}
}
emit dataChunkReceived();
if (!m_frameReader->isEmpty()) {
emit readyRead();
catch (const std::runtime_error &e) {
shvWarning() << "Corrupted meta data received:\n" << shv::chainpack::utils::hexDump(std::string_view(data.constData(), std::min(data.size(), static_cast<decltype(data.size())>(64))));
}
}

void WebSocket::onBinaryMessageReceived(const QByteArray &message)
{
shvDebug() << "binary message received:" << message;
for (auto rqid : m_frameReader->addData(std::string_view(message.constData(), message.size()))) {
emit responseMetaReceived(rqid);
try {
shvDebug() << "binary message received:" << message;
for (auto rqid : m_frameReader->addData(std::string_view(message.constData(), message.size()))) {
emit responseMetaReceived(rqid);
}
emit dataChunkReceived();
if (!m_frameReader->isEmpty()) {
emit readyRead();
}
}
emit dataChunkReceived();
if (!m_frameReader->isEmpty()) {
emit readyRead();
catch (const std::runtime_error &e) {
shvWarning() << "Corrupted meta data received:\n" << shv::chainpack::utils::hexDump(std::string_view(message.constData(), std::min(message.size(), static_cast<decltype(message.size())>(64))));
}
}

Expand Down

0 comments on commit 52b8c27

Please sign in to comment.