mirror of
https://github.com/agessaman/MeshCore.git
synced 2026-10-23 02:11:33 +00:00
fix(mqtt): never hand back a half-initialized client or transport
esp_mqtt_client_init() succeeded without a registered event sink when registration failed, and the WebSocket wrap returned a transport with the unpadded SDK buffer when the padded allocation failed. Both paths now fail cleanly instead, the IDF 4 WebSocket layout is pinned to the validated patch level, and the connection flags esp-mqtt tasks write become atomic.
This commit is contained in:
1 parent
6124f3c139
commit
665ece1e12
6 files changed
+135
-27
No files matched your search
@@ -62,7 +62,12 @@
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR == 4
|
||||
|
||||
#if ESP_IDF_VERSION_MINOR != 4 || ESP_IDF_VERSION_PATCH != 7
|
||||
#error "Revalidate the private WebSocket layout before using another IDF 4 SDK"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "RequiredTransportBuffer.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_transport.h"
|
||||
#include "esp_transport_ws.h"
|
||||
@@ -97,22 +102,15 @@ extern "C" {
|
||||
esp_transport_handle_t __real_esp_transport_ws_init(esp_transport_handle_t parent_handle);
|
||||
|
||||
esp_transport_handle_t __wrap_esp_transport_ws_init(esp_transport_handle_t parent_handle) {
|
||||
esp_transport_handle_t t = __real_esp_transport_ws_init(parent_handle);
|
||||
if (t != nullptr) {
|
||||
transport_ws_t* ws = (transport_ws_t*)esp_transport_get_context_data(t);
|
||||
if (ws != nullptr && ws->buffer != nullptr) {
|
||||
// The buffer is untouched at this point (allocated moments ago inside
|
||||
// __real_esp_transport_ws_init), so a swap is safe.
|
||||
char* padded = (char*)malloc(CONFIG_WS_BUFFER_SIZE + 1);
|
||||
if (padded != nullptr) {
|
||||
return initWithRequiredTransportBuffer<esp_transport_handle_t>(
|
||||
CONFIG_WS_BUFFER_SIZE + 1, malloc,
|
||||
[&]() { return __real_esp_transport_ws_init(parent_handle); },
|
||||
[](esp_transport_handle_t transport, void* buffer) {
|
||||
// Successful init in the pinned SDK guarantees this context and buffer.
|
||||
transport_ws_t* ws = (transport_ws_t*)esp_transport_get_context_data(transport);
|
||||
free(ws->buffer);
|
||||
ws->buffer = padded;
|
||||
}
|
||||
// On alloc failure keep the original buffer: same behavior as before
|
||||
// this fix, which is still strictly better than failing init here.
|
||||
}
|
||||
}
|
||||
return t;
|
||||
ws->buffer = static_cast<char*>(buffer);
|
||||
}, free);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
Reference in new issue
Block a user