Improved the FTPClient class by adding better verification to buffers
This commit is contained in:
		
							parent
							
								
									4a1fc5b712
								
							
						
					
					
						commit
						f7fc5abad5
					
				@ -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();
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user