mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-29 15:22:08 +00:00
- sanitization of temporary file stuff for Timidity++.
* do not use the global temp directory. Instead create one in the AppData folder. * removed lots of unneeded code from tmpfileplus. * use C++ strings in there.
This commit is contained in:
parent
f6f17fbfb4
commit
7cbcbe66c0
7 changed files with 105 additions and 83 deletions
|
@ -53,6 +53,7 @@ FString M_ZLibError(int zerrnum);
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
FString GetUserFile (const char *path); // Prepends ~/.zdoom to path
|
FString GetUserFile (const char *path); // Prepends ~/.zdoom to path
|
||||||
#endif
|
#endif
|
||||||
|
FString M_GetAppDataPath(bool create);
|
||||||
FString M_GetCachePath(bool create);
|
FString M_GetCachePath(bool create);
|
||||||
FString M_GetAutoexecPath();
|
FString M_GetAutoexecPath();
|
||||||
FString M_GetCajunPath(const char *filename);
|
FString M_GetCajunPath(const char *filename);
|
||||||
|
|
|
@ -39,6 +39,35 @@
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
#include "version.h" // for GAMENAME
|
#include "version.h" // for GAMENAME
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetAppDataPath macOS
|
||||||
|
//
|
||||||
|
// Returns the path for the AppData folder.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetAppDataPath(bool create)
|
||||||
|
{
|
||||||
|
FString path;
|
||||||
|
|
||||||
|
char pathstr[PATH_MAX];
|
||||||
|
FSRef folder;
|
||||||
|
|
||||||
|
if (noErr == FSFindFolder(kUserDomain, kApplicationSupportFolderType, create ? kCreateFolder : 0, &folder) &&
|
||||||
|
noErr == FSRefMakePath(&folder, (UInt8*)pathstr, PATH_MAX))
|
||||||
|
{
|
||||||
|
path = pathstr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = progdir;
|
||||||
|
}
|
||||||
|
path += "/" GAMENAMELOWERCASE;
|
||||||
|
if (create) CreatePath(path);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// M_GetCachePath macOS
|
// M_GetCachePath macOS
|
||||||
|
@ -64,6 +93,7 @@ FString M_GetCachePath(bool create)
|
||||||
path = progdir;
|
path = progdir;
|
||||||
}
|
}
|
||||||
path += "/zdoom/cache";
|
path += "/zdoom/cache";
|
||||||
|
if (create) CreatePath(path);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,26 @@ FString GetUserFile (const char *file)
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetAppDataPath Unix
|
||||||
|
//
|
||||||
|
// Returns the path for the AppData folder.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetAppDataPath(bool create)
|
||||||
|
{
|
||||||
|
// Don't use GAME_DIR and such so that ZDoom and its child ports can
|
||||||
|
// share the node cache.
|
||||||
|
FString path = NicePath("~/.config/" GAMENAMELOWERCASE);
|
||||||
|
if (create)
|
||||||
|
{
|
||||||
|
CreatePath(path);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// M_GetCachePath Unix
|
// M_GetCachePath Unix
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "tmpfileplus.h"
|
#include "tmpfileplus.h"
|
||||||
|
#include "m_misc.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -82,7 +83,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
bool LaunchTimidity();
|
bool LaunchTimidity();
|
||||||
|
|
||||||
char* DiskName;
|
FString DiskName;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HANDLE ReadWavePipe;
|
HANDLE ReadWavePipe;
|
||||||
HANDLE WriteWavePipe;
|
HANDLE WriteWavePipe;
|
||||||
|
@ -165,8 +166,7 @@ CUSTOM_CVAR (Int, timidity_frequency, 44100, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
|
TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args) :
|
||||||
: DiskName(nullptr),
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
ReadWavePipe(INVALID_HANDLE_VALUE), WriteWavePipe(INVALID_HANDLE_VALUE),
|
ReadWavePipe(INVALID_HANDLE_VALUE), WriteWavePipe(INVALID_HANDLE_VALUE),
|
||||||
ChildProcess(INVALID_HANDLE_VALUE),
|
ChildProcess(INVALID_HANDLE_VALUE),
|
||||||
|
@ -204,10 +204,9 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
|
||||||
|
|
||||||
TimidityPPMIDIDevice::~TimidityPPMIDIDevice ()
|
TimidityPPMIDIDevice::~TimidityPPMIDIDevice ()
|
||||||
{
|
{
|
||||||
if (nullptr != DiskName)
|
if (DiskName.IsNotEmpty())
|
||||||
{
|
{
|
||||||
remove(DiskName);
|
remove(DiskName);
|
||||||
free(DiskName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
@ -257,7 +256,10 @@ bool TimidityPPMIDIDevice::Preprocess(MIDIStreamer *song, bool looping)
|
||||||
// Write MIDI song to temporary file
|
// Write MIDI song to temporary file
|
||||||
song->CreateSMF(midi, looping ? 0 : 1);
|
song->CreateSMF(midi, looping ? 0 : 1);
|
||||||
|
|
||||||
f = tmpfileplus(nullptr, "zmid", &DiskName, 1);
|
FString path = M_GetAppDataPath(false);
|
||||||
|
path += "/tmp";
|
||||||
|
CreatePath(path);
|
||||||
|
f = tmpfileplus(path, "zmid", &DiskName, 1);
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
{
|
{
|
||||||
Printf(PRINT_BOLD, "Could not open temp music file\n");
|
Printf(PRINT_BOLD, "Could not open temp music file\n");
|
||||||
|
@ -454,7 +456,7 @@ bool TimidityPPMIDIDevice::ValidateTimidity()
|
||||||
|
|
||||||
bool TimidityPPMIDIDevice::LaunchTimidity ()
|
bool TimidityPPMIDIDevice::LaunchTimidity ()
|
||||||
{
|
{
|
||||||
if (ExeName.IsEmpty() || nullptr == DiskName)
|
if (ExeName.IsEmpty() || DiskName.IsEmpty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -565,7 +567,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
|
||||||
arglist.push_back("-");
|
arglist.push_back("-");
|
||||||
arglist.push_back(outmodearg.c_str());
|
arglist.push_back(outmodearg.c_str());
|
||||||
arglist.push_back(ifacearg.c_str());
|
arglist.push_back(ifacearg.c_str());
|
||||||
arglist.push_back(DiskName);
|
arglist.push_back(DiskName.GetChars());
|
||||||
|
|
||||||
DPrintf(DMSG_NOTIFY, "Timidity EXE: \x1cG%s\n", exename);
|
DPrintf(DMSG_NOTIFY, "Timidity EXE: \x1cG%s\n", exename);
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
|
@ -97,10 +97,9 @@
|
||||||
|
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
|
#include "zstring.h"
|
||||||
|
|
||||||
|
|
||||||
#define FILE_SEPARATOR "/"
|
|
||||||
|
|
||||||
#define RANDCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
#define RANDCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||||
#define NRANDCHARS (sizeof(RANDCHARS) - 1)
|
#define NRANDCHARS (sizeof(RANDCHARS) - 1)
|
||||||
|
|
||||||
|
@ -121,27 +120,13 @@ static char *set_randpart(char *s)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Call getenv and save a copy in buf */
|
|
||||||
static char *getenv_save(const char *varname, char *buf, size_t bufsize)
|
|
||||||
{
|
|
||||||
char *ptr = getenv(varname);
|
|
||||||
buf[0] = '\0';
|
|
||||||
if (ptr)
|
|
||||||
{
|
|
||||||
strncpy(buf, ptr, bufsize);
|
|
||||||
buf[bufsize-1] = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try and create a randomly-named file in directory `tmpdir`.
|
* Try and create a randomly-named file in directory `tmpdir`.
|
||||||
* If successful, allocate memory and set `tmpname_ptr` to full filepath, and return file pointer;
|
* If successful, allocate memory and set `tmpname_ptr` to full filepath, and return file pointer;
|
||||||
* otherwise return NULL.
|
* otherwise return NULL.
|
||||||
* If `keep` is zero then create the file as temporary and it should not exist once closed.
|
* If `keep` is zero then create the file as temporary and it should not exist once closed.
|
||||||
*/
|
*/
|
||||||
static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmpname_ptr, int keep)
|
static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, FString *tmpname_ptr, int keep)
|
||||||
/* PRE:
|
/* PRE:
|
||||||
* pfx is not NULL and points to a valid null-terminated string
|
* pfx is not NULL and points to a valid null-terminated string
|
||||||
* tmpname_ptr is not NULL.
|
* tmpname_ptr is not NULL.
|
||||||
|
@ -150,9 +135,7 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int fd;
|
int fd;
|
||||||
char randpart[] = "1234567890";
|
char randpart[] = "1234567890";
|
||||||
size_t lentempname;
|
|
||||||
int i;
|
int i;
|
||||||
char *tmpname = NULL;
|
|
||||||
int oflag, pmode;
|
int oflag, pmode;
|
||||||
|
|
||||||
/* In Windows, we use the _O_TEMPORARY flag with `open` to ensure the file is deleted when closed.
|
/* In Windows, we use the _O_TEMPORARY flag with `open` to ensure the file is deleted when closed.
|
||||||
|
@ -176,18 +159,13 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lentempname = strlen(tmpdir) + strlen(FILE_SEPARATOR) + strlen(pfx) + strlen(randpart);
|
FString tempname;
|
||||||
tmpname = (char*)malloc(lentempname + 1);
|
|
||||||
if (!tmpname)
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* If we don't manage to create a file after 10 goes, there is something wrong... */
|
/* If we don't manage to create a file after 10 goes, there is something wrong... */
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
sprintf(tmpname, "%s%s%s%s", tmpdir, FILE_SEPARATOR, pfx, set_randpart(randpart));
|
tempname.Format("%s/%s%s", tmpdir, pfx, set_randpart(randpart));
|
||||||
fd = OPEN_(tmpname, oflag, pmode);
|
fd = OPEN_(tempname, oflag, pmode);
|
||||||
if (fd != -1) break;
|
if (fd != -1) break;
|
||||||
}
|
}
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
|
@ -205,13 +183,8 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
|
||||||
{ /* We failed */
|
{ /* We failed */
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
}
|
}
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
free(tmpname);
|
|
||||||
tmpname = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*tmpname_ptr = tmpname;
|
if (tmpname_ptr) *tmpname_ptr = tempname;
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,47 +192,10 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
|
||||||
/* EXPORTED FUNCTIONS */
|
/* EXPORTED FUNCTIONS */
|
||||||
/**********************/
|
/**********************/
|
||||||
|
|
||||||
FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep)
|
FILE *tmpfileplus(const char *dir, const char *prefix, FString *pathname, int keep)
|
||||||
{
|
{
|
||||||
FILE *fp = NULL;
|
FILE *fp = mktempfile_internal(dir, (prefix ? prefix : "tmp."), pathname, keep);
|
||||||
char *tmpname = NULL;
|
if (!fp && pathname) *pathname = "";
|
||||||
char *tmpdir = NULL;
|
|
||||||
const char *pfx = (prefix ? prefix : "tmp.");
|
|
||||||
char *tempdirs[12] = { 0 };
|
|
||||||
char env1[FILENAME_MAX+1] = { 0 };
|
|
||||||
char env2[FILENAME_MAX+1] = { 0 };
|
|
||||||
char env3[FILENAME_MAX+1] = { 0 };
|
|
||||||
int ntempdirs = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Set up a list of temp directories we will try in order */
|
|
||||||
i = 0;
|
|
||||||
tempdirs[i++] = (char *)dir;
|
|
||||||
#ifdef _WIN32
|
|
||||||
tempdirs[i++] = getenv_save("TMP", env1, sizeof(env1));
|
|
||||||
tempdirs[i++] = getenv_save("TEMP", env2, sizeof(env2));
|
|
||||||
#else
|
|
||||||
tempdirs[i++] = getenv_save("TMPDIR", env3, sizeof(env3));
|
|
||||||
tempdirs[i++] = P_tmpdir;
|
|
||||||
#endif
|
|
||||||
tempdirs[i++] = ".";
|
|
||||||
ntempdirs = i;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
/* Work through list we set up before, and break once we are successful */
|
|
||||||
for (i = 0; i < ntempdirs; i++)
|
|
||||||
{
|
|
||||||
tmpdir = tempdirs[i];
|
|
||||||
fp = mktempfile_internal(tmpdir, pfx, &tmpname, keep);
|
|
||||||
if (fp) break;
|
|
||||||
}
|
|
||||||
/* If we succeeded and the user passed a pointer, set it to the alloc'd pathname: the user must free this */
|
|
||||||
if (fp && pathname)
|
|
||||||
*pathname = tmpname;
|
|
||||||
else /* Otherwise, free the alloc'd memory */
|
|
||||||
free(tmpname);
|
|
||||||
|
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class FString;
|
||||||
|
|
||||||
/** Create a unique temporary file.
|
/** Create a unique temporary file.
|
||||||
@param dir (optional) directory to create file. If NULL use default TMP directory.
|
@param dir (optional) directory to create file. If NULL use default TMP directory.
|
||||||
@param prefix (optional) prefix for file name. If NULL use "tmp.".
|
@param prefix (optional) prefix for file name. If NULL use "tmp.".
|
||||||
|
@ -33,7 +35,7 @@
|
||||||
@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
|
@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
|
||||||
@exception ENOMEM Not enough memory to allocate filename.
|
@exception ENOMEM Not enough memory to allocate filename.
|
||||||
*/
|
*/
|
||||||
FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep);
|
FILE *tmpfileplus(const char *dir, const char *prefix, FString *pathname, int keep);
|
||||||
|
|
||||||
|
|
||||||
#define TMPFILE_KEEP 1
|
#define TMPFILE_KEEP 1
|
||||||
|
|
|
@ -153,6 +153,33 @@ bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// M_GetAppDataPath Windows
|
||||||
|
//
|
||||||
|
// Returns the path for the AppData folder.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString M_GetAppDataPath(bool create)
|
||||||
|
{
|
||||||
|
FString path;
|
||||||
|
|
||||||
|
if (!GetKnownFolder(CSIDL_LOCAL_APPDATA, FOLDERID_LocalAppData, create, path))
|
||||||
|
{ // Failed (e.g. On Win9x): use program directory
|
||||||
|
path = progdir;
|
||||||
|
}
|
||||||
|
// Don't use GAME_DIR and such so that ZDoom and its child ports can
|
||||||
|
// share the node cache.
|
||||||
|
path += "/" GAMENAMELOWERCASE;
|
||||||
|
path.Substitute("//", "/"); // needed because progdir ends with a slash.
|
||||||
|
if (create)
|
||||||
|
{
|
||||||
|
CreatePath(path);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// M_GetCachePath Windows
|
// M_GetCachePath Windows
|
||||||
|
@ -173,6 +200,10 @@ FString M_GetCachePath(bool create)
|
||||||
// share the node cache.
|
// share the node cache.
|
||||||
path += "/zdoom/cache";
|
path += "/zdoom/cache";
|
||||||
path.Substitute("//", "/"); // needed because progdir ends with a slash.
|
path.Substitute("//", "/"); // needed because progdir ends with a slash.
|
||||||
|
if (create)
|
||||||
|
{
|
||||||
|
CreatePath(path);
|
||||||
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue