Problem: heartbeat command parsing does not check command name size

Solution: treat the first byte of the command body as the size of the
command name, rather than as an id, to comply with ZMTP 3.1.
This was not an actual problem at runtime since both heartbeat
commands have a size of 4, which was treated like an id.
But once SUBSCRIBE/UNSUBSCRIBE get implemented it needs to be checked.
This commit is contained in:
Luca Boccassi 2018-04-29 23:47:56 +01:00 committed by Simon Giesecke
parent ba9274c39a
commit 5482b1ca45
2 changed files with 18 additions and 3 deletions

View File

@ -935,9 +935,7 @@ int zmq::stream_engine_t::decode_and_push (msg_t *msg_)
}
if (msg_->flags () & msg_t::command) {
uint8_t cmd_id = *((uint8_t *) msg_->data ());
if (cmd_id == 4)
process_heartbeat_message (msg_);
process_command_message (msg_);
}
if (metadata)
@ -1094,3 +1092,19 @@ int zmq::stream_engine_t::process_heartbeat_message (msg_t *msg_)
return 0;
}
int zmq::stream_engine_t::process_command_message (msg_t *msg_)
{
uint8_t cmd_name_size = *((uint8_t *) msg_->data ());
// Malformed command
if (msg_->size () < cmd_name_size + sizeof (cmd_name_size))
return -1;
uint8_t *cmd_name = ((uint8_t *) msg_->data ()) + 1;
if (cmd_name_size == 4
&& (memcmp (cmd_name, "PING", cmd_name_size) == 0
|| memcmp (cmd_name, "PONG", cmd_name_size) == 0))
return process_heartbeat_message (msg_);
return 0;
}

View File

@ -127,6 +127,7 @@ class stream_engine_t : public io_object_t, public i_engine
typedef metadata_t::dict_t properties_t;
bool init_properties (properties_t &properties);
int process_command_message (msg_t *msg_);
int produce_ping_message (msg_t *msg_);
int process_heartbeat_message (msg_t *msg_);
int produce_pong_message (msg_t *msg_);