mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-26 23:01:04 +08:00
Message validity is checked in the runtime
Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
This commit is contained in:
parent
20e0b7cdcb
commit
581697695a
@ -35,7 +35,8 @@ it shall return `-1` and set 'errno' to one of the values defined below.
|
||||
|
||||
ERRORS
|
||||
------
|
||||
No errors are defined.
|
||||
*EFAULT*::
|
||||
Invalid message.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
|
@ -37,7 +37,8 @@ shall return `-1` and set 'errno' to one of the values defined below.
|
||||
|
||||
ERRORS
|
||||
------
|
||||
No errors are defined.
|
||||
*EFAULT*::
|
||||
Invalid message.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
|
@ -32,7 +32,8 @@ shall return `-1` and set 'errno' to one of the values defined below.
|
||||
|
||||
ERRORS
|
||||
------
|
||||
No errors are defined.
|
||||
*EFAULT*::
|
||||
Invalid message.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
|
@ -68,6 +68,8 @@ The provided 'socket' was invalid.
|
||||
*EINTR*::
|
||||
The operation was interrupted by delivery of a signal before a message was
|
||||
available.
|
||||
*EFAULT*::
|
||||
The message passed to the function was invalid.
|
||||
|
||||
|
||||
EXAMPLE
|
||||
|
@ -78,6 +78,8 @@ The provided 'socket' was invalid.
|
||||
*EINTR*::
|
||||
The operation was interrupted by delivery of a signal before the message was
|
||||
sent.
|
||||
*EFAULT*::
|
||||
Invalid message.
|
||||
|
||||
|
||||
EXAMPLE
|
||||
|
@ -137,6 +137,7 @@ ZMQ_EXPORT const char *zmq_strerror (int errnum);
|
||||
/* allows us to pack the stucture tigher and thus improve performance. */
|
||||
#define ZMQ_MSG_MORE 1
|
||||
#define ZMQ_MSG_SHARED 128
|
||||
#define ZMQ_MSG_MASK 129 /* Merges all the flags */
|
||||
|
||||
/* A message. Note that 'content' is not a pointer to the raw data. */
|
||||
/* Rather it is pointer to zmq::msg_content_t structure */
|
||||
|
40
src/msg.cpp
40
src/msg.cpp
@ -26,12 +26,13 @@
|
||||
#include <new>
|
||||
|
||||
#include "stdint.hpp"
|
||||
#include "likely.hpp"
|
||||
#include "err.hpp"
|
||||
|
||||
int zmq_msg_init (zmq_msg_t *msg_)
|
||||
{
|
||||
msg_->content = (zmq::msg_content_t*) ZMQ_VSM;
|
||||
msg_->flags = 0;
|
||||
msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
|
||||
msg_->vsm_size = 0;
|
||||
return 0;
|
||||
}
|
||||
@ -40,7 +41,7 @@ int zmq_msg_init_size (zmq_msg_t *msg_, size_t size_)
|
||||
{
|
||||
if (size_ <= ZMQ_MAX_VSM_SIZE) {
|
||||
msg_->content = (zmq::msg_content_t*) ZMQ_VSM;
|
||||
msg_->flags = 0;
|
||||
msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
|
||||
msg_->vsm_size = (uint8_t) size_;
|
||||
}
|
||||
else {
|
||||
@ -50,7 +51,7 @@ int zmq_msg_init_size (zmq_msg_t *msg_, size_t size_)
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
msg_->flags = 0;
|
||||
msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
|
||||
|
||||
zmq::msg_content_t *content = (zmq::msg_content_t*) msg_->content;
|
||||
content->data = (void*) (content + 1);
|
||||
@ -67,7 +68,7 @@ int zmq_msg_init_data (zmq_msg_t *msg_, void *data_, size_t size_,
|
||||
{
|
||||
msg_->content = (zmq::msg_content_t*) malloc (sizeof (zmq::msg_content_t));
|
||||
alloc_assert (msg_->content);
|
||||
msg_->flags = 0;
|
||||
msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
|
||||
zmq::msg_content_t *content = (zmq::msg_content_t*) msg_->content;
|
||||
content->data = data_;
|
||||
content->size = size_;
|
||||
@ -79,6 +80,12 @@ int zmq_msg_init_data (zmq_msg_t *msg_, void *data_, size_t size_,
|
||||
|
||||
int zmq_msg_close (zmq_msg_t *msg_)
|
||||
{
|
||||
// Check the validity tag.
|
||||
if (unlikely (msg_->flags | ZMQ_MSG_MASK) != 0xff) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// For VSMs and delimiters there are no resources to free.
|
||||
if (msg_->content != (zmq::msg_content_t*) ZMQ_DELIMITER &&
|
||||
msg_->content != (zmq::msg_content_t*) ZMQ_VSM) {
|
||||
@ -98,17 +105,21 @@ int zmq_msg_close (zmq_msg_t *msg_)
|
||||
}
|
||||
}
|
||||
|
||||
// As a safety measure, let's make the deallocated message look like
|
||||
// an empty message.
|
||||
msg_->content = (zmq::msg_content_t*) ZMQ_VSM;
|
||||
// Remove the validity tag from the message.
|
||||
msg_->flags = 0;
|
||||
msg_->vsm_size = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zmq_msg_move (zmq_msg_t *dest_, zmq_msg_t *src_)
|
||||
{
|
||||
// Check the validity tags.
|
||||
if (unlikely ((dest_->flags | ZMQ_MSG_MASK) != 0xff ||
|
||||
(src_->flags | ZMQ_MSG_MASK) != 0xff)) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
zmq_msg_close (dest_);
|
||||
*dest_ = *src_;
|
||||
zmq_msg_init (src_);
|
||||
@ -117,6 +128,13 @@ int zmq_msg_move (zmq_msg_t *dest_, zmq_msg_t *src_)
|
||||
|
||||
int zmq_msg_copy (zmq_msg_t *dest_, zmq_msg_t *src_)
|
||||
{
|
||||
// Check the validity tags.
|
||||
if (unlikely ((dest_->flags | ZMQ_MSG_MASK) != 0xff ||
|
||||
(src_->flags | ZMQ_MSG_MASK) != 0xff)) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
zmq_msg_close (dest_);
|
||||
|
||||
// VSMs and delimiters require no special handling.
|
||||
@ -140,6 +158,9 @@ int zmq_msg_copy (zmq_msg_t *dest_, zmq_msg_t *src_)
|
||||
|
||||
void *zmq_msg_data (zmq_msg_t *msg_)
|
||||
{
|
||||
// Check the validity tag.
|
||||
zmq_assert ((msg_->flags | ZMQ_MSG_MASK) == 0xff);
|
||||
|
||||
if (msg_->content == (zmq::msg_content_t*) ZMQ_VSM)
|
||||
return msg_->vsm_data;
|
||||
if (msg_->content == (zmq::msg_content_t*) ZMQ_DELIMITER)
|
||||
@ -150,6 +171,9 @@ void *zmq_msg_data (zmq_msg_t *msg_)
|
||||
|
||||
size_t zmq_msg_size (zmq_msg_t *msg_)
|
||||
{
|
||||
// Check the validity tag.
|
||||
zmq_assert ((msg_->flags | ZMQ_MSG_MASK) == 0xff);
|
||||
|
||||
if (msg_->content == (zmq::msg_content_t*) ZMQ_VSM)
|
||||
return msg_->vsm_size;
|
||||
if (msg_->content == (zmq::msg_content_t*) ZMQ_DELIMITER)
|
||||
|
@ -49,7 +49,7 @@ int zmq::req_t::xsend (zmq_msg_t *msg_, int flags_)
|
||||
zmq_msg_t prefix;
|
||||
int rc = zmq_msg_init (&prefix);
|
||||
zmq_assert (rc == 0);
|
||||
prefix.flags = ZMQ_MSG_MORE;
|
||||
prefix.flags |= ZMQ_MSG_MORE;
|
||||
rc = xreq_t::xsend (&prefix, flags_);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
@ -466,11 +466,18 @@ int zmq::socket_base_t::connect (const char *addr_)
|
||||
|
||||
int zmq::socket_base_t::send (::zmq_msg_t *msg_, int flags_)
|
||||
{
|
||||
// Check whether the library haven't been shut down yet.
|
||||
if (unlikely (ctx_terminated)) {
|
||||
errno = ETERM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check whether message passed to the function is valid.
|
||||
if (unlikely ((msg_->flags | ZMQ_MSG_MASK) != 0xff)) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Process pending commands, if any.
|
||||
int rc = process_commands (false, true);
|
||||
if (unlikely (rc != 0))
|
||||
@ -504,11 +511,18 @@ int zmq::socket_base_t::send (::zmq_msg_t *msg_, int flags_)
|
||||
|
||||
int zmq::socket_base_t::recv (::zmq_msg_t *msg_, int flags_)
|
||||
{
|
||||
// Check whether the library haven't been shut down yet.
|
||||
if (unlikely (ctx_terminated)) {
|
||||
errno = ETERM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check whether message passed to the function is valid.
|
||||
if (unlikely ((msg_->flags | ZMQ_MSG_MASK) != 0xff)) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get the message.
|
||||
int rc = xrecv (msg_, flags_);
|
||||
int err = errno;
|
||||
|
@ -269,7 +269,7 @@ int zmq::xrep_t::xrecv (zmq_msg_t *msg_, int flags_)
|
||||
zmq_assert (rc == 0);
|
||||
memcpy (zmq_msg_data (msg_), inpipes [current_in].identity.data (),
|
||||
zmq_msg_size (msg_));
|
||||
msg_->flags = ZMQ_MSG_MORE;
|
||||
msg_->flags |= ZMQ_MSG_MORE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user