diff --git a/common/include/ntstring.h b/common/include/ntstring.h index 176c59374..336971ae1 100644 --- a/common/include/ntstring.h +++ b/common/include/ntstring.h @@ -44,9 +44,13 @@ public: template void copy_if(std::size_t, const ntstring &, std::size_t = 0) = delete; template - bool copy_if(const array &i) + bool copy_if(const array &i, std::size_t n = N) { - return copy_if(i.data(), N); +#ifdef DXX_HAVE_BUILTIN_CONSTANT_P + if (__builtin_constant_p(n > N) && n > N) + DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_overread, "read size exceeds array size"); +#endif + return copy_if(i.data(), n); } template bool copy_if(const char (&i)[N]) diff --git a/similar/main/mission.cpp b/similar/main/mission.cpp index c697716e6..9a83baf7f 100644 --- a/similar/main/mission.cpp +++ b/similar/main/mission.cpp @@ -82,6 +82,11 @@ typedef std::vector mission_list; Mission_ptr Current_mission; // currently loaded mission +static bool null_or_space(char c) +{ + return !c || isspace(static_cast(c)); +} + // Allocate the Level_names, Secret_level_names and Secret_level_table arrays static int allocate_levels(void) { @@ -296,7 +301,7 @@ static int istok(const char *buf,const char *tok) //adds a terminating 0 after a string at the first white space static void add_term(char *s) { - while (*s && !isspace(*s)) s++; + while (!null_or_space(*s)) s++; *s = 0; //terminate! } @@ -840,9 +845,11 @@ static int load_mission(const mle *mission) Level_names = make_unique(n_levels); range_for (auto &i, unchecked_partial_range(Level_names.get(), n_levels)) { - PHYSFSX_fgets(buf,mfile); - add_term(buf); - if (i.copy_if(buf.line())) + if (!PHYSFSX_fgets(buf, mfile)) + break; + auto &line = buf.line(); + auto s = std::find_if(line.begin(), line.end(), null_or_space); + if (i.copy_if(buf.line(), std::distance(line.begin(), s))) { Last_level++; }