Skip to content

Commit

Permalink
Fix potential memory leak in TcpClient::send
Browse files Browse the repository at this point in the history
  • Loading branch information
mikee47 committed Apr 1, 2024
1 parent 0e46891 commit 3609357
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
33 changes: 22 additions & 11 deletions Sming/Components/Network/src/Network/TcpClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@ bool TcpClient::send(const char* data, uint16_t len, bool forceCloseAfterSent)
return false;
}

std::unique_ptr<MemoryDataStream> newStream;
auto memoryStream = static_cast<MemoryDataStream*>(stream);
if(memoryStream == nullptr || memoryStream->getStreamType() != eSST_MemoryWritable) {
memoryStream = new MemoryDataStream();
newStream = std::make_unique<MemoryDataStream>();
if(!newStream) {
return false;
}
memoryStream = newStream.get();
}

if(!memoryStream->ensureCapacity(memoryStream->getSize() + len)) {
Expand All @@ -56,11 +61,21 @@ bool TcpClient::send(const char* data, uint16_t len, bool forceCloseAfterSent)

memoryStream->write(data, len);

return send(memoryStream, forceCloseAfterSent);
if(!send(memoryStream, forceCloseAfterSent)) {
return false;
}

newStream.release();
return true;
}

bool TcpClient::send(IDataSourceStream* source, bool forceCloseAfterSent)
{
std::unique_ptr<IDataSourceStream> sourceRef;
if(stream != source) {
sourceRef.reset(source);
}

if(state != eTCS_Connecting && state != eTCS_Connected) {
return false;
}
Expand All @@ -76,36 +91,32 @@ bool TcpClient::send(IDataSourceStream* source, bool forceCloseAfterSent)
auto chainStream = static_cast<StreamChain*>(stream);
if(!chainStream->attachStream(source)) {
debug_w("Unable to attach source to existing stream chain!");
delete source;
return false;
}
} else {
debug_d("Creating stream chain ...");
auto chainStream = new StreamChain();
if(chainStream == nullptr) {
delete source;
auto chainStream = std::make_unique<StreamChain>();
if(!chainStream) {
debug_w("Unable to create stream chain!");
return false;
}

if(!chainStream->attachStream(stream)) {
delete source;
delete chainStream;
debug_w("Unable to attach stream to new chain!");
return false;
}

if(!chainStream->attachStream(source)) {
delete source;
delete chainStream;
debug_w("Unable to attach source to new chain!");
return false;
}

stream = chainStream;
stream = chainStream.release();
}
}

sourceRef.release();

int length = source->available();
if(length > 0) {
totalSentBytes += length;
Expand Down
30 changes: 30 additions & 0 deletions samples/Websocket_Client/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python
#
# Test python application to send test message to server
#
# Shows connection detail so we can compare it to Sming code
#

import argparse
import logging
import asyncio
from websockets.sync.client import connect

def main():
parser = argparse.ArgumentParser(description='Simple websocket client test')
parser.add_argument('URL', help='Connection URL', default='ws://192.168.13.10/ws')

args = parser.parse_args()

logging.basicConfig(
format="%(asctime)s %(message)s",
level=logging.DEBUG,
)
print(f'Connecting to {args.URL}...')
with connect(args.URL) as websocket:
websocket.send("Hello world!")
websocket.recv()
websocket.recv()

if __name__ == "__main__":
main()

0 comments on commit 3609357

Please sign in to comment.