Test whether change_filename_extension succeeded before using its output

This commit is contained in:
Kp 2022-10-09 23:15:20 +00:00
parent b0ebe3b82c
commit 0ebcc64ac5
8 changed files with 35 additions and 17 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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)
{

View File

@ -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

View 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());

View File

@ -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"

View File

@ -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);
}

View File

@ -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;