Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the FF_MakeNameCompliant behavior #63

Merged
merged 16 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 33 additions & 26 deletions ff_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,6 @@ static BaseType_t FF_ValidShortChar( char cChar );
#endif /* if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) */
#endif /* if ( ffconfigLFN_SUPPORT != 0 ) */

#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
static void FF_MakeNameCompliant( FF_T_WCHAR * pcName );
#else
static void FF_MakeNameCompliant( char * pcName );
#endif

#if ( FF_NOSTRCASECMP == 0 )
static portINLINE unsigned char prvToLower( unsigned char c )
{
Expand Down Expand Up @@ -2875,40 +2869,48 @@ FF_Error_t FF_ExtendDirectory( FF_IOManager_t * pxIOManager,
} /* FF_ExtendDirectory() */
/*-----------------------------------------------------------*/

static const uint8_t forbiddenChrs[] =
/* *INDENT-OFF* */
togrue marked this conversation as resolved.
Show resolved Hide resolved
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
static const FF_T_WCHAR forbiddenChars[] =
#else
static const uint8_t forbiddenChars[] =
#endif
{
/* Windows says: don't use these characters: '\/:*?"<>|'
* " * / : < > ? '\' ? | */
0x22, 0x2A, 0x2F, 0x3A, 0x3C, 0x3E, 0x3F, 0x5C, 0x7F, 0x7C
};
/* *INDENT-ON* */

/* *INDENT-OFF* */
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
static void FF_MakeNameCompliant( FF_T_WCHAR * pcName )
BaseType_t FF_IsNameCompliant( FF_T_WCHAR * pcName )
#else
static void FF_MakeNameCompliant( char * pcName )
BaseType_t FF_IsNameCompliant( char * pcName )
#endif
/* *INDENT-ON* */
{
BaseType_t xReturn = pdTRUE;
BaseType_t index;

if( ( uint8_t ) pcName[ 0 ] == FF_FAT_DELETED ) /* Support Japanese KANJI symbol0xE5. */
if( ( uint8_t ) pcName[ 0 ] == FF_FAT_DELETED ) /* Do not create a "deleted" entry 0xE5. */
{
pcName[ 0 ] = 0x05;
xReturn = pdFALSE;
}

for( ; *pcName; pcName++ )
{
for( index = 0; index < ( BaseType_t ) sizeof( forbiddenChrs ); index++ )
for( index = 0; index < ( BaseType_t ) ( sizeof( forbiddenChars ) / sizeof( forbiddenChars[ 0 ] ) ); index++ )
{
if( *pcName == forbiddenChrs[ index ] )
if( *pcName == forbiddenChars[ index ] )
{
*pcName = '_';
break;
xReturn = pdFALSE;
togrue marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
} /* FF_MakeNameCompliant() */

return xReturn;
} /* FF_IsNameCompliant() */
/*-----------------------------------------------------------*/

FF_Error_t FF_CreateDirent( FF_IOManager_t * pxIOManager,
Expand Down Expand Up @@ -2941,15 +2943,6 @@ FF_Error_t FF_CreateDirent( FF_IOManager_t * pxIOManager,
/* Round-up the number of LFN's needed: */
xLFNCount = ( BaseType_t ) ( ( NameLen + 12 ) / 13 );

#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
{
FF_MakeNameCompliant( pxDirEntry->pcFileName ); /* Ensure we don't break the Dir tables. */
}
#else
{
FF_MakeNameCompliant( pxDirEntry->pcFileName ); /* Ensure we don't break the Dir tables. */
}
#endif
memset( pucEntryBuffer, 0, sizeof( pucEntryBuffer ) );

#if ( ffconfigLFN_SUPPORT != 0 )
Expand Down Expand Up @@ -3127,7 +3120,15 @@ FF_Error_t FF_CreateDirent( FF_IOManager_t * pxIOManager,
STRNCPY( xMyFile.pcFileName, pcFileName, ffconfigMAX_FILENAME - 1 );
xMyFile.pcFileName[ ffconfigMAX_FILENAME - 1 ] = 0;

xMyFile.ulObjectCluster = FF_CreateClusterChain( pxIOManager, &xError );
if( FF_IsNameCompliant( xMyFile.pcFileName ) == pdFALSE )
{
xError = FF_createERR( FF_ERR_FILE_INVALID_PATH, FF_CREATEFILE );
}

if( FF_isERR( xError ) == pdFALSE )
{
xMyFile.ulObjectCluster = FF_CreateClusterChain( pxIOManager, &xError );
}

if( FF_isERR( xError ) == pdFALSE )
{
Expand Down Expand Up @@ -3269,6 +3270,12 @@ FF_Error_t FF_CreateDirent( FF_IOManager_t * pxIOManager,
break;
}

if( FF_IsNameCompliant( pcDirName ) == pdFALSE )
{
xError = FF_createERR( FF_ERR_DIR_INVALID_PATH, FF_MKDIR );
break;
}

xFindParams.ulDirCluster = FF_FindDir( pxIOManager, pcPath, ( uint16_t ) xIndex, &xError );

if( FF_isERR( xError ) )
Expand Down
66 changes: 40 additions & 26 deletions ff_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,7 @@ static FF_FILE * prvAllocFileHandle( FF_IOManager_t * pxIOManager,
* @retval FF_ERR_FILE_DESTINATION_EXISTS if the destination file exists.
* @retval FF_ERR_FILE_COULD_NOT_CREATE_DIRENT if dirent creation failed (fatal error!).
* @retval FF_ERR_FILE_DIR_NOT_FOUND if destination directory was not found.
* @retval FF_ERR_FILE_INVALID_PATH if destination path is invalid.
* @retval FF_ERR_FILE_SOURCE_NOT_FOUND if the source file was not found.
*
**/
Expand All @@ -886,11 +887,11 @@ static FF_FILE * prvAllocFileHandle( FF_IOManager_t * pxIOManager,
#endif
/* *INDENT-ON* */
{
FF_Error_t xError;
FF_Error_t xError = FF_ERR_NONE;
FF_FILE * pSrcFile, * pxDestFile;
FF_DirEnt_t xMyFile;
uint8_t ucEntryBuffer[ 32 ];
UBaseType_t xIndex;
size_t uxIndex = 0U;
uint32_t ulDirCluster = 0ul;
FF_FetchContext_t xFetchContext;

Expand All @@ -906,12 +907,46 @@ static FF_FILE * prvAllocFileHandle( FF_IOManager_t * pxIOManager,
}

#if ( ffconfigREMOVABLE_MEDIA != 0 )
else if( ( pxIOManager->ucFlags & FF_IOMAN_DEVICE_IS_EXTRACTED ) != 0 )
else if( ( pxIOManager->ucFlags & FF_IOMAN_DEVICE_IS_EXTRACTED ) != 0U )
{
xError = FF_createERR( FF_ERR_IOMAN_DRIVER_NOMEDIUM, FF_MOVE );
}
#endif /* ffconfigREMOVABLE_MEDIA */
else

if( FF_isERR( xError ) == pdFALSE )
{
uxIndex = ( size_t ) STRLEN( szDestinationFile );

/* Find the base name. */
while( uxIndex != 0U )
{
if( ( szDestinationFile[ uxIndex ] == '\\' ) || ( szDestinationFile[ uxIndex ] == '/' ) )
{
break;
}

uxIndex--;
}

/* Copy the base name of the destination file. */
STRNCPY( xMyFile.pcFileName, ( szDestinationFile + uxIndex + 1 ), ffconfigMAX_FILENAME - 1 );
xMyFile.pcFileName[ ffconfigMAX_FILENAME - 1 ] = 0;

/* Now check if the target base name is compliant. */
if( FF_IsNameCompliant( xMyFile.pcFileName ) == pdFALSE )
{
xError = FF_createERR( FF_ERR_FILE_INVALID_PATH, FF_MOVE );
}

if( uxIndex == 0U )
{
/* Give the directory part a minimum
* length of 1, to get '/' at least. */
uxIndex = 1U;
}
}

if( FF_isERR( xError ) == pdFALSE )
{
/* Check destination file doesn't exist! */
pxDestFile = FF_Open( pxIOManager, szDestinationFile, FF_MODE_READ, &xError );
Expand Down Expand Up @@ -969,30 +1004,9 @@ static FF_FILE * prvAllocFileHandle( FF_IOManager_t * pxIOManager,
xMyFile.ulObjectCluster = pSrcFile->ulObjectCluster;
xMyFile.usCurrentItem = 0;

xIndex = ( UBaseType_t ) STRLEN( szDestinationFile );

while( xIndex != 0 )
{
if( ( szDestinationFile[ xIndex ] == '\\' ) || ( szDestinationFile[ xIndex ] == '/' ) )
{
break;
}

xIndex--;
}

/* Copy the base name of the destination file. */
STRNCPY( xMyFile.pcFileName, ( szDestinationFile + xIndex + 1 ), ffconfigMAX_FILENAME - 1 );
xMyFile.pcFileName[ ffconfigMAX_FILENAME - 1 ] = 0;

if( xIndex == 0 )
{
xIndex = 1;
}

/* Find the (cluster of the) directory in which the target file will be located.
* It must exist before calling FF_Move(). */
ulDirCluster = FF_FindDir( pxIOManager, szDestinationFile, ( uint16_t ) xIndex, &xError );
ulDirCluster = FF_FindDir( pxIOManager, szDestinationFile, ( uint16_t ) uxIndex, &xError );
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions include/ff_dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,16 @@ int8_t FF_PushEntry( FF_IOManager_t * pxIOManager,
uint8_t * buffer,
void * pParam );

/*
* FF_IsNameCompliant is a function that checks if a given path name
* contains any legal characters only.
*/
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
BaseType_t FF_IsNameCompliant( FF_T_WCHAR * pcName );
#else
BaseType_t FF_IsNameCompliant( char * pcName );
#endif

static portINLINE BaseType_t FF_isEndOfDir( const uint8_t * pucEntryBuffer )
{
return pucEntryBuffer[ 0 ] == ( uint8_t ) 0;
Expand Down
1 change: 1 addition & 0 deletions include/ff_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
#define FF_MKDIR ( ( 12 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_TRAVERSE ( ( 13 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_FINDDIR ( ( 14 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_CREATEFILE ( ( 15 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )

/*----- FF_FILE - The FreeRTOS+FAT file handling routines. */
#define FF_GETMODEBITS ( ( 1 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
Expand Down
Loading