fixed crash and some memory leaks in FS module

This commit is contained in:
BADIM-PC\Vadim 2018-02-16 12:59:39 +03:00
parent a2d961f060
commit 148552893a
3 changed files with 132 additions and 55 deletions

View File

@ -34,9 +34,6 @@ FILE* _wfopen(const wchar_t *, const wchar_t *);
wchar_t* wcsrchr(const wchar_t *, wchar_t); wchar_t* wcsrchr(const wchar_t *, wchar_t);
wchar_t* wcscpy(wchar_t *, const wchar_t *); wchar_t* wcscpy(wchar_t *, const wchar_t *);
#define UTF8ToString(S) (wchar_t *)SDL_iconv_string("UTF-16LE", "UTF-8", (char *)(S), SDL_strlen(S)+1)
#define StringToUTF8(S) SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(S), (SDL_wcslen(S)+1)*sizeof(wchar_t))
void file_dialog_load(file_dialog_load_callback callback, void* data) void file_dialog_load(file_dialog_load_callback callback, void* data)
{ {
OPENFILENAMEW ofn; OPENFILENAMEW ofn;
@ -71,7 +68,10 @@ void file_dialog_load(file_dialog_load_callback callback, void* data)
const wchar_t* basename = wcsrchr(filename, L'\\'); const wchar_t* basename = wcsrchr(filename, L'\\');
const wchar_t* name = basename ? basename + 1 : filename; const wchar_t* name = basename ? basename + 1 : filename;
callback(StringToUTF8(name), buffer, size, data, 0); char resName[MAX_PATH];
wcstombs(resName, name, MAX_PATH);
callback(resName, buffer, size, data, 0);
free(buffer); free(buffer);
return; return;
} }
@ -87,8 +87,7 @@ void file_dialog_save(file_dialog_save_callback callback, const char* name, cons
SDL_zero(ofn); SDL_zero(ofn);
wchar_t filename[MAX_PATH]; wchar_t filename[MAX_PATH];
memset(filename, 0, sizeof(filename)); mbstowcs(filename, name, MAX_PATH);
wcscpy(filename, UTF8ToString(name));
ofn.lStructSize = sizeof(ofn); ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = filename; ofn.lpstrFile = filename;

165
src/fs.c
View File

@ -106,29 +106,33 @@ bool fsIsInPublicDir(FileSystem* fs)
#if defined(__TIC_WINDOWS__) || defined(__TIC_WINRT__) #if defined(__TIC_WINDOWS__) || defined(__TIC_WINRT__)
typedef wchar_t fsString;
#define __S(x) L ## x #define __S(x) L ## x
#define _S(x) __S(x) #define _S(x) __S(x)
static const wchar_t* UTF8ToString(const char* str) static const fsString* utf8ToString(const char* str)
{ {
static wchar_t wstr[FILENAME_MAX]; fsString* wstr = malloc(FILENAME_MAX * sizeof(fsString));
mbstowcs(wstr, str, FILENAME_MAX); mbstowcs(wstr, str, FILENAME_MAX);
return wstr; return wstr;
} }
static char* StringToUTF8(const wchar_t* wstr) static const char* stringToUtf8(const fsString* wstr)
{ {
static char str[FILENAME_MAX]; char* str = malloc(FILENAME_MAX * sizeof(char));
wcstombs(str, wstr, FILENAME_MAX); wcstombs(str, wstr, FILENAME_MAX);
return str; return str;
} }
FILE* _wfopen(const wchar_t *, const wchar_t *); #define freeString(S) free((void*)S)
int _wremove(const wchar_t *);
FILE* _wfopen(const fsString *, const fsString *);
int _wremove(const fsString *);
#define TIC_DIR _WDIR #define TIC_DIR _WDIR
#define tic_dirent _wdirent #define tic_dirent _wdirent
@ -145,10 +149,14 @@ int _wremove(const wchar_t *);
#else #else
typedef char fsString;
#define _S(x) (x) #define _S(x) (x)
#define UTF8ToString(S) (S) #define utf8ToString(S) (S)
#define StringToUTF8(S) (S) #define stringToUtf8(S) (S)
#define freeString(S)
#define TIC_DIR DIR #define TIC_DIR DIR
#define tic_dirent dirent #define tic_dirent dirent
@ -309,38 +317,62 @@ void fsEnumFiles(FileSystem* fs, ListCallback callback, void* data)
const char* path = getFilePath(fs, ""); const char* path = getFilePath(fs, "");
if ((dir = tic_opendir(UTF8ToString(path))) != NULL) {
const fsString* pathString = utf8ToString(path);
if ((dir = tic_opendir(pathString)) != NULL)
{ {
while ((ent = tic_readdir(dir)) != NULL) while ((ent = tic_readdir(dir)) != NULL)
{ {
if (ent->d_type == DT_DIR && *ent->d_name != '.') if (ent->d_type == DT_DIR && *ent->d_name != _S('.'))
{ {
if (!callback(StringToUTF8(ent->d_name), NULL, 0, data, true))break; const char* name = stringToUtf8(ent->d_name);
bool result = callback(name, NULL, 0, data, true);
freeString(name);
if(!result) break;
} }
} }
tic_closedir(dir); tic_closedir(dir);
} }
if ((dir = tic_opendir(UTF8ToString(path))) != NULL) freeString(pathString);
}
{
const fsString* pathString = utf8ToString(path);
if ((dir = tic_opendir(pathString)) != NULL)
{ {
while ((ent = tic_readdir(dir)) != NULL) while ((ent = tic_readdir(dir)) != NULL)
{ {
if (ent->d_type == DT_REG) if (ent->d_type == DT_REG)
{ {
if (!callback(StringToUTF8(ent->d_name), NULL, 0, data, false))break; const char* name = stringToUtf8(ent->d_name);
bool result = callback(name, NULL, 0, data, false);
freeString(name);
if (!result)break;
} }
} }
tic_closedir(dir); tic_closedir(dir);
} }
freeString(pathString);
}
} }
bool fsDeleteDir(FileSystem* fs, const char* name) bool fsDeleteDir(FileSystem* fs, const char* name)
{ {
#if defined(__TIC_WINRT__) || defined(__TIC_WINDOWS__) #if defined(__TIC_WINRT__) || defined(__TIC_WINDOWS__)
const char* path = getFilePath(fs, name); const char* path = getFilePath(fs, name);
bool result = tic_rmdir(UTF8ToString(path));
const fsString* pathString = utf8ToString(path);
bool result = tic_rmdir(pathString);
freeString(pathString);
#else #else
bool result = rmdir(getFilePath(fs, name)); bool result = rmdir(getFilePath(fs, name));
#endif #endif
@ -355,7 +387,10 @@ bool fsDeleteDir(FileSystem* fs, const char* name)
bool fsDeleteFile(FileSystem* fs, const char* name) bool fsDeleteFile(FileSystem* fs, const char* name)
{ {
const char* path = getFilePath(fs, name); const char* path = getFilePath(fs, name);
bool result = tic_remove(UTF8ToString(path));
const fsString* pathString = utf8ToString(path);
bool result = tic_remove(pathString);
freeString(pathString);
#if defined(__EMSCRIPTEN__) #if defined(__EMSCRIPTEN__)
EM_ASM(FS.syncfs(function(){})); EM_ASM(FS.syncfs(function(){}));
@ -380,7 +415,10 @@ static void onAddFile(const char* name, const u8* buffer, s32 size, void* data,
{ {
const char* destname = getFilePath(fs, name); const char* destname = getFilePath(fs, name);
FILE* file = tic_fopen(UTF8ToString(destname), _S("rb")); const fsString* destString = utf8ToString(destname);
FILE* file = tic_fopen(destString, _S("rb"));
freeString(destString);
if(file) if(file)
{ {
fclose(file); fclose(file);
@ -390,7 +428,10 @@ static void onAddFile(const char* name, const u8* buffer, s32 size, void* data,
else else
{ {
const char* path = getFilePath(fs, name); const char* path = getFilePath(fs, name);
FILE* dest = tic_fopen(UTF8ToString(path), _S("wb"));
const fsString* pathString = utf8ToString(path);
FILE* dest = tic_fopen(pathString, _S("wb"));
freeString(pathString);
if (dest) if (dest)
{ {
@ -548,7 +589,11 @@ bool fsIsDir(FileSystem* fs, const char* name)
const char* path = getFilePath(fs, name); const char* path = getFilePath(fs, name);
struct tic_stat_struct s; struct tic_stat_struct s;
return tic_stat(UTF8ToString(path), &s) == 0 && S_ISDIR(s.st_mode); const fsString* pathString = utf8ToString(path);
bool ret = tic_stat(pathString, &s) == 0 && S_ISDIR(s.st_mode);
freeString(pathString);
return ret;
} }
void fsGetFileData(GetCallback callback, const char* name, void* buffer, size_t size, u32 mode, void* data) void fsGetFileData(GetCallback callback, const char* name, void* buffer, size_t size, u32 mode, void* data)
@ -601,7 +646,9 @@ void fsGetFile(FileSystem* fs, GetCallback callback, const char* name, void* dat
bool fsWriteFile(const char* name, const void* buffer, s32 size) bool fsWriteFile(const char* name, const void* buffer, s32 size)
{ {
FILE* file = tic_fopen(UTF8ToString(name), _S("wb")); const fsString* pathString = utf8ToString(name);
FILE* file = tic_fopen(pathString, _S("wb"));
freeString(pathString);
if(file) if(file)
{ {
@ -626,7 +673,10 @@ bool fsCopyFile(const char* src, const char* dst)
s32 size = 0; s32 size = 0;
{ {
FILE* file = tic_fopen(UTF8ToString(src), _S("rb")); const fsString* pathString = utf8ToString(src);
FILE* file = tic_fopen(pathString, _S("rb"));
freeString(pathString);
if(file) if(file)
{ {
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
@ -641,7 +691,9 @@ bool fsCopyFile(const char* src, const char* dst)
if(buffer) if(buffer)
{ {
FILE* file = tic_fopen(UTF8ToString(dst), _S("wb")); const fsString* pathString = utf8ToString(dst);
FILE* file = tic_fopen(pathString, _S("wb"));
freeString(pathString);
if(file) if(file)
{ {
@ -659,7 +711,10 @@ bool fsCopyFile(const char* src, const char* dst)
void* fsReadFile(const char* path, s32* size) void* fsReadFile(const char* path, s32* size)
{ {
FILE* file = tic_fopen(UTF8ToString(path), _S("rb")); const fsString* pathString = utf8ToString(path);
FILE* file = tic_fopen(pathString, _S("rb"));
freeString(pathString);
void* buffer = NULL; void* buffer = NULL;
if(file) if(file)
@ -679,37 +734,43 @@ void* fsReadFile(const char* path, s32* size)
static void makeDir(const char* name) static void makeDir(const char* name)
{ {
tic_mkdir(UTF8ToString(name)); const fsString* pathString = utf8ToString(name);
tic_mkdir(pathString);
freeString(pathString);
#if defined(__EMSCRIPTEN__) #if defined(__EMSCRIPTEN__)
EM_ASM(FS.syncfs(function(){})); EM_ASM(FS.syncfs(function(){}));
#endif #endif
} }
const char* fsFilename(const char *path) static void fsFullname(const char *path, char *fullname)
{ {
const char* full = fsFullname(path);
const char* base = fsBasename(path);
return base ? full + strlen(fsBasename(path)) : NULL;
}
const char* fsFullname(const char *path)
{
char* result = NULL;
#if defined(__TIC_WINDOWS__) || defined(__TIC_WINRT__) #if defined(__TIC_WINDOWS__) || defined(__TIC_WINRT__)
static wchar_t wpath[FILENAME_MAX]; static wchar_t wpath[FILENAME_MAX];
GetFullPathNameW(UTF8ToString(path), sizeof(wpath), wpath, NULL);
result = StringToUTF8(wpath); const fsString* pathString = utf8ToString(path);
GetFullPathNameW(pathString, sizeof(wpath), wpath, NULL);
freeString(pathString);
const char* res = stringToUtf8(wpath);
#else #else
result = realpath(path, NULL); const char* res = realpath(path, NULL);
#endif #endif
return result; strcpy(fullname, res);
free((void*)res);
}
const char* fsFilename(const char *path)
{
static char full[FILENAME_MAX];
fsFullname(path, full);
const char* base = fsBasename(path);
return base ? full + strlen(fsBasename(path)) : NULL;
} }
const char* fsBasename(const char *path) const char* fsBasename(const char *path)
@ -723,10 +784,16 @@ const char* fsBasename(const char *path)
#endif #endif
{ {
char* full = (char*)fsFullname(path); static char full[FILENAME_MAX];
fsFullname(path, full);
struct tic_stat_struct s; struct tic_stat_struct s;
if(tic_stat(UTF8ToString(full), &s) == 0)
const fsString* fullString = utf8ToString(full);
s32 ret = tic_stat(fullString, &s);
freeString(fullString);
if(ret == 0)
{ {
result = full; result = full;
@ -757,7 +824,12 @@ const char* fsBasename(const char *path)
bool fsExists(const char* name) bool fsExists(const char* name)
{ {
struct tic_stat_struct s; struct tic_stat_struct s;
return tic_stat(UTF8ToString(name), &s) == 0;
const fsString* pathString = utf8ToString(name);
bool ret = tic_stat(pathString, &s) == 0;
freeString(pathString);
return ret;
} }
bool fsExistsFile(FileSystem* fs, const char* name) bool fsExistsFile(FileSystem* fs, const char* name)
@ -769,7 +841,11 @@ u64 fsMDate(FileSystem* fs, const char* name)
{ {
struct tic_stat_struct s; struct tic_stat_struct s;
if(tic_stat(UTF8ToString(getFilePath(fs, name)), &s) == 0 && S_ISREG(s.st_mode)) const fsString* pathString = utf8ToString(getFilePath(fs, name));
s32 ret = tic_stat(pathString, &s);
freeString(pathString);
if(ret == 0 && S_ISREG(s.st_mode))
{ {
return s.st_mtime; return s.st_mtime;
} }
@ -855,7 +931,10 @@ void* fsLoadFile(FileSystem* fs, const char* name, s32* size)
} }
else else
{ {
FILE* file = tic_fopen(UTF8ToString(getFilePath(fs, name)), _S("rb")); const fsString* pathString = utf8ToString(getFilePath(fs, name));
FILE* file = tic_fopen(pathString, _S("rb"));
freeString(pathString);
void* ptr = NULL; void* ptr = NULL;
if(file) if(file)

View File

@ -64,7 +64,6 @@ u64 fsMDate(FileSystem* fs, const char* name);
const char* fsBasename(const char *path); const char* fsBasename(const char *path);
const char* fsFilename(const char *path); const char* fsFilename(const char *path);
const char* fsFullname(const char *path);
bool fsExists(const char* name); bool fsExists(const char* name);
void* fsReadFile(const char* path, s32* size); void* fsReadFile(const char* path, s32* size);
bool fsWriteFile(const char* path, const void* data, s32 size); bool fsWriteFile(const char* path, const void* data, s32 size);