Test whether change_filename_extension succeeded before using its output
This commit is contained in:
parent
b0ebe3b82c
commit
0ebcc64ac5
|
@ -61,7 +61,8 @@ struct splitpath_t
|
|||
void removeext(const char *filename, std::array<char, 20> &out);
|
||||
|
||||
//give a filename a new extension, doesn't work with paths with no extension already there
|
||||
void change_filename_extension(std::span<char> dest, const char *src, std::span<const char, 4> ext);
|
||||
[[nodiscard]]
|
||||
bool change_filename_extension(std::span<char> dest, const char *src, std::span<const char, 4> ext);
|
||||
|
||||
/* Given an MS-DOS path, return pointers to the start of the basename and the
|
||||
* start of the extension.
|
||||
|
|
|
@ -136,16 +136,17 @@ void removeext(const char *const filename, std::array<char, 20> &out)
|
|||
}
|
||||
|
||||
//give a filename a new extension, won't append if strlen(dest) > 8 chars.
|
||||
void change_filename_extension(const std::span<char> dest, const char *const src, const std::span<const char, 4> ext)
|
||||
bool change_filename_extension(const std::span<char> dest, const char *const src, const std::span<const char, 4> ext)
|
||||
{
|
||||
const char *const p = strrchr(src, '.');
|
||||
const std::size_t src_dist_to_last_dot = p ? std::distance(src, p) : strlen(src);
|
||||
if (src_dist_to_last_dot + 1 + ext.size() > dest.size())
|
||||
{
|
||||
dest.front() = 0;
|
||||
return; // a non-opened file is better than a bad memory access
|
||||
return false; // a non-opened file is better than a bad memory access
|
||||
}
|
||||
std::snprintf(dest.data(), dest.size(), "%.*s.%s", static_cast<int>(src_dist_to_last_dot), src, ext.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
splitpath_t d_splitpath(const char *name)
|
||||
|
|
|
@ -518,7 +518,11 @@ static int init_subtitles(d_loaded_subtitle_state &SubtitleState, const std::spa
|
|||
|
||||
if (!ifile) { //no text version, try binary version
|
||||
std::array<char, FILENAME_LEN> filename2;
|
||||
change_filename_extension(filename2, filename.data(), "txb");
|
||||
if (!change_filename_extension(filename2, filename.data(), "txb"))
|
||||
{
|
||||
con_printf(CON_NORMAL, "Rebirth: skipping subtitles because cannot open \"%s\" (\"%s\")", filename.data(), PHYSFS_getErrorByCode(physfserr));
|
||||
return 0;
|
||||
}
|
||||
auto &&[ifile2, physfserr2] = PHYSFSX_openReadBuffered(filename2.data());
|
||||
if (!ifile2)
|
||||
{
|
||||
|
|
|
@ -538,7 +538,11 @@ void load_robot_replacements(const d_fname &level_name)
|
|||
auto &Robot_joints = LevelSharedRobotJointState.Robot_joints;
|
||||
int t,j;
|
||||
std::array<char, FILENAME_LEN> ifile_name;
|
||||
change_filename_extension(ifile_name, level_name, "HXM");
|
||||
if (!change_filename_extension(ifile_name, level_name, "HXM"))
|
||||
{
|
||||
con_printf(CON_URGENT, "Failed to generate HXM name from level name \"%s\"", level_name.data());
|
||||
return;
|
||||
}
|
||||
|
||||
auto fp = PHYSFSX_openReadBuffered(ifile_name.data()).first;
|
||||
if (!fp) //no robot replacement file
|
||||
|
|
|
@ -1845,12 +1845,18 @@ static int save_level_sub(
|
|||
}
|
||||
// else
|
||||
{
|
||||
auto &level_file_extension =
|
||||
#if defined(DXX_BUILD_DESCENT_II)
|
||||
if (Gamesave_current_version > 3)
|
||||
change_filename_extension(temp_filename, filename, D2X_LEVEL_FILE_EXTENSION);
|
||||
else
|
||||
(Gamesave_current_version > 3)
|
||||
? D2X_LEVEL_FILE_EXTENSION
|
||||
:
|
||||
#endif
|
||||
change_filename_extension(temp_filename, filename, D1X_LEVEL_FILE_EXTENSION);
|
||||
D1X_LEVEL_FILE_EXTENSION;
|
||||
if (!change_filename_extension(temp_filename, filename, level_file_extension))
|
||||
{
|
||||
con_printf(CON_URGENT, "Failed to generate filename for level data from \"%s\"", filename);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
auto &&[SaveFile, physfserr] = PHYSFSX_openWriteBuffered(temp_filename.data());
|
||||
|
|
|
@ -876,7 +876,8 @@ static window_event_result demo_menu_keycommand( listbox *lb,const d_event &even
|
|||
|
||||
// Get backup name
|
||||
const auto ic = items[citem];
|
||||
change_filename_extension(bakname, ic, DEMO_BACKUP_EXT);
|
||||
if (!change_filename_extension(bakname, ic, DEMO_BACKUP_EXT))
|
||||
return window_event_result::handled;
|
||||
const auto x = nm_messagebox(menu_title{nullptr}, 2, TXT_YES, TXT_NO, "Are you sure you want to\n"
|
||||
"swap the endianness of\n"
|
||||
"%s? If the file is\n"
|
||||
|
|
|
@ -4360,11 +4360,9 @@ int newdemo_swap_endian(const char *filename)
|
|||
infile.reset();
|
||||
outfile.reset();
|
||||
|
||||
if (complete)
|
||||
std::array<char, PATH_MAX> bakpath;
|
||||
if (complete && change_filename_extension(bakpath, inpath, DEMO_BACKUP_EXT))
|
||||
{
|
||||
std::array<char, PATH_MAX> bakpath;
|
||||
|
||||
change_filename_extension(bakpath, inpath, DEMO_BACKUP_EXT);
|
||||
PHYSFSX_rename(inpath, bakpath.data());
|
||||
PHYSFSX_rename(DEMO_FILENAME, inpath);
|
||||
}
|
||||
|
|
|
@ -1542,9 +1542,11 @@ static void piggy_write_pigfile(const std::span<const char, FILENAME_LEN> filena
|
|||
data_offset = bitmap_data_start;
|
||||
|
||||
std::array<char, FILENAME_LEN> tname;
|
||||
change_filename_extension(tname, filename.data(), "lst");
|
||||
if (!change_filename_extension(tname, filename.data(), "lst"))
|
||||
return;
|
||||
auto fp1 = PHYSFSX_openWriteBuffered(tname.data()).first;
|
||||
change_filename_extension(tname, filename.data(), "all");
|
||||
if (!change_filename_extension(tname, filename.data(), "all"))
|
||||
return;
|
||||
auto fp2 = PHYSFSX_openWriteBuffered(tname.data()).first;
|
||||
|
||||
for (i=1; i < Num_bitmap_files; i++ ) {
|
||||
|
@ -1785,7 +1787,8 @@ void load_bitmap_replacements(const std::span<const char, FILENAME_LEN> level_na
|
|||
free_bitmap_replacements();
|
||||
|
||||
std::array<char, FILENAME_LEN> ifile_name;
|
||||
change_filename_extension(ifile_name, level_name.data(), "POG");
|
||||
if (!change_filename_extension(ifile_name, level_name.data(), "POG"))
|
||||
return;
|
||||
if (auto ifile = PHYSFSX_openReadBuffered(ifile_name.data()).first)
|
||||
{
|
||||
int id,version;
|
||||
|
|
Loading…
Reference in New Issue