Patch to handle decoding errors. >From 0a179e4c16e390e091629ab83f08b813ae5ad4ed Mon Sep 17 00:00:00 2001 From: dhammika <[email protected]> Date: Wed, 20 Oct 2010 19:27:00 -0700 Subject: [PATCH] handle decoding malformed messages
Signed-off-by: dhammika <[email protected]> --- src/decoder.cpp | 26 ++++++++++++-------------- src/decoder.hpp | 25 +++++++++++++++++++++---- src/zmq_engine.cpp | 24 ++++++++++++++---------- 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/src/decoder.cpp b/src/decoder.cpp index 131ee24..49febc0 100644 --- a/src/decoder.cpp +++ b/src/decoder.cpp @@ -54,16 +54,16 @@ bool zmq::decoder_t::one_byte_size_ready () next_step (tmpbuf, 8, &decoder_t::eight_byte_size_ready); else { - // TODO: Handle over-sized message decently. - // There has to be at least one byte (the flags) in the message). - zmq_assert (*tmpbuf > 0); - // in_progress is initialised at this point so in theory we should // close it before calling zmq_msg_init_size, however, it's a 0-byte // message and thus we can treat it as uninitialised... - int rc = zmq_msg_init_size (&in_progress, *tmpbuf - 1); - errno_assert (rc == 0); + if (!*tmpbuf || + zmq_msg_init_size (&in_progress, *tmpbuf - 1)) { + decoding_error (); + return false; + } + next_step (tmpbuf, 1, &decoder_t::flags_ready); } return true; @@ -75,19 +75,17 @@ bool zmq::decoder_t::eight_byte_size_ready () // read the message data into it. size_t size = (size_t) get_uint64 (tmpbuf); - // TODO: Handle over-sized message decently. - // There has to be at least one byte (the flags) in the message). - zmq_assert (size > 0); - - // in_progress is initialised at this point so in theory we should // close it before calling zmq_msg_init_size, however, it's a 0-byte // message and thus we can treat it as uninitialised... - int rc = zmq_msg_init_size (&in_progress, size - 1); - errno_assert (rc == 0); - next_step (tmpbuf, 1, &decoder_t::flags_ready); + if (!size || + zmq_msg_init_size (&in_progress, size - 1)) { + decoding_error (); + return false; + } + next_step (tmpbuf, 1, &decoder_t::flags_ready); return true; } diff --git a/src/decoder.hpp b/src/decoder.hpp index 87982a0..bf46cd6 100644 --- a/src/decoder.hpp +++ b/src/decoder.hpp @@ -98,9 +98,14 @@ namespace zmq read_pos += size_; to_read -= size_; - while (!to_read) - if (!(static_cast <T*> (this)->*next) ()) + while (!to_read) { + if (!(static_cast <T*> (this)->*next) ()) { + if (unlikely (!(static_cast <T*> (this)->next))) + return (size_t) -1; + return size_; + } + } return size_; } @@ -109,9 +114,14 @@ namespace zmq // Try to get more space in the message to fill in. // If none is available, return. - while (!to_read) - if (!(static_cast <T*> (this)->*next) ()) + while (!to_read) { + if (!(static_cast <T*> (this)->*next) ()) { + if (unlikely (!(static_cast <T*> (this)->next))) + return (size_t) -1; + return pos; + } + } // If there are no more data in the buffer, return. if (pos == size_) @@ -142,6 +152,13 @@ namespace zmq next = next_; } + // This function should be called from the derived class to + // abort decoder state machine. + inline void decoding_error() + { + next = NULL; + } + private: unsigned char *read_pos; diff --git a/src/zmq_engine.cpp b/src/zmq_engine.cpp index 815697c..bde0998 100644 --- a/src/zmq_engine.cpp +++ b/src/zmq_engine.cpp @@ -119,19 +119,23 @@ void zmq::zmq_engine_t::in_event () // Push the data to the decoder. size_t processed = decoder.process_buffer (inpos, insize); - // Stop polling for input if we got stuck. - if (processed < insize) { + if (unlikely (processed == (size_t) -1)) { + disconnection = true; + } else { + // Stop polling for input if we got stuck. + if (processed < insize) { + + // This may happen if queue limits are in effect or when + // init object reads all required information from the socket + // and rejects to read more data. + reset_pollin (handle); + } - // This may happen if queue limits are in effect or when - // init object reads all required information from the socket - // and rejects to read more data. - reset_pollin (handle); + // Adjust the buffer. + inpos += processed; + insize -= processed; } - // Adjust the buffer. - inpos += processed; - insize -= processed; - // Flush all messages the decoder may have produced. inout->flush (); -- 1.7.0.4 _______________________________________________ zeromq-dev mailing list [email protected] http://lists.zeromq.org/mailman/listinfo/zeromq-dev
