-
Notifications
You must be signed in to change notification settings - Fork 203
mqtt5 issue reproduce #995
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,6 @@ | ||
| idf_component_register(SRCS "app_main.cpp" | ||
| idf_component_register(SRCS "app_main.c" | ||
| INCLUDE_DIRS ".") | ||
|
|
||
| # target_compile_options(${COMPONENT_LIB} PUBLIC -fsanitize=address) | ||
| # target_link_options(${COMPONENT_LIB} PUBLIC -fsanitize=address) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,210 @@ | ||
| /* | ||
| * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD | ||
| * | ||
| * SPDX-License-Identifier: Unlicense OR CC0-1.0 | ||
| */ | ||
| #include <stdio.h> | ||
| #include <stdint.h> | ||
| #include <stddef.h> | ||
| #include <string.h> | ||
| #include <stdlib.h> | ||
| #include "esp_system.h" | ||
| #include "nvs_flash.h" | ||
| #include "esp_event.h" | ||
| #include "esp_netif.h" | ||
| #include "protocol_examples_common.h" | ||
| #include "esp_log.h" | ||
| #include "mqtt_client.h" | ||
| #include "mqtt5_client.h" | ||
| #include "sdkconfig.h" | ||
|
|
||
| static const char *TAG = "mqtt5_example"; | ||
|
|
||
|
|
||
| static void log_error_if_nonzero(const char *message, int error_code) | ||
| { | ||
| if (error_code != 0) { | ||
| ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code); | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| * @brief Event handler registered to receive MQTT events | ||
| * | ||
| * This function is called by the MQTT client event loop. | ||
| * | ||
| * @param handler_args user data registered to the event. | ||
| * @param base Event base for the handler(always MQTT Base in this example). | ||
| * @param event_id The id for the received event. | ||
| * @param event_data The data for the event, esp_mqtt_event_handle_t. | ||
| */ | ||
| static esp_mqtt5_user_property_item_t user_property_arr[] = { | ||
| {"board", "esp32"}, | ||
| {"u", "user"}, | ||
| {"p", "password"} | ||
| }; | ||
|
|
||
| #define USE_PROPERTY_ARR_SIZE sizeof(user_property_arr)/sizeof(esp_mqtt5_user_property_item_t) | ||
|
|
||
| static void print_user_property(mqtt5_user_property_handle_t user_property) | ||
| { | ||
| if (user_property) { | ||
| uint8_t count = esp_mqtt5_client_get_user_property_count(user_property); | ||
| if (count) { | ||
| esp_mqtt5_user_property_item_t *item = malloc(count * sizeof(esp_mqtt5_user_property_item_t)); | ||
| if (esp_mqtt5_client_get_user_property(user_property, item, &count) == ESP_OK) { | ||
| for (int i = 0; i < count; i++) { | ||
| esp_mqtt5_user_property_item_t *t = &item[i]; | ||
| ESP_LOGI(TAG, "key is %s, value is %s", t->key, t->value); | ||
| free((char *)t->key); | ||
| free((char *)t->value); | ||
| } | ||
| } | ||
| free(item); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static void mqtt5_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) | ||
| { | ||
| ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32, base, event_id); | ||
| esp_mqtt_event_handle_t event = event_data; | ||
| esp_mqtt_client_handle_t client = event->client; | ||
| int msg_id; | ||
|
|
||
| ESP_LOGD(TAG, "free heap size is %" PRIu32 ", minimum %" PRIu32, esp_get_free_heap_size(), esp_get_minimum_free_heap_size()); | ||
| switch ((esp_mqtt_event_id_t)event_id) { | ||
| case MQTT_EVENT_CONNECTED: | ||
| ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); | ||
| esp_mqtt_client_disconnect(client); | ||
| // print_user_property(event->property->user_property); | ||
| // msg_id = esp_mqtt_client_subscribe(client, "sensor/data", 0); | ||
| // ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); | ||
| break; | ||
| case MQTT_EVENT_DISCONNECTED: | ||
| ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); | ||
| print_user_property(event->property->user_property); | ||
| break; | ||
|
|
||
| case MQTT_EVENT_SUBSCRIBED: | ||
| ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d, reason code=0x%02x ", event->msg_id, (uint8_t)*event->data); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsafe dereference of event->data without validationMedium Severity The |
||
| print_user_property(event->property->user_property); | ||
| break; | ||
| case MQTT_EVENT_UNSUBSCRIBED: | ||
| ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id); | ||
| print_user_property(event->property->user_property); | ||
| break; | ||
| case MQTT_EVENT_PUBLISHED: | ||
| ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id); | ||
| print_user_property(event->property->user_property); | ||
| break; | ||
| case MQTT_EVENT_DATA: | ||
| ESP_LOGI(TAG, "MQTT_EVENT_DATA"); | ||
| print_user_property(event->property->user_property); | ||
| ESP_LOGI(TAG, "payload_format_indicator is %d", event->property->payload_format_indicator); | ||
| ESP_LOGI(TAG, "response_topic is %.*s", event->property->response_topic_len, event->property->response_topic); | ||
| ESP_LOGI(TAG, "correlation_data is %.*s", event->property->correlation_data_len, event->property->correlation_data); | ||
| ESP_LOGI(TAG, "content_type is %.*s", event->property->content_type_len, event->property->content_type); | ||
| ESP_LOGI(TAG, "TOPIC=%.*s", event->topic_len, event->topic); | ||
| printf("data length: %d\n", event->data_len); | ||
| for (int i = 0; i < /*(uint32_t)*/event->data_len; i++) { | ||
| printf("%02x ", event->data[i]); | ||
| } | ||
| printf("\n"); | ||
| // ESP_LOGI(TAG, "DATA=%.*s", event->data_len, event->data); | ||
| break; | ||
| case MQTT_EVENT_ERROR: | ||
| ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); | ||
| print_user_property(event->property->user_property); | ||
| ESP_LOGI(TAG, "MQTT5 return code is %d", event->error_handle->connect_return_code); | ||
| if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) { | ||
| log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err); | ||
| log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err); | ||
| log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno); | ||
| ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno)); | ||
|
|
||
| } | ||
| break; | ||
| default: | ||
| ESP_LOGI(TAG, "Other event id:%d", event->event_id); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| static void mqtt5_app_start(void) | ||
| { | ||
| esp_mqtt5_connection_property_config_t connect_property = { | ||
| .session_expiry_interval = 10, | ||
| .maximum_packet_size = 1024, | ||
| .receive_maximum = 65535, | ||
| .topic_alias_maximum = 2, | ||
| .request_resp_info = true, | ||
| .request_problem_info = true, | ||
| .will_delay_interval = 10, | ||
| .payload_format_indicator = true, | ||
| .message_expiry_interval = 10, | ||
| .response_topic = "/test/response", | ||
| .correlation_data = "123456", | ||
| .correlation_data_len = 6, | ||
| }; | ||
| const esp_mqtt_client_config_t mqtt5_cfg = { | ||
| .broker = { | ||
| .address.uri = "mqtt://127.0.0.1:1883", | ||
| }, | ||
| .session = { | ||
| .protocol_ver = MQTT_PROTOCOL_V_5, | ||
| .last_will = { | ||
| .topic = "/topic/will", | ||
| .msg = "i will leave", | ||
| .msg_len = 12, | ||
| .qos = 1, | ||
| .retain = true, | ||
| }, | ||
| }, | ||
| }; | ||
|
|
||
| esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing NULL check after MQTT client initializationMedium Severity The return value of Additional Locations (2) |
||
|
|
||
| /* Set connection properties and user properties */ | ||
| esp_mqtt5_client_set_user_property(&connect_property.user_property, user_property_arr, USE_PROPERTY_ARR_SIZE); | ||
| esp_mqtt5_client_set_user_property(&connect_property.will_user_property, user_property_arr, USE_PROPERTY_ARR_SIZE); | ||
| esp_mqtt5_client_set_connect_property(client, &connect_property); | ||
|
|
||
| /* If you call esp_mqtt5_client_set_user_property to set user properties, DO NOT forget to delete them. | ||
| * esp_mqtt5_client_set_connect_property will malloc buffer to store the user_property and you can delete it after | ||
| */ | ||
| esp_mqtt5_client_delete_user_property(connect_property.user_property); | ||
| esp_mqtt5_client_delete_user_property(connect_property.will_user_property); | ||
|
|
||
| /* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */ | ||
| esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL); | ||
| esp_mqtt_client_start(client); | ||
| } | ||
|
|
||
|
|
||
| void app_main(void) | ||
| { | ||
| ESP_LOGI(TAG, "[APP] Startup.."); | ||
| ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size()); | ||
| ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version()); | ||
|
|
||
| // esp_log_level_set("*", ESP_LOG_INFO); | ||
| // esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE); | ||
| // esp_log_level_set("mqtt5_example", ESP_LOG_VERBOSE); | ||
| // esp_log_level_set("transport_base", ESP_LOG_VERBOSE); | ||
| // esp_log_level_set("esp-tls", ESP_LOG_VERBOSE); | ||
| // esp_log_level_set("transport", ESP_LOG_VERBOSE); | ||
| // esp_log_level_set("outbox", ESP_LOG_VERBOSE); | ||
|
|
||
| ESP_ERROR_CHECK(nvs_flash_init()); | ||
| ESP_ERROR_CHECK(esp_netif_init()); | ||
| ESP_ERROR_CHECK(esp_event_loop_create_default()); | ||
|
|
||
| /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. | ||
| * Read "Establishing Wi-Fi or Ethernet Connection" section in | ||
| * examples/protocols/README.md for more information about this function. | ||
| */ | ||
| ESP_ERROR_CHECK(example_connect()); | ||
|
|
||
| mqtt5_app_start(); | ||
| } | ||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing NULL check after malloc allocation
Medium Severity
The
malloccall inprint_user_property()doesn't check if the allocation succeeded before using the returned pointer. Ifmallocreturns NULL due to memory exhaustion, passing it toesp_mqtt5_client_get_user_property()will cause undefined behavior or a crash.