Skip to content

Commit

Permalink
Added error handling.
Browse files Browse the repository at this point in the history
Without this fix, a segv will happen in certain error conditions where
the reply_obj == nullptr.
  • Loading branch information
bveldhoen committed Jan 26, 2016
1 parent b7a938a commit 0be0162
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 9 deletions.
2 changes: 1 addition & 1 deletion include/redox/client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ class Redox {
template <class ReplyT> friend void Command<ReplyT>::free();

// Access to call disconnectedCallback
template <class ReplyT> friend void Command<ReplyT>::processReply(redisReply *r);
template <class ReplyT> friend void Command<ReplyT>::processReply(redisReply *r, const std::string& errorMessage);
};

// ------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion include/redox/command.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ template <class ReplyT> class Command {
bool free_memory, log::Logger &logger);

// Handles a new reply from the server
void processReply(redisReply *r);
void processReply(redisReply *r, const std::string& errorMessage = std::string());

// Invoke a user callback from the reply object. This method is specialized
// for each ReplyT of Command.
Expand Down
20 changes: 15 additions & 5 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,17 +365,27 @@ template <class ReplyT> Command<ReplyT> *Redox::findCommand(long id) {
template <class ReplyT>
void Redox::commandCallback(redisAsyncContext *ctx, void *r, void *privdata) {

Redox *rdx = (Redox *)ctx->data;
long id = (long)privdata;
redisReply *reply_obj = (redisReply *)r;
Redox *rdx = reinterpret_cast<Redox*>(ctx->data);
if (rdx == nullptr) {
return;
}

redisReply *reply_obj = reinterpret_cast<redisReply*>(r);

long id = (long)privdata;
Command<ReplyT> *c = rdx->findCommand<ReplyT>(id);
if (c == nullptr) {
freeReplyObject(reply_obj);
if (reply_obj != nullptr) {
freeReplyObject(reply_obj);
}
return;
}

c->processReply(reply_obj);
if (ctx->err) {
c->processReply(nullptr, std::string(ctx->errstr));
} else {
c->processReply(reply_obj);
}
}

template <class ReplyT> bool Redox::submitToServer(Command<ReplyT> *c) {
Expand Down
9 changes: 7 additions & 2 deletions src/command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,19 @@ template <class ReplyT> void Command<ReplyT>::wait() {
waiting_done_ = {false};
}

template <class ReplyT> void Command<ReplyT>::processReply(redisReply *r) {
template <class ReplyT> void Command<ReplyT>::processReply(redisReply *r, const std::string& errorMessage) {

last_error_.clear();
reply_obj_ = r;

if (reply_obj_ == nullptr) {
reply_status_ = ERROR_REPLY;
last_error_ = "Received null redisReply* from hiredis.";
if (errorMessage.empty()) {
last_error_ = "Received null redisReply* from hiredis.";
}
else {
last_error_ = errorMessage;
}
logger_.error() << last_error_;
Redox::disconnectedCallback(rdx_->ctx_, REDIS_ERR);

Expand Down

0 comments on commit 0be0162

Please sign in to comment.