rcore: fix GetFileNameWithoutExt returning wrong value on repeated calls
GetFileNameWithoutExt returns a pointer into a single static buffer, so two consecutive calls return two pointers that alias the same address. Any use of both results (snprintf, separate variables, etc.) silently reads whichever path was written last. Mirror the rotating-buffer idiom TextFormat uses in rtext.c (and the rcore.c !SUPPORT_MODULE_RTEXT fallback): MAX_FILENAME_BUFFERS (default 4, overridable) slots with a rotating index. Same lifetime contract as TextFormat. No API/ABI change. Drive-by: fixes the pre-existing fileNameLenght -> fileNameLength typo in the same function.
This commit is contained in:
parent
019cc889fc
commit
c4ba2a2b6f
|
|
@ -1152,7 +1152,7 @@ RLAPI int GetFileLength(const char *fileName); // Get file
|
|||
RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time)
|
||||
RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png')
|
||||
RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string
|
||||
RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string)
|
||||
RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses rotating static strings)
|
||||
RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string)
|
||||
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string)
|
||||
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
|
||||
|
|
|
|||
29
src/rcore.c
29
src/rcore.c
|
|
@ -2503,31 +2503,42 @@ const char *GetFileName(const char *filePath)
|
|||
return fileName + 1;
|
||||
}
|
||||
|
||||
// Get filename string without extension (uses static string)
|
||||
// Get filename string without extension (uses rotating static strings)
|
||||
// WARNING: String returned will expire after this function is called MAX_FILENAME_BUFFERS times
|
||||
const char *GetFileNameWithoutExt(const char *filePath)
|
||||
{
|
||||
#define MAX_FILENAME_LENGTH 256
|
||||
#ifndef MAX_FILENAME_BUFFERS
|
||||
#define MAX_FILENAME_BUFFERS 4 // Maximum number of static buffers for filename without extension
|
||||
#endif
|
||||
|
||||
static char fileName[MAX_FILENAME_LENGTH] = { 0 };
|
||||
memset(fileName, 0, MAX_FILENAME_LENGTH);
|
||||
// Create an array of buffers so strings don't expire until MAX_FILENAME_BUFFERS invocations
|
||||
static char fileName[MAX_FILENAME_BUFFERS][MAX_FILENAME_LENGTH] = { 0 };
|
||||
static int index = 0;
|
||||
|
||||
char *currentBuffer = fileName[index];
|
||||
memset(currentBuffer, 0, MAX_FILENAME_LENGTH); // Clear buffer before using
|
||||
|
||||
if (filePath != NULL)
|
||||
{
|
||||
strncpy(fileName, GetFileName(filePath), MAX_FILENAME_LENGTH - 1); // Get filename.ext without path
|
||||
int fileNameLenght = (int)strlen(fileName); // Get size in bytes
|
||||
strncpy(currentBuffer, GetFileName(filePath), MAX_FILENAME_LENGTH - 1); // Get filename.ext without path
|
||||
int fileNameLength = (int)strlen(currentBuffer); // Get size in bytes
|
||||
|
||||
for (int i = fileNameLenght; i > 0; i--) // Reverse search '.'
|
||||
for (int i = fileNameLength; i > 0; i--) // Reverse search '.'
|
||||
{
|
||||
if (fileName[i] == '.')
|
||||
if (currentBuffer[i] == '.')
|
||||
{
|
||||
// NOTE: Break on first '.' found
|
||||
fileName[i] = '\0';
|
||||
currentBuffer[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
index += 1; // Move to next buffer for next function call
|
||||
if (index >= MAX_FILENAME_BUFFERS) index = 0;
|
||||
}
|
||||
|
||||
return fileName;
|
||||
return currentBuffer;
|
||||
}
|
||||
|
||||
// Get directory for a given filePath
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user