From 9b16cb75f863b4e4161e45a6ef97548edc4c5841 Mon Sep 17 00:00:00 2001 From: Xentec Date: Tue, 1 Oct 2019 01:31:09 +0200 Subject: [PATCH] esp_event: fix crash when unregistering a handler instance in itself When a handler instance is the last one in the list und unregisters itself, the handler iterator will be invalidated by entering free'd memory. Same applies for event base and id, if they become empty. Merges https://github.com/espressif/esp-idf/pull/4139 --- components/esp_event/esp_event.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/components/esp_event/esp_event.c b/components/esp_event/esp_event.c index 08e7cd2502..f4628e6949 100644 --- a/components/esp_event/esp_event.c +++ b/components/esp_event/esp_event.c @@ -526,30 +526,30 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick bool exec = false; - esp_event_handler_instance_t *handler; + esp_event_handler_instance_t *handler, *temp_handler; esp_event_loop_node_t *loop_node; - esp_event_base_node_t *base_node; - esp_event_id_node_t *id_node; + esp_event_base_node_t *base_node, *temp_base; + esp_event_id_node_t *id_node, *temp_id_node; SLIST_FOREACH(loop_node, &(loop->loop_nodes), next) { // Execute loop level handlers - SLIST_FOREACH(handler, &(loop_node->handlers), next) { + SLIST_FOREACH_SAFE(handler, &(loop_node->handlers), next, temp_handler) { handler_execute(loop, handler, post); exec |= true; } - SLIST_FOREACH(base_node, &(loop_node->base_nodes), next) { + SLIST_FOREACH_SAFE(base_node, &(loop_node->base_nodes), next, temp_base) { if (base_node->base == post.base) { // Execute base level handlers - SLIST_FOREACH(handler, &(base_node->handlers), next) { + SLIST_FOREACH_SAFE(handler, &(base_node->handlers), next, temp_handler) { handler_execute(loop, handler, post); exec |= true; } - SLIST_FOREACH(id_node, &(base_node->id_nodes), next) { - if(id_node->id == post.id) { + SLIST_FOREACH_SAFE(id_node, &(base_node->id_nodes), next, temp_id_node) { + if (id_node->id == post.id) { // Execute id level handlers - SLIST_FOREACH(handler, &(id_node->handlers), next) { + SLIST_FOREACH_SAFE(handler, &(id_node->handlers), next, temp_handler) { handler_execute(loop, handler, post); exec |= true; }