Skip to content

Commit

Permalink
Change the FF_MakeNameCompliant behavior
Browse files Browse the repository at this point in the history
* Change the handling of invalid file-names to cause an error.
Depending on the entry to create (directory/file), a different error code is returned.
  • Loading branch information
ifta-togure authored and togrue committed Jan 29, 2024
1 parent bc13a8a commit a7f6389
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 120 deletions.
253 changes: 133 additions & 120 deletions ff_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ static BaseType_t FF_ValidShortChar( char cChar );
#endif /* if ( ffconfigLFN_SUPPORT != 0 ) */

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

#if ( FF_NOSTRCASECMP == 0 )
Expand Down Expand Up @@ -2875,7 +2875,13 @@ FF_Error_t FF_ExtendDirectory( FF_IOManager_t * pxIOManager,
} /* FF_ExtendDirectory() */
/*-----------------------------------------------------------*/

static const uint8_t forbiddenChrs[] =
/* *INDENT-OFF* */
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
static const FF_T_WCHAR forbiddenChrs[] =
#else
static const uint8_t forbiddenChrs[] =
#endif
/* *INDENT-ON* */
{
/* Windows says: don't use these characters: '\/:*?"<>|'
* " * / : < > ? '\' ? | */
Expand All @@ -2884,15 +2890,17 @@ static const uint8_t forbiddenChrs[] =

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

if( ( uint8_t ) pcName[ 0 ] == FF_FAT_DELETED ) /* Support Japanese KANJI symbol0xE5. */
/* Support Japanese KANJI symbol 0xE5 (stored as 0x05) */
if( ( uint8_t ) pcName[ 0 ] == FF_FAT_DELETED )
{
pcName[ 0 ] = 0x05;
}
Expand All @@ -2903,11 +2911,11 @@ static const uint8_t forbiddenChrs[] =
{
if( *pcName == forbiddenChrs[ index ] )
{
*pcName = '_';
break;
xReturn = pdFALSE;
}
}
}
return xReturn;
} /* FF_MakeNameCompliant() */
/*-----------------------------------------------------------*/

Expand All @@ -2929,7 +2937,7 @@ FF_Error_t FF_CreateDirent( FF_IOManager_t * pxIOManager,
char pcShortName[ 13 ];
#endif
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
uint16_t NameLen = ( uint16_t ) wcslen( pxDirEntry->pcFileName );
uint16_t NameLen = ( uint16_t ) wcslen( pxDirEntry->pcFileName );
#else
uint16_t NameLen = ( uint16_t ) strlen( pxDirEntry->pcFileName );
#endif
Expand All @@ -2941,160 +2949,165 @@ 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
if ( FF_MakeNameCompliant( pxDirEntry->pcFileName ) == pdTRUE )
{
FF_MakeNameCompliant( pxDirEntry->pcFileName ); /* Ensure we don't break the Dir tables. */
}
#endif
memset( pucEntryBuffer, 0, sizeof( pucEntryBuffer ) );

#if ( ffconfigLFN_SUPPORT != 0 )
{
/* Create and push the LFN's. */
/* Find enough places for the LFNs and the ShortName. */
xEntryCount = xLFNCount + 1;
}
#else
{
xEntryCount = 1;
}
#endif

/* Create the ShortName. */
FF_LockDirectory( pxIOManager );

do
{
/* Open a do {} while( pdFALSE ) loop to allow the use of break statements. */
/* As FF_FindShortName( ) can fail, it should be called before finding a free directory entry. */
if( ( pxFindParams->ulFlags & FIND_FLAG_SHORTNAME_SET ) == 0 )
{
FF_CreateShortName( pxFindParams, pxDirEntry->pcFileName );
}

lFitShort = FF_FindShortName( pxIOManager, pxFindParams );
memset( pucEntryBuffer, 0, sizeof( pucEntryBuffer ) );

memcpy( pucEntryBuffer, pxFindParams->pcEntryBuffer, sizeof( pucEntryBuffer ) );

if( FF_isERR( lFitShort ) )
#if ( ffconfigLFN_SUPPORT != 0 )
{
xReturn = lFitShort;
break;
/* Create and push the LFN's. */
/* Find enough places for the LFNs and the ShortName. */
xEntryCount = xLFNCount + 1;
}

if( lFitShort != 0 )
#else
{
/* There is no need to create a LFN entry because the file name
* fits into a normal 32-byte entry.. */
xLFNCount = 0;
xEntryCount = 1;
}
#endif

lFreeEntry = FF_FindFreeDirent( pxIOManager, pxFindParams, ( uint16_t ) xEntryCount );
/* Create the ShortName. */
FF_LockDirectory( pxIOManager );

if( FF_isERR( lFreeEntry ) )
{
xReturn = lFreeEntry;
break;
}

#if ( ffconfigLFN_SUPPORT != 0 )
do
{
if( xLFNCount > 0 )
/* Open a do {} while( pdFALSE ) loop to allow the use of break statements. */
/* As FF_FindShortName( ) can fail, it should be called before finding a free directory entry. */
if( ( pxFindParams->ulFlags & FIND_FLAG_SHORTNAME_SET ) == 0 )
{
ucCheckSum = FF_CreateChkSum( pucEntryBuffer );
xReturn = FF_CreateLFNs( pxIOManager, ulDirCluster, pxDirEntry->pcFileName, ucCheckSum, ( uint16_t ) lFreeEntry );
FF_CreateShortName( pxFindParams, pxDirEntry->pcFileName );
}
}
#else
{
xLFNCount = 0;
}
#endif /* ffconfigLFN_SUPPORT */

if( FF_isERR( xReturn ) == pdFALSE )
{
#if ( ffconfigTIME_SUPPORT != 0 )
lFitShort = FF_FindShortName( pxIOManager, pxFindParams );

memcpy( pucEntryBuffer, pxFindParams->pcEntryBuffer, sizeof( pucEntryBuffer ) );

if( FF_isERR( lFitShort ) )
{
FF_GetSystemTime( &pxDirEntry->xCreateTime ); /* Date and Time Created. */
pxDirEntry->xModifiedTime = pxDirEntry->xCreateTime; /* Date and Time Modified. */
pxDirEntry->xAccessedTime = pxDirEntry->xCreateTime; /* Date of Last Access. */
FF_PlaceTime( pucEntryBuffer, FF_FAT_DIRENT_CREATE_TIME, &pxDirEntry->xCreateTime );
FF_PlaceDate( pucEntryBuffer, FF_FAT_DIRENT_CREATE_DATE, &pxDirEntry->xCreateTime );
FF_PlaceTime( pucEntryBuffer, FF_FAT_DIRENT_LASTMOD_TIME, &pxDirEntry->xModifiedTime );
FF_PlaceDate( pucEntryBuffer, FF_FAT_DIRENT_LASTMOD_DATE, &pxDirEntry->xModifiedTime );
xReturn = lFitShort;
break;
}
#endif /* ffconfigTIME_SUPPORT */

FF_putChar( pucEntryBuffer, FF_FAT_DIRENT_ATTRIB, pxDirEntry->ucAttrib );
#if ( ffconfigSHORTNAME_CASE != 0 )
FF_putChar( pucEntryBuffer, FF_FAT_CASE_OFFS, ( uint32_t ) lFitShort & ( FF_FAT_CASE_ATTR_BASE | FF_FAT_CASE_ATTR_EXT ) );
#endif
FF_putShort( pucEntryBuffer, FF_FAT_DIRENT_CLUS_HIGH, ( uint16_t ) ( pxDirEntry->ulObjectCluster >> 16 ) );
FF_putShort( pucEntryBuffer, FF_FAT_DIRENT_CLUS_LOW, ( uint16_t ) ( pxDirEntry->ulObjectCluster ) );
FF_putLong( pucEntryBuffer, FF_FAT_DIRENT_FILESIZE, pxDirEntry->ulFileSize );
if( lFitShort != 0 )
{
/* There is no need to create a LFN entry because the file name
* fits into a normal 32-byte entry.. */
xLFNCount = 0;
xEntryCount = 1;
}

xReturn = FF_InitEntryFetch( pxIOManager, ulDirCluster, &xFetchContext );
lFreeEntry = FF_FindFreeDirent( pxIOManager, pxFindParams, ( uint16_t ) xEntryCount );

if( FF_isERR( xReturn ) )
if( FF_isERR( lFreeEntry ) )
{
xReturn = lFreeEntry;
break;
}

xReturn = FF_PushEntryWithContext( pxIOManager, ( uint16_t ) ( lFreeEntry + xLFNCount ), &xFetchContext, pucEntryBuffer );

#if ( ffconfigLFN_SUPPORT != 0 )
{
FF_Error_t xTempError;

xTempError = FF_CleanupEntryFetch( pxIOManager, &xFetchContext );

if( FF_isERR( xReturn ) == pdFALSE )
if( xLFNCount > 0 )
{
xReturn = xTempError;
ucCheckSum = FF_CreateChkSum( pucEntryBuffer );
xReturn = FF_CreateLFNs( pxIOManager, ulDirCluster, pxDirEntry->pcFileName, ucCheckSum, ( uint16_t ) lFreeEntry );
}
}

if( FF_isERR( xReturn ) )
#else
{
break;
xLFNCount = 0;
}
#endif /* ffconfigLFN_SUPPORT */

#if ( ffconfigHASH_CACHE != 0 )
if( FF_isERR( xReturn ) == pdFALSE )
{
if( FF_DirHashed( pxIOManager, ulDirCluster ) == pdFALSE )
#if ( ffconfigTIME_SUPPORT != 0 )
{
/* Hash the directory. */
FF_HashDir( pxIOManager, ulDirCluster );
FF_GetSystemTime( &pxDirEntry->xCreateTime ); /* Date and Time Created. */
pxDirEntry->xModifiedTime = pxDirEntry->xCreateTime; /* Date and Time Modified. */
pxDirEntry->xAccessedTime = pxDirEntry->xCreateTime; /* Date of Last Access. */
FF_PlaceTime( pucEntryBuffer, FF_FAT_DIRENT_CREATE_TIME, &pxDirEntry->xCreateTime );
FF_PlaceDate( pucEntryBuffer, FF_FAT_DIRENT_CREATE_DATE, &pxDirEntry->xCreateTime );
FF_PlaceTime( pucEntryBuffer, FF_FAT_DIRENT_LASTMOD_TIME, &pxDirEntry->xModifiedTime );
FF_PlaceDate( pucEntryBuffer, FF_FAT_DIRENT_LASTMOD_DATE, &pxDirEntry->xModifiedTime );
}
#endif /* ffconfigTIME_SUPPORT */

memcpy( pcShortName, pucEntryBuffer, 11 );
FF_ProcessShortName( pcShortName ); /* Format the shortname to 8.3. */
#if ( ffconfigHASH_FUNCTION == CRC16 )
FF_putChar( pucEntryBuffer, FF_FAT_DIRENT_ATTRIB, pxDirEntry->ucAttrib );
#if ( ffconfigSHORTNAME_CASE != 0 )
FF_putChar( pucEntryBuffer, FF_FAT_CASE_OFFS, ( uint32_t ) lFitShort & ( FF_FAT_CASE_ATTR_BASE | FF_FAT_CASE_ATTR_EXT ) );
#endif
FF_putShort( pucEntryBuffer, FF_FAT_DIRENT_CLUS_HIGH, ( uint16_t ) ( pxDirEntry->ulObjectCluster >> 16 ) );
FF_putShort( pucEntryBuffer, FF_FAT_DIRENT_CLUS_LOW, ( uint16_t ) ( pxDirEntry->ulObjectCluster ) );
FF_putLong( pucEntryBuffer, FF_FAT_DIRENT_FILESIZE, pxDirEntry->ulFileSize );

xReturn = FF_InitEntryFetch( pxIOManager, ulDirCluster, &xFetchContext );

if( FF_isERR( xReturn ) )
{
FF_AddDirentHash( pxIOManager, ulDirCluster, ( uint32_t ) FF_GetCRC16( ( uint8_t * ) pcShortName, ( uint32_t ) strlen( pcShortName ) ) );
break;
}
#elif ( ffconfigHASH_FUNCTION == CRC8 )

xReturn = FF_PushEntryWithContext( pxIOManager, ( uint16_t ) ( lFreeEntry + xLFNCount ), &xFetchContext, pucEntryBuffer );

{
FF_AddDirentHash( pxIOManager, ulDirCluster, ( uint32_t ) FF_GetCRC8( ( uint8_t * ) pcShortName, strlen( pcShortName ) ) );
FF_Error_t xTempError;

xTempError = FF_CleanupEntryFetch( pxIOManager, &xFetchContext );

if( FF_isERR( xReturn ) == pdFALSE )
{
xReturn = xTempError;
}
}
#endif /* ffconfigHASH_FUNCTION */

if( FF_isERR( xReturn ) )
{
break;
}

#if ( ffconfigHASH_CACHE != 0 )
{
if( FF_DirHashed( pxIOManager, ulDirCluster ) == pdFALSE )
{
/* Hash the directory. */
FF_HashDir( pxIOManager, ulDirCluster );
}

memcpy( pcShortName, pucEntryBuffer, 11 );
FF_ProcessShortName( pcShortName ); /* Format the shortname to 8.3. */
#if ( ffconfigHASH_FUNCTION == CRC16 )
{
FF_AddDirentHash( pxIOManager, ulDirCluster, ( uint32_t ) FF_GetCRC16( ( uint8_t * ) pcShortName, ( uint32_t ) strlen( pcShortName ) ) );
}
#elif ( ffconfigHASH_FUNCTION == CRC8 )
{
FF_AddDirentHash( pxIOManager, ulDirCluster, ( uint32_t ) FF_GetCRC8( ( uint8_t * ) pcShortName, strlen( pcShortName ) ) );
}
#endif /* ffconfigHASH_FUNCTION */
}
#endif /* ffconfigHASH_CACHE*/
}
#endif /* ffconfigHASH_CACHE*/
}
}
while( pdFALSE );
while( pdFALSE );

FF_UnlockDirectory( pxIOManager );
FF_UnlockDirectory( pxIOManager );

if( FF_isERR( xReturn ) == pdFALSE )
if( FF_isERR( xReturn ) == pdFALSE )
{
if( pxDirEntry != NULL )
{
pxDirEntry->usCurrentItem = ( uint16_t ) ( lFreeEntry + xLFNCount );
}
}
} /* if ( FF_MakeNameCompliant( pxDirEntry->pcFileName ) == pdTRUE ) */
else
{
if( pxDirEntry != NULL )
if ( pxDirEntry->ucAttrib & FF_FAT_ATTR_DIR )
{
xReturn = FF_createERR( FF_ERR_DIR_INVALID_PATH, FF_CREATEDIRENT );
}
else
{
pxDirEntry->usCurrentItem = ( uint16_t ) ( lFreeEntry + xLFNCount );
xReturn = FF_createERR( FF_ERR_FILE_INVALID_PATH, FF_CREATEDIRENT );
}
}

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_CREATEDIRENT ( ( 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

0 comments on commit a7f6389

Please sign in to comment.