Skip to content

Commit 4f467d0

Browse files
committed
Merge branch 'fix/ws_transport_mem_corrupt' into 'master'
fix(transport): Fix websocket mem-corruption while reading headers Closes IDFGH-13585 See merge request espressif/esp-idf!33593
2 parents bcfa928 + 53e63eb commit 4f467d0

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

components/tcp_transport/host_test/main/test_websocket_transport.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "esp_transport_tcp.h"
2222
#include "esp_transport_ws.h"
2323

24-
#define WS_BUFFER_SIZE 1024
24+
#define WS_BUFFER_SIZE CONFIG_WS_BUFFER_SIZE
2525

2626
extern "C" {
2727
#include "Mockmock_transport.h"
@@ -103,15 +103,16 @@ int mock_write_callback(esp_transport_handle_t transport, const char *request_se
103103
}
104104

105105
// Callback function for mock_read
106-
int mock_read_callback(esp_transport_handle_t transport, char *buffer, int len, int timeout_ms, int num_call) {
106+
int mock_valid_read_callback(esp_transport_handle_t transport, char *buffer, int len, int timeout_ms, int num_call)
107+
{
107108
std::string websocket_response = make_response();
108109
std::memcpy(buffer, websocket_response.data(), websocket_response.size());
109110
return websocket_response.size();
110111
}
111112

112113
}
113114

114-
TEST_CASE("WebSocket Transport Connection", "[websocket_transport]") {
115+
void test_ws_connect(bool expect_valid_connection, CMOCK_mock_read_CALLBACK read_callback) {
115116
constexpr static auto timeout = 50;
116117
constexpr static auto port = 8080;
117118
constexpr static auto host = "localhost";
@@ -134,10 +135,18 @@ TEST_CASE("WebSocket Transport Connection", "[websocket_transport]") {
134135
mock_write_Stub(mock_write_callback);
135136
mock_connect_ExpectAndReturn(parent_handle.get(), host, port, timeout, ESP_OK);
136137
// Set the callback function for mock_read
137-
mock_read_Stub(mock_read_callback);
138+
mock_read_Stub(read_callback);
138139
mock_poll_read_ExpectAnyArgsAndReturn(1);
139140
esp_crypto_base64_encode_ExpectAnyArgsAndReturn(0);
140141
mock_destroy_ExpectAnyArgsAndReturn(ESP_OK);
142+
143+
if (!expect_valid_connection) {
144+
// for invalid connections we only check that the connect() function fails
145+
REQUIRE(esp_transport_connect(websocket_transport.get(), host, port, timeout) != 0);
146+
// and we're done here
147+
return;
148+
}
149+
141150
REQUIRE(esp_transport_connect(websocket_transport.get(), host, port, timeout) == 0);
142151

143152
char buffer[WS_BUFFER_SIZE];
@@ -147,5 +156,37 @@ TEST_CASE("WebSocket Transport Connection", "[websocket_transport]") {
147156

148157
std::string response(buffer, read_len);
149158
REQUIRE(response == "Test");
159+
150160
}
151161
}
162+
163+
// Happy flow
164+
TEST_CASE("WebSocket Transport Connection", "[websocket_transport]")
165+
{
166+
test_ws_connect(true, mock_valid_read_callback);
167+
}
168+
169+
// Some corner cases where we expect the ws connection to fail
170+
171+
TEST_CASE("ws connect fails (0 len response)", "[websocket_transport]")
172+
{
173+
test_ws_connect(false, [](esp_transport_handle_t h, char *buf, int len, int tout, int n) {
174+
return 0;
175+
});
176+
}
177+
178+
TEST_CASE("ws connect fails (invalid response)", "[websocket_transport]")
179+
{
180+
test_ws_connect(false, [](esp_transport_handle_t h, char *buf, int len, int tout, int n) {
181+
int resp_len = len/2;
182+
std::memset(buf, '?', resp_len);
183+
return resp_len;
184+
});
185+
}
186+
187+
TEST_CASE("ws connect fails (big response)", "[websocket_transport]")
188+
{
189+
test_ws_connect(false, [](esp_transport_handle_t h, char *buf, int len, int tout, int n) {
190+
return WS_BUFFER_SIZE;
191+
});
192+
}

components/tcp_transport/transport_ws.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ static int ws_connect(esp_transport_handle_t t, const char *host, int port, int
285285
}
286286
int header_len = 0;
287287
do {
288-
if ((len = esp_transport_read(ws->parent, ws->buffer + header_len, WS_BUFFER_SIZE - header_len, timeout_ms)) <= 0) {
288+
if ((len = esp_transport_read(ws->parent, ws->buffer + header_len, WS_BUFFER_SIZE - 1 - header_len, timeout_ms)) <= 0) {
289289
ESP_LOGE(TAG, "Error read response for Upgrade header %s", ws->buffer);
290290
return -1;
291291
}

0 commit comments

Comments
 (0)