Improved the FTPClient class by adding better verification to buffers

This commit is contained in:
anschrammh 2019-10-31 21:26:02 +01:00
parent 4a1fc5b712
commit f7fc5abad5
2 changed files with 27 additions and 7 deletions

View File

@ -12,6 +12,7 @@ _fileRecvBytes(0),
_waitingForDataConnection(false), _waitingForDataConnection(false),
_fileIsBeeingReceived(false), _fileIsBeeingReceived(false),
_actionTimeout(0), _actionTimeout(0),
_dataClientConnected(false),
_ftpClientState(FTPServer<FTPClient>::FTPClientState::INIT), _ftpClientState(FTPServer<FTPClient>::FTPClientState::INIT),
_binaryFlag(FTPServer<FTPClient>::BinaryFlag::OFF), _binaryFlag(FTPServer<FTPClient>::BinaryFlag::OFF),
_dataTransferPending(FTPServer<FTPClient>::FTPClientDataTransfer::NONE) _dataTransferPending(FTPServer<FTPClient>::FTPClientDataTransfer::NONE)
@ -30,6 +31,7 @@ FTPClient::~FTPClient()
void FTPClient::setDataClient(WiFiClient dataClient) void FTPClient::setDataClient(WiFiClient dataClient)
{ {
_dataClientConnected = true;
_dataClient = dataClient; _dataClient = dataClient;
} }
@ -41,32 +43,42 @@ boolean FTPClient::parseCommandAndParameters()
if(cr != NULL) if(cr != NULL)
{ {
*cr = '\0'; *cr = '\0';
//Serial.println("got r");
} }
else else
{ {
cr = strchr((char *)_data,'\n'); cr = strchr((char *)_data,'\n');
if(cr != NULL) if(cr != NULL)
{
*cr = '\0'; *cr = '\0';
//Serial.println("got n");
}
} }
//Serial.printf("Data : #%s#\n", (char *)_data);
char *cmdDelimiter = strchr((char *)_data,' '); char *cmdDelimiter = strchr((char *)_data,' ');
if(cmdDelimiter == NULL) //It means that we do not have any parameters if(cmdDelimiter == NULL) //It means that we do not have any parameters
{ {
cmdDelimiter = (char *)_data + strlen((char *)_data) - 1; uint16_t dataSize = strlen((char *)_data);
strcpy(_ftpCommand, (char *)_data); cmdDelimiter = (char *)_data + dataSize - 1;
strncpy(_ftpCommand, (char *)_data, dataSize <= 4 ? dataSize : 4);
_ftpCommand[dataSize <= 4 ? dataSize : 4] = '\0';
//Serial.printf("Got no space : size %d\n", dataSize);
} }
else //we do else //we do
{ {
strncpy(_ftpCommand, (char *)_data, cmdDelimiter - (char *)_data); uint16_t dataSize = cmdDelimiter - (char *)_data;
_ftpCommand[cmdDelimiter - (char *)_data] = '\0'; // /!\ strncpy does not append the terminating string character
strncpy(_ftpCommand, (char *)_data, dataSize <= 4 ? dataSize : 4);
_ftpCommand[dataSize <= 4 ? dataSize : 4] = '\0'; // /!\ strncpy does not append the terminating string character
//Serial.printf("Got a space : size %d\n", dataSize);
} }
//We get the parameters : //We get the parameters :
DictionaryHelper::StringEntity params(cmdDelimiter+1); //+1 to skip the first space DictionaryHelper::StringEntity params(cmdDelimiter+1); //+1 to skip the first space
delete _cmdParameters; delete _cmdParameters;
_cmdParameters = params.split(' '); _cmdParameters = params.split(' ');
//At the end, we flush the buffer: //At the end, we flush the buffer:
freeDataBuffer(_dataSize); freeDataBuffer(_dataSize);
@ -103,6 +115,12 @@ void FTPClient::setCurrentFile(const char *file)
} }
} }
void FTPClient::closeDataConnection()
{
_dataClientConnected = false;
_dataClient.stop();
}
void FTPClient::startTimeout() void FTPClient::startTimeout()
{ {
_actionTimeout = millis(); _actionTimeout = millis();

View File

@ -21,6 +21,7 @@ class FTPClient : public TCPClient
void setCurrentDirectory(const char *dir); void setCurrentDirectory(const char *dir);
void setCurrentFile(const char *file); void setCurrentFile(const char *file);
void startTimeout(); void startTimeout();
void closeDataConnection();
char _ftpCommand[5]; char _ftpCommand[5];
Dictionary<DictionaryHelper::StringEntity> *_cmdParameters; Dictionary<DictionaryHelper::StringEntity> *_cmdParameters;
@ -33,6 +34,7 @@ class FTPClient : public TCPClient
boolean _waitingForDataConnection; boolean _waitingForDataConnection;
boolean _fileIsBeeingReceived; boolean _fileIsBeeingReceived;
uint64_t _actionTimeout; uint64_t _actionTimeout;
boolean _dataClientConnected;
FTPServer<FTPClient>::FTPClientState _ftpClientState; FTPServer<FTPClient>::FTPClientState _ftpClientState;
FTPServer<FTPClient>::BinaryFlag _binaryFlag; FTPServer<FTPClient>::BinaryFlag _binaryFlag;