[Scummvm-git-logs] scummvm master -> d221301032bb739486f515715350046f5be6f4cb
tag2015
noreply at scummvm.org
Sun Nov 10 23:07:52 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d221301032 AGS: Engine: use safe strcpy function instead of snprintf where truncation expected
Commit: d221301032bb739486f515715350046f5be6f4cb
https://github.com/scummvm/scummvm/commit/d221301032bb739486f515715350046f5be6f4cb
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-11-10T23:56:05+01:00
Commit Message:
AGS: Engine: use safe strcpy function instead of snprintf where truncation expected
Partially from upstream 2f4345ef7ce248f047326d407aee915d5892e736
Changed paths:
engines/ags/shared/game/main_game_file.cpp
engines/ags/shared/util/string_compat.cpp
engines/ags/shared/util/string_compat.h
diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp
index 69d086f7918..ec57cc2d850 100644
--- a/engines/ags/shared/game/main_game_file.cpp
+++ b/engines/ags/shared/game/main_game_file.cpp
@@ -564,14 +564,17 @@ void UpgradeCharacters(GameSetupStruct &game, GameDataVersion data_ver) {
const int numcharacters = _GP(game).numcharacters;
// Fixup character script names for 2.x (EGO -> cEgo)
+ // In 2.x versions the "scriptname" field in game data contained a name
+ // limited by 14 chars (although serialized in 20 bytes). After reading,
+ // it was exported as "cScriptname..." for the script.
if (data_ver <= kGameVersion_272) {
- char namelwr[LEGACY_MAX_SCRIPT_NAME_LEN];
+ char namelwr[LEGACY_MAX_SCRIPT_NAME_LEN - 1];
for (int i = 0; i < numcharacters; i++) {
if (chars[i].scrname[0] == 0)
continue;
- memcpy(namelwr, chars[i].scrname, LEGACY_MAX_SCRIPT_NAME_LEN);
+ ags_strncpy_s(namelwr, sizeof(namelwr), chars[i].scrname, LEGACY_MAX_SCRIPT_NAME_LEN - 2);
ags_strlwr(namelwr + 1); // lowercase starting with the second char
- snprintf(chars[i].scrname, LEGACY_MAX_SCRIPT_NAME_LEN, "c%s", namelwr);
+ snprintf(chars[i].scrname, sizeof(chars[i].scrname), "c%s", namelwr);
chars2[i].scrname_new = chars[i].scrname;
}
}
diff --git a/engines/ags/shared/util/string_compat.cpp b/engines/ags/shared/util/string_compat.cpp
index 4ad775b7982..d1a002e3e84 100644
--- a/engines/ags/shared/util/string_compat.cpp
+++ b/engines/ags/shared/util/string_compat.cpp
@@ -21,6 +21,7 @@
#include "ags/shared/util/string_compat.h"
#include "ags/shared/core/platform.h"
+#include "ags/lib/allegro/error.h"
#include "common/str.h"
namespace AGS3 {
@@ -54,4 +55,28 @@ char *ags_strdup(const char *s) {
return result;
}
+int ags_strncpy_s(char *dest, size_t dest_sz, const char *src, size_t count) {
+ // NOTE: implementation approximately mimics explanation for "strncpy_s":
+ // https://en.cppreference.com/w/c/string/byte/strncpy
+ assert(dest && dest_sz > 0 && ((dest + dest_sz - 1 < src) || (dest > src + count)));
+ if (!dest || dest_sz == 0 || ((dest <= src) && (dest + dest_sz - 1 >= src)) || ((src <= dest) && (src + count - 1 >= dest)))
+ return AL_EINVAL; // null buffer, or dest and src overlap
+ if (!src) {
+ dest[0] = 0; // ensure null terminator
+ return AL_EINVAL;
+ }
+
+ const size_t copy_len = (count < dest_sz - 1) ? count : dest_sz - 1; // reserve null-terminator
+ const char *psrc = src;
+ const char *src_end = src + copy_len;
+ char *pdst = dest;
+ for (; *psrc && (psrc != src_end); ++psrc, ++pdst)
+ *pdst = *psrc;
+ *pdst = 0; // ensure null terminator
+ assert((*psrc == 0) || ((psrc - src) == (int)count)); // assert that no *unintended* truncation occured
+ if ((*psrc != 0) && ((psrc - src) < (int)count))
+ return AL_ERANGE; // not enough dest buffer - error
+ return 0; // success
+}
+
} // namespace AGS3
diff --git a/engines/ags/shared/util/string_compat.h b/engines/ags/shared/util/string_compat.h
index cebf2478878..6a9bc75d769 100644
--- a/engines/ags/shared/util/string_compat.h
+++ b/engines/ags/shared/util/string_compat.h
@@ -31,6 +31,7 @@ char *ags_strupr(char *s);
int ags_stricmp(const char *, const char *);
int ags_strnicmp(const char *, const char *, size_t);
char *ags_strdup(const char *s);
+int ags_strncpy_s(char *dest, size_t dest_sz, const char *src, size_t count);
} // namespace AGS3
More information about the Scummvm-git-logs
mailing list