]> granicus.if.org Git - esp-idf/commitdiff
esp_event: fix issue with post data preparation
authorRenz Christian Bagaporo <renz@espressif.com>
Thu, 16 May 2019 03:51:57 +0000 (11:51 +0800)
committerRenz Christian Bagaporo <renz@espressif.com>
Wed, 22 May 2019 03:28:39 +0000 (11:28 +0800)
Fixes an issue with post instance data preparation. Currently, there is
no way to check if event data has really been set during handler
execution preparation. When data is not allocated from the heap, user
could have passed 0x0 which can lead to failed checks.

This also implements using the already allocated data memory for posting
events from non-ISR functions when data size is less than the capacity.

components/esp_event/esp_event.c
components/esp_event/private_include/esp_event_internal.h

index e89b7e3caaabb8c9468a793c39f85782bd916b1a..f9704977d162ce0a22c18414da88f9ad33ec74a4 100644 (file)
@@ -132,8 +132,18 @@ static void handler_execute(esp_event_loop_instance_t* loop, esp_event_handler_i
 #endif
     // Execute the handler
 #if CONFIG_ESP_EVENT_POST_FROM_ISR
-    (*(handler->handler))(handler->arg, post.base, post.id, post.data_allocd ? post.data.ptr : &post.data.val);
-#else 
+    void* data_ptr = NULL;
+
+    if (post.data_set) {
+        if (post.data_allocated) {
+            data_ptr = post.data.ptr;
+        } else {
+            data_ptr = &post.data.val;
+        }
+    }
+
+    (*(handler->handler))(handler->arg, post.base, post.id, data_ptr);
+#else
     (*(handler->handler))(handler->arg, post.base, post.id, post.data);
 #endif
 
@@ -380,7 +390,7 @@ static void loop_node_remove_all_handler(esp_event_loop_node_t* loop_node)
 static void inline __attribute__((always_inline)) post_instance_delete(esp_event_post_instance_t* post)
 {
 #if CONFIG_ESP_EVENT_POST_FROM_ISR
-    if (post->data_allocd && post->data.ptr) {
+    if (post->data_allocated && post->data.ptr) {
         free(post->data.ptr);
     }
 #else
@@ -740,20 +750,28 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t
     esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
 
     esp_event_post_instance_t post;
-    memset((void*)(&(post.data)), 0, sizeof(post.data));
+    memset((void*)(&post), 0, sizeof(post));
 
     if (event_data != NULL && event_data_size != 0) {
-        // Make persistent copy of event data on heap.
-        void* event_data_copy = calloc(1, event_data_size);
+#if CONFIG_ESP_EVENT_POST_FROM_ISR
+        if(event_data_size > sizeof(post.data.val)) {
+#endif
+            // Make persistent copy of event data on heap.
+            void* event_data_copy = calloc(1, event_data_size);
 
-        if (event_data_copy == NULL) {
-            return ESP_ERR_NO_MEM;
-        }
+            if (event_data_copy == NULL) {
+                return ESP_ERR_NO_MEM;
+            }
 
-        memcpy(event_data_copy, event_data, event_data_size);
+            memcpy(event_data_copy, event_data, event_data_size);
 #if CONFIG_ESP_EVENT_POST_FROM_ISR
-        post.data.ptr = event_data_copy;
-        post.data_allocd = true;
+            post.data.ptr = event_data_copy;
+            post.data_allocated = true;
+        } else {
+            memcpy(&post.data.val, event_data, event_data_size);
+            post.data_allocated = false;
+        }
+        post.data_set = true;
 #else
         post.data = event_data_copy;
 #endif
@@ -816,7 +834,7 @@ esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop, esp_event_ba
     esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
 
     esp_event_post_instance_t post;
-    memset((void*)(&(post.data)), 0, sizeof(post.data));
+    memset((void*)(&post), 0, sizeof(post));
 
     if (event_data_size > sizeof(post.data.val)) {
         return ESP_ERR_INVALID_ARG;
@@ -824,7 +842,8 @@ esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop, esp_event_ba
 
     if (event_data != NULL && event_data_size != 0) {
         memcpy((void*)(&(post.data.val)), event_data, event_data_size);
-        post.data_allocd = false;
+        post.data_allocated = false;
+        post.data_set = true;
     }
     post.base = event_base;
     post.id = event_id;
index d5bbb7fac17758381fc5496cbf789bef50c2efaa..fb970a806801d1b8fa5b81015a67ef59dfc0378b 100644 (file)
@@ -97,7 +97,8 @@ typedef void* esp_event_post_data_t;
 /// Event posted to the event queue
 typedef struct esp_event_post_instance {
 #if CONFIG_ESP_EVENT_POST_FROM_ISR
-    bool data_allocd;                                                /**< indicates whether data is alloc'd */
+    bool data_allocated;                                             /**< indicates whether data is allocated from heap */
+    bool data_set;                                                   /**< indicates if data is null */
 #endif
     esp_event_base_t base;                                           /**< the event base */
     int32_t id;                                                      /**< the event id */