[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