Skip to content

Commit

Permalink
ws: directly iterate over internal callbacks array (#2248)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcspr authored May 12, 2020
1 parent 025e8c8 commit e44bb0e
Showing 1 changed file with 10 additions and 35 deletions.
45 changes: 10 additions & 35 deletions code/espurna/ws_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,6 @@ struct ws_ticket_t {
// WS callbacks
// -----------------------------------------------------------------------------

struct ws_counter_t {

ws_counter_t() : current(0), start(0), stop(0) {}

ws_counter_t(uint32_t start, uint32_t stop) :
current(start), start(start), stop(stop) {}

void reset() {
current = start;
}

void next() {
if (current < stop) {
++current;
}
}

bool done() {
return (current >= stop);
}

uint32_t current;
uint32_t start;
uint32_t stop;
};

struct ws_data_t {

enum mode_t {
Expand All @@ -69,46 +43,47 @@ struct ws_data_t {
client_id(0),
mode(ALL),
callbacks(*storage.get()),
counter(0, 1)
current(callbacks.begin())
{}

ws_data_t(uint32_t client_id, const ws_on_send_callback_f& cb) :
storage(new ws_on_send_callback_list_t {cb}),
client_id(client_id),
mode(ALL),
callbacks(*storage.get()),
counter(0, 1)
current(callbacks.begin())
{}

ws_data_t(const uint32_t client_id, ws_on_send_callback_list_t&& callbacks, mode_t mode = SEQUENCE) :
storage(new ws_on_send_callback_list_t(std::move(callbacks))),
client_id(client_id),
mode(mode),
callbacks(*storage.get()),
counter(0, (storage.get())->size())
current(callbacks.begin())

This comment has been minimized.

Copy link
@mcspr

mcspr May 26, 2020

Author Collaborator

Turns out this causes iterator to reference already moved moved callbacks, which is invalid and will crash with things like haconfig where we use this ctor by manually moving callbacks in to the storage

callbacks arg -> cbs
current(callbacks.begin()) -> current(cbs.begin())

{}

ws_data_t(const uint32_t client_id, const ws_on_send_callback_list_t& callbacks, mode_t mode = SEQUENCE) :
client_id(client_id),
mode(mode),
callbacks(callbacks),
counter(0, callbacks.size())
current(callbacks.begin())
{}

bool done() {
return counter.done();
return current == callbacks.end();
}

void sendAll(JsonObject& root) {
while (!counter.done()) counter.next();
current = callbacks.end();
for (auto& callback : callbacks) {
callback(root);
}
}

void sendCurrent(JsonObject& root) {
callbacks[counter.current](root);
counter.next();
if (current == callbacks.end()) return;
(*current)(root);
++current;
}

void send(JsonObject& root) {
Expand All @@ -123,7 +98,7 @@ struct ws_data_t {
const uint32_t client_id;
const mode_t mode;
const ws_on_send_callback_list_t& callbacks;
ws_counter_t counter;
ws_on_send_callback_list_t::const_iterator current;
};

// -----------------------------------------------------------------------------
Expand Down

0 comments on commit e44bb0e

Please sign in to comment.