[Scummvm-git-logs] scummvm master -> 6524f7beb5d9b05685a8759e2839bab2ef223b57

sev- noreply at scummvm.org
Sun Oct 23 20:47:16 UTC 2022


This automated email contains information about 106 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
f8c25e2374 COMMON: Add strcpy_s and strcat_s
3aa220fdb4 GRAPHICS: Don't use unsafe strcat and strcpy
7948a2820f ENGINES: Don't use unsafe strcat and strcpy
d8a4c106dd GUI: Don't use unsafe strcat and strcpy
c89f760066 AGI: Don't use unsafe strcat and strcpy
1d23fc0240 AGOS: Don't use unsafe strcat and strcpy
7f90669bdd AGS: Don't use unsafe strcat and strcpy
a302f1859b ASYLUM: Don't use unsafe strcat and strcpy
d698fc6bbe CGE: Don't use unsafe strcat and strcpy
ceca603464 CGE2: Don't use unsafe strcat and strcpy
e871394664 CHEWY: Don't use unsafe strcat and strcpy
c618b7fe91 CINE: Don't use unsafe strcat and strcpy
f2ddbbea91 CRUISE: Don't use unsafe strcat and strcpy
f25c8239b1 CRYO: Don't use unsafe strcat and strcpy
b6a1284baf CRYOMNI3D: Don't use unsafe strcat and strcpy
667ea2f88e DM: Don't use unsafe strcat and strcpy
b25335bd33 DRASCULA: Don't use unsafe strcat and strcpy
93cdbbbf39 GLK: Don't use unsafe strcat and strcpy
f26ce1e4ff GOB: Don't use unsafe strcat and strcpy
0a0d21b904 GRIFFON: Don't use unsafe strcat and strcpy
e15aa92118 GRIM: Don't use unsafe strcat and strcpy
6a391ff462 HOPKINS: Don't use unsafe strcat and strcpy
5fbf81f498 HUGO: Don't use unsafe strcat and strcpy
f24d143565 ICB: Don't use unsafe strcat and strcpy
abb4c3cd6c LASTEXPRESS: Don't use unsafe strcat and strcpy
700a965361 LURE: Don't use unsafe strcat and strcpy
295253abf3 MADS: Don't use unsafe strcat and strcpy
e249dac38e NGI: Don't use unsafe strcat and strcpy
a21b7eb75a PARALLACTION: Don't use unsafe strcat and strcpy
e61f13b0aa QUEEN: Don't use unsafe strcat and strcpy
f564ffc12f SCUMM: Don't use unsafe strcat and strcpy
44870b1ad6 SAGA: Don't use unsafe strcat and strcpy
80ee3dddd7 SAGA2: Don't use unsafe strcat and strcpy
0b918a5352 SCI: Rename strcpy function to prepare for forbidden name
682c11e801 SCI: Don't use unsafe strcat and strcpy
5b67238944 SKY: Don't use unsafe strcat and strcpy
1a5ef8794a STARTREK: Don't use unsafe strcat and strcpy
51da2bbd7c SWORD2: Don't use unsafe strcat and strcpy
b7ef4078dc SWORD25: Don't use unsafe strcat and strcpy
422d8d98ae TEENAGENT: Don't use unsafe strcat and strcpy
52caebf8af TINSEL: Don't use unsafe strcat and strcpy
4bbe3d9286 ULTIMA: Don't use unsafe strcat and strcpy
73c09b1d56 WINTERMUTE: Don't use unsafe strcat and strcpy
1808493909 XEEN: Don't use unsafe strcat and strcpy
523ed4a34d ZVISION: Don't use unsafe strcat and strcpy
5a0e4ced67 AMIGAOS: Don't use unsafe strcat and strcpy
6f5ac54828 DC: Don't use unsafe strcat and strcpy
15e7346f1c MORPHOS: Don't use unsafe strcat and strcpy
7c657796f4 POSIX: Don't use unsafe strcat and strcpy
a3cc6b5218 TIMIDITY: Don't use unsafe strcat and strcpy
387da5b820 WII: Don't use unsafe strcat and strcpy
6293c2b3c2 WIN32: Don't use unsafe strcat and strcpy
9c04d72471 COMMON: Forbid use of unsafe strcat and strcpy
cd785e2208 COMMON: Add sprintf_s and vsprintf_s
94b8f34302 GRAPHICS: Don't use unsafe sprintf and vsprintf
a91558aefd AGI: Don't use unsafe sprintf and vsprintf
429afa3a34 AGOS: Don't use unsafe sprintf and vsprintf
ab0854d81a AGS: Don't use unsafe sprintf and vsprintf
14e3d1f343 CGE: Don't use unsafe sprintf and vsprintf
1ae18bc650 CHEWY: Don't use unsafe sprintf and vsprintf
b75ecadf56 CINE: Don't use unsafe sprintf and vsprintf
fe5eb4dbcd CRUISE: Don't use unsafe sprintf and vsprintf
29dea747a8 DIRECTOR: Don't use unsafe sprintf and vsprintf
fcda5809b8 DRAGONS: Don't use unsafe sprintf and vsprintf
8373886eb9 DRASCULA: Don't use unsafe sprintf and vsprintf
4282dec6f6 DREAMWEB: Don't use unsafe sprintf and vsprintf
6d3a10c631 GLK: Don't use unsafe sprintf and vsprintf
28318d0839 GNAP: Don't use unsafe sprintf and vsprintf
4a82710bc0 GOB: Don't use unsafe sprintf and vsprintf
0674bd29a7 GRIFFON: Don't use unsafe sprintf and vsprintf
a4073b8c6f GRIM: Don't use unsafe sprintf and vsprintf
c93b9981f8 GROOVIE: Don't use unsafe sprintf and vsprintf
8055e2d14c HDB: Don't use unsafe sprintf and vsprintf
714ebdd302 HOPKINS: Don't use unsafe sprintf and vsprintf
926b7533c5 HUGO: Don't use unsafe sprintf and vsprintf
11b3f71973 ICB: Don't use unsafe sprintf and vsprintf
dbe47a28ba KYRA: Don't use unsafe sprintf and vsprintf
27ba4d72c8 LASTEXPRESS: Don't use unsafe sprintf and vsprintf
f4853e863d LURE: Don't use unsafe sprintf and vsprintf
19fe3f8b90 NGI: Don't use unsafe sprintf and vsprintf
9a5f51864a PARALLACTION: Don't use unsafe sprintf and vsprintf
1f45b787b9 QUEEN: Don't use unsafe sprintf and vsprintf
d5b55b667f SAGA: Don't use unsafe sprintf and vsprintf
707c71ecf9 SAGA2: Don't use unsafe sprintf and vsprintf
f54bdf989a SCI: Don't use unsafe sprintf and vsprintf
137b51d7ac SCUMM: Don't use unsafe sprintf and vsprintf
a858fd57f0 SHERLOCK: Don't use unsafe sprintf and vsprintf
3fa310340e SKY: Don't use unsafe sprintf and vsprintf
95d5bafb57 SLUDGE: Don't use unsafe sprintf and vsprintf
5987c9f8ff SUPERNOVA: Don't use unsafe sprintf and vsprintf
b2ecd531a6 SWORD1: Don't use unsafe sprintf and vsprintf
027be5b7c0 SWORD2: Don't use unsafe sprintf and vsprintf
5ad311fbaa TINSEL: Don't use unsafe sprintf and vsprintf
87f40c8edc TOLTECS: Don't use unsafe sprintf and vsprintf
ae898f3316 TOON: Don't use unsafe sprintf and vsprintf
86bb6a215f TUCKER: Don't use unsafe sprintf and vsprintf
ebe46dcf6e TWINE: Don't use unsafe sprintf and vsprintf
34cf68b318 ULTIMA: Don't use unsafe sprintf and vsprintf
4c18545085 WAGE: Don't use unsafe sprintf and vsprintf
62f105c0ce WINTERMUTE: Don't use unsafe sprintf and vsprintf
26dd9a05fa ZVISION: Don't use unsafe sprintf and vsprintf
29f5d51972 DC: Don't use unsafe sprintf and vsprintf
a60e8ff2cb MORPHOS: Don't use unsafe sprintf and vsprintf
f61400075f PSP: Don't use unsafe sprintf and vsprintf
43997e2911 WIN32: Don't use unsafe sprintf and vsprintf
6524f7beb5 COMMON: Forbid use of unsafe sprintf and vsprintf


Commit: f8c25e2374fd0d9a22de83168b330fb355c1a50e
    https://github.com/scummvm/scummvm/commit/f8c25e2374fd0d9a22de83168b330fb355c1a50e
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
COMMON: Add strcpy_s and strcat_s

These functions will issue warnings and truncate strings.
It's like strlcpy and strlcat but noisier.
There are also versions automatically determining size based on the destination
array size.
This raises a compilation error when the size cannot be determined by
the compiler.

Changed paths:
    common/str.cpp
    common/str.h


diff --git a/common/str.cpp b/common/str.cpp
index af33638581d..08d0c4b9d13 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -736,6 +736,88 @@ String tag2string(uint32 tag, bool nonPrintable) {
 
 #endif
 
+// When str.cpp is used in devtools warning is not defined
+#ifdef SCUMMVM_UTIL
+#define warning(msg, ...)
+#endif
+
+// Our simple implementation of strcpy_s and strcat_s
+// We don't check for overlapping strings and we issue warnings instead of erroring out
+void strcpy_s(char *dst, size_t size, const char *src) {
+	if (!dst) {
+		warning("%s: dst is nullptr", __func__);
+		return;
+	}
+	if (!src) {
+		warning("%s: src is nullptr", __func__);
+		return;
+	}
+	if (!size) {
+		warning("%s: size is zero", __func__);
+		return;
+	}
+
+	if (dst == src) {
+		// Nothing to do
+		return;
+	}
+
+	// Copy over (size - 1) bytes at max.
+	while (size != 0) {
+		*dst = *src;
+		if (*dst == '\0') {
+			return;
+		}
+		++dst;
+		++src;
+		--size;
+	}
+
+	warning("%s: truncating string", __func__);
+	dst[-1] = '\0';
+}
+
+void strcat_s(char *dst, size_t size, const char *src) {
+	if (!dst) {
+		warning("%s: dst is nullptr", __func__);
+		return;
+	}
+	if (!src) {
+		warning("%s: src is nullptr", __func__);
+		return;
+	}
+	if (!size) {
+		warning("%s: size is zero", __func__);
+		return;
+	}
+
+	// Search the end of the destination, but do not
+	// move past the terminating zero.
+	while(*dst != '\0') {
+		++dst;
+		--size;
+		if (!size) {
+			warning("%s: dst is unterminated", __func__);
+			return;
+		}
+	}
+
+	// Copy over all of the source that fits
+	// the destination buffer.
+	while (size != 0) {
+		*dst = *src;
+		if (*dst == '\0') {
+			return;
+		}
+		++dst;
+		++src;
+		--size;
+	}
+
+	warning("%s: truncating string", __func__);
+	dst[-1] = '\0';
+}
+
 size_t strlcpy(char *dst, const char *src, size_t size) {
 	// Our backup of the source's start, we need this
 	// to calculate the source's length.
diff --git a/common/str.h b/common/str.h
index 878883f019d..78ff663d443 100644
--- a/common/str.h
+++ b/common/str.h
@@ -371,6 +371,66 @@ void replace(Common::String &source, const Common::String &what, const Common::S
  */
 String tag2string(uint32 tag, bool nonPrintable = false);
 
+/**
+ * Copy up to size - 1 characters from src to dst and also zero terminate the
+ * result. Note that src must be a zero terminated string.
+ *
+ * @note This is modeled after strcpy_s from C11 but simplified by using warning
+ * instead of erroring out
+ *
+ * @param dst The destination buffer.
+ * @param size The size of the destination buffer.
+ * @param src The source string.
+ */
+void strcpy_s(char *dst, size_t size, const char *src);
+
+/**
+ * Copy up to N - 1 characters from src to dst and also zero terminate the
+ * result. Note that src must be a zero terminated string.
+ *
+ * @note This is modeled after strcpy_s from C11 but simplified by using warning
+ * instead of erroring out
+ *
+ * @param dst The destination buffer as a reference to a constant size array.
+ * @param src The source string.
+ */
+template<typename T, size_t N>
+FORCEINLINE void strcpy_s(T (&dst)[N], const char *src) {
+	STATIC_ASSERT(sizeof(T) == sizeof(char), T_is_not_compatible_with_char);
+	strcpy_s((char *)dst, N, src);
+}
+
+/**
+ * Append the string src to the string dst. Note that both src and dst must be
+ * zero terminated. The result will be zero terminated. At most
+ * "size - strlen(dst) - 1" bytes will be appended.
+ *
+ * @note This is modeled after strcpy_s from C11 but simplified by using warning
+ * instead of erroring out
+ *
+ * @param dst The string the source string should be appended to.
+ * @param size The (total) size of the destination buffer.
+ * @param src The source string.
+ */
+void strcat_s(char *dst, size_t size, const char *src);
+
+/**
+ * Append the string src to the string dst. Note that both src and dst must be
+ * zero terminated. The result will be zero terminated. At most
+ * "N - strlen(dst) - 1" bytes will be appended.
+ *
+ * @note This is modeled after strcat_s from C11 but simplified by using warning
+ * instead of erroring out
+ *
+ * @param dst The string the source string should be appended to as a reference to a constant size array.
+ * @param src The source string.
+ */
+template<typename T, size_t N>
+FORCEINLINE void strcat_s(T (&dst)[N], const char *src) {
+	STATIC_ASSERT(sizeof(T) == sizeof(char), T_is_not_compatible_with_char);
+	strcat_s((char *)dst, N, src);
+}
+
 /**
  * Copy up to size - 1 characters from src to dst and also zero terminate the
  * result. Note that src must be a zero terminated string.


Commit: 3aa220fdb412915efe2b794b6657b0ab1757e0d7
    https://github.com/scummvm/scummvm/commit/3aa220fdb412915efe2b794b6657b0ab1757e0d7
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GRAPHICS: Don't use unsafe strcat and strcpy

Changed paths:
    graphics/fonts/bdf.cpp


diff --git a/graphics/fonts/bdf.cpp b/graphics/fonts/bdf.cpp
index b337b8f8965..764c11b0c3a 100644
--- a/graphics/fonts/bdf.cpp
+++ b/graphics/fonts/bdf.cpp
@@ -757,11 +757,13 @@ BdfFont *BdfFont::scaleFont(BdfFont *src, int newSize) {
 	data.firstCharacter = src->_data.firstCharacter;
 	data.defaultCharacter = src->_data.defaultCharacter;
 	data.numCharacters = src->_data.numCharacters;
-	char *familyName = new char[1 + strlen(src->_data.familyName)];
-	strcpy(familyName, src->_data.familyName);
+	uint sz = 1 + strlen(src->_data.familyName);
+	char *familyName = new char[sz];
+	Common::strcpy_s(familyName, sz, src->_data.familyName);
 	data.familyName = familyName;
-	char *slant = new char[1 + strlen(src->_data.slant)];
-	strcpy(slant, src->_data.slant);
+	sz = 1 + strlen(src->_data.slant);
+	char *slant = new char[sz];
+	Common::strcpy_s(slant, sz, src->_data.slant);
 	data.slant = slant;
 
 	BdfBoundingBox *boxes = new BdfBoundingBox[data.numCharacters];


Commit: 7948a2820fb30410e90fa85ae4e914f98d5dc055
    https://github.com/scummvm/scummvm/commit/7948a2820fb30410e90fa85ae4e914f98d5dc055
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
ENGINES: Don't use unsafe strcat and strcpy

Changed paths:
    engines/metaengine.cpp


diff --git a/engines/metaengine.cpp b/engines/metaengine.cpp
index b158788a914..1373c75b83b 100644
--- a/engines/metaengine.cpp
+++ b/engines/metaengine.cpp
@@ -193,7 +193,7 @@ void MetaEngine::appendExtendedSaveToStream(Common::WriteStream *saveFile, uint3
 
 	uint headerPos = saveFile->pos() + posoffset;
 
-	strcpy(header.id, "SVMCR");
+	Common::strcpy_s(header.id, "SVMCR");
 	header.version = EXTENDED_SAVE_VERSION;
 
 	TimeDate curTime;


Commit: d8a4c106dd29a2d205fa7ee1af7f72a5ad3663b3
    https://github.com/scummvm/scummvm/commit/d8a4c106dd29a2d205fa7ee1af7f72a5ad3663b3
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GUI: Don't use unsafe strcat and strcpy

Changed paths:
    gui/debugger.cpp


diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index b395a6edd52..332c9c1708d 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -527,7 +527,7 @@ char *Debugger::readlineComplete(const char *input, int state) {
 	for (; iter != _cmds.end(); ++iter) {
 		if (iter->_key.hasPrefix(input)) {
 			char *ret = (char *)malloc(iter->_key.size() + 1);
-			strcpy(ret, iter->_key.c_str());
+			Common::strcpy_s(ret, iter->_key.size() + 1, iter->_key.c_str());
 			return ret;
 		}
 	}


Commit: c89f760066f75b3574573aa79caf227e91293cce
    https://github.com/scummvm/scummvm/commit/c89f760066f75b3574573aa79caf227e91293cce
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
AGI: Don't use unsafe strcat and strcpy

Changed paths:
    engines/agi/metaengine.cpp
    engines/agi/preagi/mickey.cpp
    engines/agi/saveload.cpp


diff --git a/engines/agi/metaengine.cpp b/engines/agi/metaengine.cpp
index a30671fbb65..fe5ceb39022 100644
--- a/engines/agi/metaengine.cpp
+++ b/engines/agi/metaengine.cpp
@@ -205,10 +205,10 @@ SaveStateList AgiMetaEngine::listSaves(const char *target) const {
 							break;
 					}
 					if (descriptionPos >= sizeof(description)) {
-						strcpy(description, "[broken saved game]");
+						Common::strcpy_s(description, "[broken saved game]");
 					}
 				} else {
-					strcpy(description, "[not an AGI saved game]");
+					Common::strcpy_s(description, "[not an AGI saved game]");
 				}
 
 				delete in;
diff --git a/engines/agi/preagi/mickey.cpp b/engines/agi/preagi/mickey.cpp
index 3126be1ab5b..f00ed7677c4 100644
--- a/engines/agi/preagi/mickey.cpp
+++ b/engines/agi/preagi/mickey.cpp
@@ -614,7 +614,7 @@ void MickeyEngine::patchMenu(MSA_MENU *menu) {
 
 	// change planet name in ship airlock menu
 	if (_gameStateMickey.iRoom == IDI_MSA_PIC_SHIP_AIRLOCK) {
-		strcpy((char *)menu->row[1].entry[2].szText, IDS_MSA_NAME_PLANET[_gameStateMickey.iPlanet]);
+		Common::strcpy_s(menu->row[1].entry[2].szText, IDS_MSA_NAME_PLANET[_gameStateMickey.iPlanet]);
 	}
 
 	// exit if fix unnecessary
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index 0f215ed9311..70ee112ec25 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -436,7 +436,7 @@ int AgiEngine::loadGame(const Common::String &fileName, bool checkId) {
 		// this fact in the debug output. The string saved in "md5" will never match
 		// any valid MD5 sum, thus it is safe to do that here.
 		if (md5[0] == 0)
-			strcpy(md5, "fallback matched");
+			Common::strcpy_s(md5, "fallback matched");
 
 		debug(0, "Saved game MD5: \"%s\"", md5);
 


Commit: 1d23fc0240927423632fff1d4d2168a8c7749f00
    https://github.com/scummvm/scummvm/commit/1d23fc0240927423632fff1d4d2168a8c7749f00
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
AGOS: Don't use unsafe strcat and strcpy

Changed paths:
    engines/agos/string.cpp
    engines/agos/string_pn.cpp


diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp
index 3025b007277..ec1f6925d0f 100644
--- a/engines/agos/string.cpp
+++ b/engines/agos/string.cpp
@@ -764,7 +764,7 @@ void AGOSEngine_Feeble::printScreenText(uint vgaSpriteId, uint color, const char
 					*convertedString2++ = ' ';
 					spaces--;
 			}
-			strcpy(convertedString2, string);
+			Common::strcpy_s(convertedString2, sizeof(convertedString) - (convertedString2 - convertedString), string);
 			break;
 		}
 		while (*string2 != ' ') {
diff --git a/engines/agos/string_pn.cpp b/engines/agos/string_pn.cpp
index 5da9ba22b4c..f8a16950d28 100644
--- a/engines/agos/string_pn.cpp
+++ b/engines/agos/string_pn.cpp
@@ -67,6 +67,8 @@ void AGOSEngine_PN::uncomstr(char *c, uint32 x) {
 	*c = 0;
 }
 
+#define OBJECT_NAME_SIZE 15
+
 static const char *const objectNames[30] = {
 	"\0",
 	"Take \0",
@@ -108,7 +110,7 @@ void AGOSEngine_PN::getObjectName(char *v, uint16 x) {
 		uncomstr(v, ftext(getlong(27), x * _dataBase[47]));
 	} else {
 		assert(x < 30);
-		strcpy(v, objectNames[x]);
+		Common::strcpy_s(v, OBJECT_NAME_SIZE, objectNames[x]);
 	}
 }
 
@@ -117,7 +119,7 @@ void AGOSEngine_PN::pcl(const char *s) {
 	if (strchr(s, '\n') == nullptr) {
 		for (char *str = _sb; *str; str++)
 			windowPutChar(_windowArray[_curWindow], *str);
-		strcpy(_sb, "");
+		_sb[0] = '\0'; // Reset to empty string
 	}
 }
 


Commit: 7f90669bddfcbbd7445af8e329fd53add0e96263
    https://github.com/scummvm/scummvm/commit/7f90669bddfcbbd7445af8e329fd53add0e96263
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
AGS: Don't use unsafe strcat and strcpy

Changed paths:
    engines/ags/engine/ac/parser.cpp
    engines/ags/engine/ac/string.cpp
    engines/ags/engine/gui/gui_dialog.cpp
    engines/ags/engine/gui/my_listbox.cpp
    engines/ags/engine/gui/my_textbox.cpp
    engines/ags/engine/main/game_run.cpp
    engines/ags/engine/main/quit.cpp
    engines/ags/plugins/ags_plugin.cpp
    engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp


diff --git a/engines/ags/engine/ac/parser.cpp b/engines/ags/engine/ac/parser.cpp
index 53a4f212bb8..edcc79ef0e4 100644
--- a/engines/ags/engine/ac/parser.cpp
+++ b/engines/ags/engine/ac/parser.cpp
@@ -103,19 +103,19 @@ int FindMatchingMultiWordWord(char *thisword, const char **text) {
 	const char *tempptr = *text;
 	char tempword[150] = "";
 	if (thisword != nullptr)
-		strcpy(tempword, thisword);
+		Common::strcpy_s(tempword, thisword);
 
 	int bestMatchFound = -1, word;
 	const char *tempptrAtBestMatch = tempptr;
 
 	do {
 		// extract and concat the next word
-		strcat(tempword, " ");
+		Common::strcat_s(tempword, " ");
 		while (tempptr[0] == ' ') tempptr++;
 		char chbuffer[2];
 		while (is_valid_word_char(tempptr[0])) {
 			snprintf(chbuffer, sizeof(chbuffer), "%c", tempptr[0]);
-			strcat(tempword, chbuffer);
+			Common::strcat_s(tempword, chbuffer);
 			tempptr++;
 		}
 		// is this it?
@@ -134,7 +134,7 @@ int FindMatchingMultiWordWord(char *thisword, const char **text) {
 		// yes, a word like "pick up" was found
 		*text = tempptrAtBestMatch;
 		if (thisword != nullptr)
-			strcpy(thisword, tempword);
+			Common::strcpy_s(thisword, 150, tempword);
 	}
 
 	return word;
@@ -247,7 +247,7 @@ int parse_sentence(const char *src_text, int *numwords, short *wordarray, short
 						continueSearching = 0;
 
 						if (text[0] == ' ') {
-							strcpy(thisword, textStart);
+							Common::strcpy_s(thisword, textStart);
 							thisword[text - textStart] = 0;
 							// forward past any multi-word alternatives
 							if (FindMatchingMultiWordWord(thisword, &text) >= 0)
@@ -275,7 +275,7 @@ int parse_sentence(const char *src_text, int *numwords, short *wordarray, short
 				// if it's an unknown word, store it for use in messages like
 				// "you can't use the word 'xxx' in this game"
 				if ((word < 0) && (_GP(play).bad_parsed_word[0] == 0))
-					strcpy(_GP(play).bad_parsed_word, thisword);
+					Common::strcpy_s(_GP(play).bad_parsed_word, 100, thisword);
 			}
 
 			if (do_word_now) {
diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp
index 8cf0ca3f398..baf6b904b75 100644
--- a/engines/ags/engine/ac/string.cpp
+++ b/engines/ags/engine/ac/string.cpp
@@ -53,9 +53,10 @@ const char *String_Copy(const char *srcString) {
 }
 
 const char *String_Append(const char *thisString, const char *extrabit) {
-	char *buffer = (char *)malloc(strlen(thisString) + strlen(extrabit) + 1);
-	strcpy(buffer, thisString);
-	strcat(buffer, extrabit);
+	size_t ln = strlen(thisString) + strlen(extrabit) + 1;
+	char *buffer = (char *)malloc(ln);
+	Common::strcpy_s(buffer, ln, thisString);
+	Common::strcat_s(buffer, ln, extrabit);
 	return CreateNewScriptString(buffer, false);
 }
 
@@ -317,7 +318,7 @@ void check_strlen(char *ptt) {
 /*void GetLanguageString(int indxx,char*buffr) {
 VALIDATE_STRING(buffr);
 char*bptr=get_language_text(indxx);
-if (bptr==NULL) strcpy(buffr,"[language string error]");
+if (bptr==NULL) Common::strcpy_s(buffr, 200, "[language string error]");
 else strncpy(buffr,bptr,199);
 buffr[199]=0;
 }*/
@@ -325,11 +326,7 @@ buffr[199]=0;
 void my_strncpy(char *dest, const char *src, int len) {
 	// the normal strncpy pads out the string with zeros up to the
 	// max length -- we don't want that
-	if (strlen(src) >= (unsigned)len) {
-		strncpy(dest, src, len);
-		dest[len] = 0;
-	} else
-		strcpy(dest, src);
+	Common::strcpy_s(dest, len + 1, src);
 }
 
 //=============================================================================
diff --git a/engines/ags/engine/gui/gui_dialog.cpp b/engines/ags/engine/gui/gui_dialog.cpp
index 5339ef9a479..926e6324db1 100644
--- a/engines/ags/engine/gui/gui_dialog.cpp
+++ b/engines/ags/engine/gui/gui_dialog.cpp
@@ -114,7 +114,7 @@ int loadgamedialog() {
 				else {
 					toret = _G(filenumbers)[cursel];
 					String path = get_save_game_path(toret);
-					strcpy(_G(bufTemp), path.GetCStr());
+					Common::strcpy_s(_G(bufTemp), path.GetCStr());
 					_G(lpTemp) = &_G(bufTemp)[0];
 				}
 			} else if (mes.id == ctrlcancel) {
@@ -135,9 +135,9 @@ int loadgamedialog() {
 
 int savegamedialog() {
 	char okbuttontext[50];
-	strcpy(okbuttontext, get_global_message(MSG_SAVEBUTTON));
+	Common::strcpy_s(okbuttontext, get_global_message(MSG_SAVEBUTTON));
 	char labeltext[200];
-	strcpy(labeltext, get_global_message(MSG_SAVEDIALOG));
+	Common::strcpy_s(labeltext, get_global_message(MSG_SAVEDIALOG));
 	const int wnd_width = 200;
 	const int wnd_height = 120;
 	const int boxleft = _G(myscrnwid) / 2 - wnd_width / 2;
@@ -155,8 +155,8 @@ int savegamedialog() {
 	CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0);    // clear the list box
 	preparesavegamelist(ctrllist);
 	if (_G(toomanygames)) {
-		strcpy(okbuttontext, get_global_message(MSG_REPLACE));
-		strcpy(labeltext, get_global_message(MSG_MUSTREPLACE));
+		Common::strcpy_s(okbuttontext, get_global_message(MSG_REPLACE));
+		Common::strcpy_s(labeltext, get_global_message(MSG_MUSTREPLACE));
 		labeltop = 2;
 	} else
 		ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr);
@@ -184,7 +184,7 @@ int savegamedialog() {
 				if (_G(numsaves) > 0)
 					CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursell, &_G(bufTemp)[0]);
 				else
-					strcpy(_G(bufTemp), "_NOSAVEGAMENAME");
+					Common::strcpy_s(_G(bufTemp), "_NOSAVEGAMENAME");
 
 				if (_G(toomanygames)) {
 					int nwhand = CSCIDrawWindow(boxleft + 5, boxtop + 20, 190, 65);
@@ -234,7 +234,7 @@ int savegamedialog() {
 
 					toret = highestnum + 1;
 					String path = get_save_game_path(toret);
-					strcpy(_G(bufTemp), path.GetCStr());
+					Common::strcpy_s(_G(bufTemp), path.GetCStr());
 				} else {
 					toret = _G(filenumbers)[cursell];
 					_G(bufTemp)[0] = 0;
@@ -242,7 +242,7 @@ int savegamedialog() {
 
 				if (_G(bufTemp)[0] == 0) {
 					String path = get_save_game_path(toret);
-					strcpy(_G(bufTemp), path.GetCStr());
+					Common::strcpy_s(_G(bufTemp), path.GetCStr());
 				}
 
 				_G(lpTemp) = &_G(bufTemp)[0];
@@ -331,7 +331,12 @@ void enterstringwindow(const char *prompttext, char *stouse) {
 	if (wantCancel)
 		CSCIDeleteControl(ctrlcancel);
 	CSCIEraseWindow(handl);
-	strcpy(stouse, _G(buffer2));
+	/* FIXME: Function should take a length parameter
+	 * It is called with a 200 bytes buffer below
+	 * but also called with a STD_BUFFER_SIZE (3000) buffer
+	 * and undetermined size buffer in the API
+	 * Using STD_BUFFER_SIZE as we don't want to break too much stuff */
+	Common::strcpy_s(stouse, STD_BUFFER_SIZE, _G(buffer2));
 }
 
 int enternumberwindow(char *prompttext) {
@@ -345,7 +350,7 @@ int enternumberwindow(char *prompttext) {
 int roomSelectorWindow(int currentRoom, int numRooms,
 		const std::vector<int> &roomNumbers, const std::vector<String> &roomNames) {
 	char labeltext[200];
-	strcpy(labeltext, get_global_message(MSG_SAVEDIALOG));
+	Common::strcpy_s(labeltext, get_global_message(MSG_SAVEDIALOG));
 	const int wnd_width = 240;
 	const int wnd_height = 160;
 	const int boxleft = _G(myscrnwid) / 2 - wnd_width / 2;
@@ -451,8 +456,8 @@ int myscimessagebox(const char *lpprompt, char *btn1, char *btn2) {
 
 int quitdialog() {
 	char quitbut[50], playbut[50];
-	strcpy(quitbut, get_global_message(MSG_QUITBUTTON));
-	strcpy(playbut, get_global_message(MSG_PLAYBUTTON));
+	Common::strcpy_s(quitbut, get_global_message(MSG_QUITBUTTON));
+	Common::strcpy_s(playbut, get_global_message(MSG_PLAYBUTTON));
 	return myscimessagebox(get_global_message(MSG_QUITDIALOG), quitbut, playbut);
 }
 
diff --git a/engines/ags/engine/gui/my_listbox.cpp b/engines/ags/engine/gui/my_listbox.cpp
index cc475e8c47f..ec92eb65d2a 100644
--- a/engines/ags/engine/gui/my_listbox.cpp
+++ b/engines/ags/engine/gui/my_listbox.cpp
@@ -126,8 +126,9 @@ int MyListBox::pressedon(int mousex, int mousey) {
 void MyListBox::additem(char *texx) {
 	if (items >= MAXLISTITEM)
 		quit("!CSCIUSER16: Too many items added to listbox");
-	itemnames[items] = (char *)malloc(strlen(texx) + 1);
-	strcpy(itemnames[items], texx);
+	size_t ln = strlen(texx) + 1;
+	itemnames[items] = (char *)malloc(ln);
+	Common::strcpy_s(itemnames[items], ln, texx);
 	items++;
 	needredraw = 1;
 }
@@ -148,14 +149,15 @@ int MyListBox::processmessage(int mcode, int wParam, NumberPtr lParam) {
 		if (topitem + numonscreen <= selected)
 			topitem = (selected + 1) - numonscreen;
 	} else if (mcode == CLB_GETTEXT)
-		strcpy((char *)lParam._ptr, itemnames[wParam]);
+		Common::strcpy_s((char *)lParam._ptr, 260, itemnames[wParam]);
 	else if (mcode == CLB_SETTEXT) {
 		if (wParam < items)
 			free(itemnames[wParam]);
 
 		char *newstri = (char *)lParam._ptr;
-		itemnames[wParam] = (char *)malloc(strlen(newstri) + 2);
-		strcpy(itemnames[wParam], newstri);
+		size_t ln = strlen(newstri) + 2;
+		itemnames[wParam] = (char *)malloc(ln);
+		Common::strcpy_s(itemnames[wParam], ln, newstri);
 
 	} else if (mcode == CTB_KEYPRESS) {
 		if ((wParam == eAGSKeyCodeDownArrow) && (selected < items - 1))
diff --git a/engines/ags/engine/gui/my_textbox.cpp b/engines/ags/engine/gui/my_textbox.cpp
index fe12753996f..10b3ed19c10 100644
--- a/engines/ags/engine/gui/my_textbox.cpp
+++ b/engines/ags/engine/gui/my_textbox.cpp
@@ -35,7 +35,7 @@ MyTextBox::MyTextBox(int xx, int yy, int wii, const char *tee) {
 	y = yy;
 	wid = wii;
 	if (tee != nullptr)
-		strcpy(text, tee);
+		Common::strcpy_s(text, tee);
 	else
 		text[0] = 0;
 
@@ -64,7 +64,7 @@ int MyTextBox::processmessage(int mcode, int wParam, NumberPtr lParam) {
 		snprintf(text, sizeof(text), "%s", (const char *)lParam._ptr);
 		needredraw = 1;
 	} else if (mcode == CTB_GETTEXT)
-		strcpy((char *)lParam._ptr, text); // FIXME! dangerous
+		Common::strcpy_s((char *)lParam._ptr, 260, text); // FIXME! dangerous
 	else if (mcode == CTB_KEYPRESS) {
 		// NOTE: this deprecated control does not support UTF-8
 		int key = wParam;
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 9f5a5b9340e..b321fcc7309 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -368,9 +368,9 @@ bool run_service_key_controls(KeyInput &out_key) {
 		for (int ff = 0; ff < _GP(game).numcharacters; ff++) {
 			if (_GP(game).chars[ff].room != _G(displayed_room)) continue;
 			if (strlen(bigbuffer) > 430) {
-				strcat(bigbuffer, "and more...");
+				Common::strcat_s(bigbuffer, "and more...");
 				Display(bigbuffer);
-				strcpy(bigbuffer, "CHARACTERS IN THIS ROOM (cont'd):[");
+				Common::strcpy_s(bigbuffer, "CHARACTERS IN THIS ROOM (cont'd):[");
 			}
 			chd = ff;
 			sprintf(&bigbuffer[strlen(bigbuffer)],
diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp
index 8a3bb503ae8..b2ccbe0f3b2 100644
--- a/engines/ags/engine/main/quit.cpp
+++ b/engines/ags/engine/main/quit.cpp
@@ -177,7 +177,7 @@ void quit(const char *quitmsg) {
 
 void quit_free() {
 	if (strlen(_G(quit_message)) == 0)
-		strcpy(_G(quit_message), "|bye!");
+		Common::strcpy_s(_G(quit_message), "|bye!");
 
 	const char *quitmsg = _G(quit_message);
 
diff --git a/engines/ags/plugins/ags_plugin.cpp b/engines/ags/plugins/ags_plugin.cpp
index b8b584fa039..594055a481b 100644
--- a/engines/ags/plugins/ags_plugin.cpp
+++ b/engines/ags/plugins/ags_plugin.cpp
@@ -19,6 +19,9 @@
  *
  */
 
+// For dangerous AGS API
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+
 #include "ags/lib/allegro.h"
 #include "ags/lib/std/vector.h"
 #include "ags/shared/core/platform.h"
diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp
index 95456248cb2..d3cb2d775b8 100644
--- a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp
+++ b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp
@@ -103,13 +103,15 @@ void VariableWidthSpriteFontRenderer::SetLineHeightAdjust(int fontNum, int LineH
 void VariableWidthSpriteFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) {
 	VariableWidthFont *font = getFontFor(fontNumber);
 	Common::String s(text);
+	size_t ln = s.size();
 
 	for (int i = (int)s.size() - 1; i >= 0 ; i--) {
 		if (font->characters.count(s[i]) == 0) {
 			s.erase(i, 1);
 		}
 	}
-	text = strcpy(text, s.c_str());
+	// We never grow the text
+	Common::strcpy_s(text, ln + 1, s.c_str());
 
 }
 


Commit: a302f1859b98fb75a09725486f835aee885b5171
    https://github.com/scummvm/scummvm/commit/a302f1859b98fb75a09725486f835aee885b5171
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
ASYLUM: Don't use unsafe strcat and strcpy

Changed paths:
    engines/asylum/views/menu.cpp


diff --git a/engines/asylum/views/menu.cpp b/engines/asylum/views/menu.cpp
index 57e9f52cbcb..d1e40c3caec 100644
--- a/engines/asylum/views/menu.cpp
+++ b/engines/asylum/views/menu.cpp
@@ -781,8 +781,8 @@ void Menu::updateLoadGame() {
 		getText()->loadFont(kFontYellow);
 		getText()->drawCentered(Common::Point(10, 100), 620, MAKE_RESOURCE(kResourcePackText, 1329));
 
-		snprintf((char *)&text, sizeof(text), "%s ?", getSaveLoad()->getName()->c_str());
-		getText()->drawCentered(Common::Point(10, 134), 620, (char *)&text);
+		snprintf(text, sizeof(text), "%s ?", getSaveLoad()->getName()->c_str());
+		getText()->drawCentered(Common::Point(10, 134), 620, text);
 
 		if (cursor.x < 247 || cursor.x > (247 + getText()->getWidth(MAKE_RESOURCE(kResourcePackText, 1330)))
 		 || cursor.y < 273 || cursor.y > (273 + 24))
@@ -830,9 +830,9 @@ void Menu::updateLoadGame() {
 			if (index + _startIndex >= 25)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
+			snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
 
-			if (cursor.x < 30 || cursor.x > (30 + getText()->getWidth((char *)&text))
+			if (cursor.x < 30 || cursor.x > (30 + getText()->getWidth(text))
 			 || cursor.y < y  || cursor.y > (y + 24)) {
 				getText()->loadFont(kFontYellow);
 			} else {
@@ -842,7 +842,7 @@ void Menu::updateLoadGame() {
 			}
 
 			getText()->setPosition(Common::Point(30, y));
-			getText()->draw((char *)&text);
+			getText()->draw(text);
 
 			++index;
 		}
@@ -853,9 +853,9 @@ void Menu::updateLoadGame() {
 			if (index + _startIndex >= 25)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
+			snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
 
-			if (cursor.x < 350 || cursor.x > (350 + getText()->getWidth((char *)&text))
+			if (cursor.x < 350 || cursor.x > (350 + getText()->getWidth(text))
 				|| cursor.y < y   || cursor.y > (y + 24)) {
 				getText()->loadFont(kFontYellow);
 			} else {
@@ -865,7 +865,7 @@ void Menu::updateLoadGame() {
 			}
 
 			getText()->setPosition(Common::Point(350, y));
-			getText()->draw((char *)&text);
+			getText()->draw(text);
 
 			++index;
 		}
@@ -926,8 +926,8 @@ void Menu::updateSaveGame() {
 		getText()->loadFont(kFontYellow);
 		getText()->drawCentered(Common::Point(10, 100), 620, MAKE_RESOURCE(kResourcePackText, 1339));
 
-		snprintf((char *)&text, sizeof(text), "%s ?", getSaveLoad()->getName()->c_str());
-		getText()->drawCentered(Common::Point(10, 134), 620, (char *)&text);
+		snprintf(text, sizeof(text), "%s ?", getSaveLoad()->getName()->c_str());
+		getText()->drawCentered(Common::Point(10, 134), 620, text);
 
 		if (cursor.x < 247 || cursor.x > (247 + getText()->getWidth(MAKE_RESOURCE(kResourcePackText, 1340)))
 		 || cursor.y < 273 || cursor.y > (273 + 24))
@@ -971,10 +971,10 @@ void Menu::updateSaveGame() {
 			if (index + _startIndex >= 25)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
+			snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
 
 			if (!_isEditingSavegameName) {
-				if (cursor.x < 30 || cursor.x > (30 + getText()->getWidth((char *)&text))
+				if (cursor.x < 30 || cursor.x > (30 + getText()->getWidth(text))
 				 || cursor.y < y  || cursor.y > (y + 24))
 					getText()->loadFont(kFontYellow);
 				else
@@ -987,7 +987,7 @@ void Menu::updateSaveGame() {
 			}
 
 			getText()->setPosition(Common::Point(30, y));
-			getText()->draw((char *)&text);
+			getText()->draw(text);
 
 			// Draw underscore
 			if (_isEditingSavegameName) {
@@ -1008,10 +1008,10 @@ void Menu::updateSaveGame() {
 			if (index + _startIndex >= 25)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
+			snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
 
 			if (!_isEditingSavegameName) {
-				if (cursor.x < 350 || cursor.x > (350 + getText()->getWidth((char *)&text))
+				if (cursor.x < 350 || cursor.x > (350 + getText()->getWidth(text))
 				 || cursor.y < y   || cursor.y > (y + 24))
 					getText()->loadFont(kFontYellow);
 				else
@@ -1024,7 +1024,7 @@ void Menu::updateSaveGame() {
 			}
 
 			getText()->setPosition(Common::Point(350, y));
-			getText()->draw((char *)&text);
+			getText()->draw(text);
 
 			// Draw underscore
 			if (_isEditingSavegameName) {
@@ -1086,8 +1086,8 @@ void Menu::updateDeleteGame() {
 		getText()->loadFont(kFontYellow);
 		getText()->drawCentered(Common::Point(10, 100), 620, MAKE_RESOURCE(kResourcePackText, 1349));
 
-		snprintf((char *)&text, sizeof(text), "%s ?", getSaveLoad()->getName()->c_str());
-		getText()->drawCentered(Common::Point(10, 134), 620, (char *)&text);
+		snprintf(text, sizeof(text), "%s ?", getSaveLoad()->getName()->c_str());
+		getText()->drawCentered(Common::Point(10, 134), 620, text);
 
 		if (cursor.x < 247 || cursor.x > (247 + getText()->getWidth(MAKE_RESOURCE(kResourcePackText, 1350)))
 		 || cursor.y < 273 || cursor.y > (273 + 24))
@@ -1119,16 +1119,16 @@ void Menu::updateDeleteGame() {
 		if (index + _startIndex >= 25)
 			break;
 
-		snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
+		snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
 
-		if (cursor.x < 30 || cursor.x > (30 + getText()->getWidth((char *)&text))
+		if (cursor.x < 30 || cursor.x > (30 + getText()->getWidth(text))
 		 || cursor.y < y  || cursor.y > (y + 24))
 			getText()->loadFont(kFontYellow);
 		else
 			getText()->loadFont(kFontBlue);
 
 		getText()->setPosition(Common::Point(30, y));
-		getText()->draw((char *)&text);
+		getText()->draw(text);
 
 		++index;
 	}
@@ -1139,16 +1139,16 @@ void Menu::updateDeleteGame() {
 		if (index + _startIndex >= 25)
 			break;
 
-		snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
+		snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
 
-		if (cursor.x < 350 || cursor.x > (350 + getText()->getWidth((char *)&text))
+		if (cursor.x < 350 || cursor.x > (350 + getText()->getWidth(text))
 		 || cursor.y < y   || cursor.y > (y + 24))
 			getText()->loadFont(kFontYellow);
 		else
 			getText()->loadFont(kFontBlue);
 
 		getText()->setPosition(Common::Point(350, y));
-		getText()->draw((char *)&text);
+		getText()->draw(text);
 
 		++index;
 	}
@@ -1195,8 +1195,8 @@ void Menu::updateViewMovies() {
 
 	if (!_dword_455C78) {
 		getText()->loadFont(kFontYellow);
-		snprintf((char *)&text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1352)), getSharedData()->cdNumber);
-		getText()->drawCentered(Common::Point(10, 100), 620, (char *)&text2);
+		snprintf(text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1352)), getSharedData()->cdNumber);
+		getText()->drawCentered(Common::Point(10, 100), 620, text2);
 
 		//////////////////////////////////////////////////////////////////////////
 		// First column
@@ -1206,19 +1206,19 @@ void Menu::updateViewMovies() {
 				break;
 
 			if (_movieList[index] != -1) {
-				snprintf((char *)&text, sizeof(text), "%d. %s", index + 1, getText()->get(MAKE_RESOURCE(kResourcePackText, 1359 + _movieList[index])));
-				snprintf((char *)&text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1356)), moviesCd[_movieList[index]]);
-				strcat((char *)&text, (char *)&text2);
+				snprintf(text, sizeof(text), "%d. %s", index + 1, getText()->get(MAKE_RESOURCE(kResourcePackText, 1359 + _movieList[index])));
+				snprintf(text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1356)), moviesCd[_movieList[index]]);
+				Common::strcat_s(text, text2);
 
 				if (getCursor()->isHidden()
-				 || cursor.x < 30 || cursor.x > (30 + getText()->getWidth((char *)&text))
+				 || cursor.x < 30 || cursor.x > (30 + getText()->getWidth(text))
 				 || cursor.y < y || cursor.y > (y + 24))
 					getText()->loadFont(kFontYellow);
 				else
 					getText()->loadFont(kFontBlue);
 
 				getText()->setPosition(Common::Point(30, y));
-				getText()->draw((char *)&text);
+				getText()->draw(text);
 			}
 
 			++index;
@@ -1231,19 +1231,19 @@ void Menu::updateViewMovies() {
 				break;
 
 			if (_movieList[index] != -1) {
-				snprintf((char *)&text, sizeof(text), "%d. %s", index + 1, getText()->get(MAKE_RESOURCE(kResourcePackText, 1359 + _movieList[index])));
-				snprintf((char *)&text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1356)), moviesCd[_movieList[index]]);
-				strcat((char *)&text, (char *)&text2);
+				snprintf(text, sizeof(text), "%d. %s", index + 1, getText()->get(MAKE_RESOURCE(kResourcePackText, 1359 + _movieList[index])));
+				snprintf(text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1356)), moviesCd[_movieList[index]]);
+				Common::strcat_s(text, text2);
 
 				if (getCursor()->isHidden()
-					|| cursor.x < 350 || cursor.x > (350 + getText()->getWidth((char *)&text))
+					|| cursor.x < 350 || cursor.x > (350 + getText()->getWidth(text))
 					|| cursor.y < y || cursor.y > (y + 24))
 					getText()->loadFont(kFontYellow);
 				else
 					getText()->loadFont(kFontBlue);
 
 				getText()->setPosition(Common::Point(350, y));
-				getText()->draw((char *)&text);
+				getText()->draw(text);
 			}
 
 			index++;
@@ -1299,12 +1299,12 @@ void Menu::updateViewMovies() {
 	}
 
 	getText()->loadFont(kFontYellow);
-	snprintf((char *)&text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1357)), getSharedData()->cdNumber);
+	snprintf(text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1357)), getSharedData()->cdNumber);
 	getText()->drawCentered(Common::Point(10, 100), 620, text2);
 
-	Common::strlcpy((char *)&text, getText()->get(MAKE_RESOURCE(kResourcePackText, 1359 + _movieIndex)), sizeof(text));
-	snprintf((char *)&text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1356)), moviesCd[_movieIndex]);
-	strcat((char *)&text, (char *)&text2);
+	Common::strlcpy(text, getText()->get(MAKE_RESOURCE(kResourcePackText, 1359 + _movieIndex)), sizeof(text));
+	snprintf(text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1356)), moviesCd[_movieIndex]);
+	Common::strcat_s(text, text2);
 	getText()->drawCentered(Common::Point(10, 134), 620, text);
 
 	getText()->drawCentered(Common::Point(10, 168), 620, getText()->get(MAKE_RESOURCE(kResourcePackText, 1358)));
@@ -1693,9 +1693,9 @@ void Menu::clickLoadGame() {
 			if (index + _startIndex + 6 > 24)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 7, getSaveLoad()->getName((uint32)(index + _startIndex + 6)).c_str());
+			snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 7, getSaveLoad()->getName((uint32)(index + _startIndex + 6)).c_str());
 
-			if (cursor.x <= (350 + getText()->getWidth((char *)&text))
+			if (cursor.x <= (350 + getText()->getWidth(text))
 			 && cursor.y >= y
 			 && cursor.y <= (y + 24)) {
 				uint32 saveIndex = (uint32)(index + _startIndex + 6);
@@ -1711,9 +1711,9 @@ void Menu::clickLoadGame() {
 			if (index + _startIndex > 24)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
+			snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
 
-			if (cursor.x <= (30 + getText()->getWidth((char *)&text))
+			if (cursor.x <= (30 + getText()->getWidth(text))
 			 && cursor.y >= y
 			 && cursor.y <= (y + 24)) {
 				uint32 saveIndex = (uint32)(index + _startIndex);
@@ -1795,9 +1795,9 @@ void Menu::clickSaveGame() {
 			if (index + _startIndex + 6 > 24)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 7, getSaveLoad()->getName((uint32)(index + _startIndex + 6)).c_str());
+			snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 7, getSaveLoad()->getName((uint32)(index + _startIndex + 6)).c_str());
 
-			if (cursor.x <= (350 + getText()->getWidth((char *)&text))
+			if (cursor.x <= (350 + getText()->getWidth(text))
 			 && cursor.y >= y
 			 && cursor.y <= (y + 24)
 			 && getScene()
@@ -1821,9 +1821,9 @@ void Menu::clickSaveGame() {
 			if (index + _startIndex > 24)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
+			snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
 
-			if (cursor.x <= (30 + getText()->getWidth((char *)&text))
+			if (cursor.x <= (30 + getText()->getWidth(text))
 			 && cursor.y >= y
 			 && cursor.y <= (y + 24)
 			 && getScene()
@@ -1909,9 +1909,9 @@ void Menu::clickDeleteGame() {
 			if (index + _startIndex + 6 > 24)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 7, getSaveLoad()->getName((uint32)(index + _startIndex + 6)).c_str());
+			snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 7, getSaveLoad()->getName((uint32)(index + _startIndex + 6)).c_str());
 
-			if (cursor.x <= (350 + getText()->getWidth((char *)&text))
+			if (cursor.x <= (350 + getText()->getWidth(text))
 			 && cursor.y >= y
 			 && cursor.y <= (y + 24)) {
 				uint32 saveIndex = (uint32)(index + _startIndex);
@@ -1927,9 +1927,9 @@ void Menu::clickDeleteGame() {
 			if (index + _startIndex > 24)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
+			snprintf(text, sizeof(text), "%d. %s", index + _startIndex + 1, getSaveLoad()->getName((uint32)(index + _startIndex)).c_str());
 
-			if (cursor.x <= (30 + getText()->getWidth((char *)&text))
+			if (cursor.x <= (30 + getText()->getWidth(text))
 			 && cursor.y >= y
 			 && cursor.y <= (y + 24)) {
 				uint32 saveIndex = (uint32)(index + _startIndex);
@@ -1998,11 +1998,11 @@ void Menu::clickViewMovies() {
 			if (_movieList[index + _startIndex + 6] == -1)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + 1, getText()->get(MAKE_RESOURCE(kResourcePackText, 1359 + _movieList[index])));
-			snprintf((char *)&text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1356)), moviesCd[_movieList[index]]);
-			strcat((char *)&text, (char *)&text2);
+			snprintf(text, sizeof(text), "%d. %s", index + 1, getText()->get(MAKE_RESOURCE(kResourcePackText, 1359 + _movieList[index])));
+			snprintf(text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1356)), moviesCd[_movieList[index]]);
+			Common::strcat_s(text, text2);
 
-			if (cursor.x <= (350 + getText()->getWidth((char *)&text))
+			if (cursor.x <= (350 + getText()->getWidth(text))
 			 && cursor.y >= y
 			 && cursor.y <= (y + 24)) {
 				uint32 movieIndex = (uint32)(index + _startIndex  + 6);
@@ -2023,11 +2023,11 @@ void Menu::clickViewMovies() {
 			if (_movieList[index + _startIndex] == -1)
 				break;
 
-			snprintf((char *)&text, sizeof(text), "%d. %s", index + 1, getText()->get(MAKE_RESOURCE(kResourcePackText, 1359 + _movieList[index])));
-			snprintf((char *)&text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1356)), moviesCd[_movieList[index]]);
-			strcat((char *)&text, (char *)&text2);
+			snprintf(text, sizeof(text), "%d. %s", index + 1, getText()->get(MAKE_RESOURCE(kResourcePackText, 1359 + _movieList[index])));
+			snprintf(text2, sizeof(text2), getText()->get(MAKE_RESOURCE(kResourcePackText, 1356)), moviesCd[_movieList[index]]);
+			Common::strcat_s(text, text2);
 
-			if (cursor.x <= (30 + getText()->getWidth((char *)&text))
+			if (cursor.x <= (30 + getText()->getWidth(text))
 			 && cursor.y >= y
 			 && cursor.y <= (y + 24)) {
 


Commit: d698fc6bbe4aa5dd05c9dcdc6bf3978ca4404e57
    https://github.com/scummvm/scummvm/commit/d698fc6bbe4aa5dd05c9dcdc6bf3978ca4404e57
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CGE: Don't use unsafe strcat and strcpy

Changed paths:
    engines/cge/bitmap.cpp
    engines/cge/cge_main.cpp
    engines/cge/text.cpp
    engines/cge/vga13h.cpp
    engines/cge/vmenu.cpp


diff --git a/engines/cge/bitmap.cpp b/engines/cge/bitmap.cpp
index a9ea0b1dd75..868dad8fa68 100644
--- a/engines/cge/bitmap.cpp
+++ b/engines/cge/bitmap.cpp
@@ -147,11 +147,11 @@ Bitmap &Bitmap::operator=(const Bitmap &bmp) {
 }
 
 char *Bitmap::forceExt(char *buf, const char *name, const char *ext) {
-	strcpy(buf, name);
+	Common::strcpy_s(buf, kMaxPath, name);
 	char *dot = strrchr(buf, '.');
 	if (dot)
 		*dot = '\0';
-	strcat(buf, ext);
+	Common::strcat_s(buf, kMaxPath, ext);
 
 	return buf;
 }
diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp
index 94882d68b93..1463afd8bcd 100644
--- a/engines/cge/cge_main.cpp
+++ b/engines/cge/cge_main.cpp
@@ -115,10 +115,10 @@ const Dac g_stdPal[] =  {// R    G   B
 };
 
 char *CGEEngine::mergeExt(char *buf, const char *name, const char *ext) {
-	strcpy(buf, name);
+	Common::strcpy_s(buf, kPathMax, name);
 	char *dot = strrchr(buf, '.');
 	if (!dot)
-		strcat(buf, ext);
+		Common::strcat_s(buf, kPathMax, ext);
 
 	return buf;
 }
@@ -1041,6 +1041,7 @@ void CGEEngine::loadSprite(const char *fname, int ref, int scene, int col = 0, i
 
 	char tmpStr[kLineMax + 1];
 	Common::String line;
+	STATIC_ASSERT(kLineMax + 1 >= kPathMax, mergeExt_expects_kPathMax_buffer);
 	mergeExt(tmpStr, fname, kSprExt);
 
 	if (_resman->exist(tmpStr)) {      // sprite description file exist
diff --git a/engines/cge/text.cpp b/engines/cge/text.cpp
index eff088ffb32..fe4d534fe22 100644
--- a/engines/cge/text.cpp
+++ b/engines/cge/text.cpp
@@ -113,8 +113,9 @@ void Text::load() {
 			++s;
 
 		_cache[idx]._ref = r;
-		_cache[idx]._text = new char[strlen(s) + 1];
-		strcpy(_cache[idx]._text, s);
+		size_t ln = strlen(s) + 1;
+		_cache[idx]._text = new char[ln];
+		Common::strcpy_s(_cache[idx]._text, ln, s);
 		idx++;
 	}
 }
diff --git a/engines/cge/vga13h.cpp b/engines/cge/vga13h.cpp
index 290180d5ad0..a1063cfe95b 100644
--- a/engines/cge/vga13h.cpp
+++ b/engines/cge/vga13h.cpp
@@ -171,9 +171,9 @@ void Sprite::setName(char *newName) {
 		_ext->_name = nullptr;
 	}
 	if (newName) {
-		_ext->_name = new char[strlen(newName) + 1];
-		assert(_ext->_name != nullptr);
-		strcpy(_ext->_name, newName);
+		size_t ln = strlen(newName) + 1;
+		_ext->_name = new char[ln];
+		Common::strcpy_s(_ext->_name, ln, newName);
 	}
 }
 
diff --git a/engines/cge/vmenu.cpp b/engines/cge/vmenu.cpp
index 732efab8378..df5d01defce 100644
--- a/engines/cge/vmenu.cpp
+++ b/engines/cge/vmenu.cpp
@@ -126,13 +126,14 @@ char *Vmenu::VMGather(Choice *list) {
 		len += strlen(cp->_text);
 		h++;
 	}
-	_vmgt = new char[len + h];
+	len += h;
+	_vmgt = new char[len];
 	if (_vmgt) {
 		*_vmgt = '\0';
 		for (cp = list; cp->_text; cp++) {
 			if (*_vmgt)
-				strcat(_vmgt, "|");
-			strcat(_vmgt, cp->_text);
+				Common::strcat_s(_vmgt, len, "|");
+			Common::strcat_s(_vmgt, len, cp->_text);
 			h++;
 		}
 	}


Commit: ceca603464f0838fbc71c56548d2b57907fcc845
    https://github.com/scummvm/scummvm/commit/ceca603464f0838fbc71c56548d2b57907fcc845
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CGE2: Don't use unsafe strcat and strcpy

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/hero.cpp
    engines/cge2/talk.cpp
    engines/cge2/text.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vmenu.cpp


diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index b271538b21c..f1ca02fcf6f 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -169,6 +169,7 @@ Sprite *CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos)
 	ID id;
 
 	char tmpStr[kLineMax + 1];
+	STATIC_ASSERT(sizeof(tmpStr) >= kPathMax, mergeExt_expects_kPathMax_buffer);
 	mergeExt(tmpStr, fname, kSprExt);
 
 	if (_resman->exist(tmpStr)) { // sprite description file exist
@@ -758,10 +759,10 @@ void CGE2Engine::cge2_main() {
 }
 
 char *CGE2Engine::mergeExt(char *buf, const char *name, const char *ext) {
-	strcpy(buf, name);
+	Common::strcpy_s(buf, kPathMax, name);
 	char *dot = strrchr(buf, '.');
 	if (!dot)
-		strcat(buf, ext);
+		Common::strcat_s(buf, kPathMax, ext);
 
 	return buf;
 }
@@ -777,8 +778,9 @@ void CGE2Engine::setEye(const V2D& e2, int z) {
 }
 
 void CGE2Engine::setEye(const char *s) {
-	char *tempStr = new char[strlen(s) + 1];
-	strcpy(tempStr, s);
+	size_t ln = strlen(s) + 1;
+	char *tempStr = new char[ln];
+	Common::strcpy_s(tempStr, ln, s);
 	_eye->_x = atoi(token(tempStr));
 	_eye->_y = atoi(token(nullptr));
 	_eye->_z = atoi(token(nullptr));
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 36441fc3c43..6dd670f089b 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -194,8 +194,9 @@ Sprite *Hero::expand() {
 	}
 
 	char *tempStr = _vm->_text->getText(_ref + 100);
-	char *text = new char[strlen(tempStr) + 1];
-	strcpy(text, tempStr);
+	size_t ln = strlen(tempStr) + 1;
+	char *text = new char[ln];
+	Common::strcpy_s(text, ln, tempStr);
 	_reachStart = atoi(_vm->token(text));
 	_reachCycle = atoi(_vm->token(nullptr));
 	_sayStart = atoi(_vm->token(nullptr));
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index 17f01370ae9..11c6f023f61 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -61,7 +61,7 @@ Font::~Font() {
 
 void Font::load() {
 	char path[10];
-	strcpy(path, "CGE.CFT");
+	Common::strcpy_s(path, "CGE.CFT");
 	if (!_vm->_resman->exist(path))
 		error("Missing Font file! %s", path);
 
@@ -78,7 +78,7 @@ void Font::load() {
 	}
 	fontFile.read(_map, p);
 
-	strcpy(path, "CGE.TXC");
+	Common::strcpy_s(path, "CGE.TXC");
 	if (!_vm->_resman->exist(path))
 		error("Missing Color file! %s", path);
 
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index 804833d976e..e0edbc6fc9d 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -47,7 +47,7 @@ Text::Text(CGE2Engine *vm, const char *fname) : _vm(vm) {
 
 	_cache[_txtCount - 1]._ref = -1;
 	_cache[_txtCount - 1]._text = new char[3];
-	strcpy(_cache[_txtCount - 1]._text, "");
+	_cache[_txtCount - 1]._text[0] = '\0';
 }
 
 Text::~Text() {
@@ -113,8 +113,9 @@ void Text::load() {
 			++s;
 
 		_cache[idx]._ref = r;
-		_cache[idx]._text = new char[strlen(s) + 1];
-		strcpy(_cache[idx]._text, s);
+		size_t ln = strlen(s) + 1;
+		_cache[idx]._text = new char[ln];
+		Common::strcpy_s(_cache[idx]._text, ln, s);
 		idx++;
 	}
 }
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index f4f495fc8fe..1201d996aeb 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -222,8 +222,9 @@ void Sprite::setName(char *newName) {
 		_ext->_name = nullptr;
 	}
 	if (newName) {
-		_ext->_name = new char[strlen(newName) + 1];
-		strcpy(_ext->_name, newName);
+		size_t ln = strlen(newName) + 1;
+		_ext->_name = new char[ln];
+		Common::strcpy_s(_ext->_name, ln, newName);
 	}
 }
 
@@ -243,6 +244,7 @@ int Sprite::labVal(Action snq, int lab) {
 			return i;
 	} else {
 		char tmpStr[kLineMax + 1];
+		STATIC_ASSERT(sizeof(tmpStr) >= kPathMax, mergeExt_expects_kPathMax_buffer);
 		_vm->mergeExt(tmpStr, _file, kSprExt);
 
 		if (_vm->_resman->exist(tmpStr)) { // sprite description file exist
diff --git a/engines/cge2/vmenu.cpp b/engines/cge2/vmenu.cpp
index 5c0c845f9da..ae15a321ba4 100644
--- a/engines/cge2/vmenu.cpp
+++ b/engines/cge2/vmenu.cpp
@@ -110,12 +110,13 @@ char *VMenu::vmGather(Common::Array<Choice *> list) {
 		len += strlen(list[i]->_text);
 		++h;
 	}
-	_vmgt = new char[len + h];
+	len += h;
+	_vmgt = new char[len];
 	*_vmgt = '\0';
 	for (uint i = 0; i < list.size(); i++) {
 		if (*_vmgt)
-			strcat(_vmgt, "|");
-		strcat(_vmgt, list[i]->_text);
+			Common::strcat_s(_vmgt, len, "|");
+		Common::strcat_s(_vmgt, len, list[i]->_text);
 		++h;
 	}
 


Commit: e87139466453ba168b0385a255d1ad5aa14f1f9c
    https://github.com/scummvm/scummvm/commit/e87139466453ba168b0385a255d1ad5aa14f1f9c
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CHEWY: Don't use unsafe strcat and strcpy

Changed paths:
    engines/chewy/mcga_graphics.cpp


diff --git a/engines/chewy/mcga_graphics.cpp b/engines/chewy/mcga_graphics.cpp
index de1509133b6..5001c1a5d4c 100644
--- a/engines/chewy/mcga_graphics.cpp
+++ b/engines/chewy/mcga_graphics.cpp
@@ -428,7 +428,7 @@ int16 McgaGraphics::scanxy(int16 x, int16 y, int16 fcol, int16 bcol, int16 cur_c
 					if (!zaehler)
 						zaehler = 81;
 					charstr = va_arg(parptr, char *);
-					strcpy(zstring, charstr);
+					Common::strcpy_s(zstring, charstr);
 					break;
 
 				default:
@@ -533,7 +533,7 @@ int16 McgaGraphics::scanxy(int16 x, int16 y, int16 fcol, int16 bcol, int16 cur_c
 
 						if (stelle > 0) {
 							const uint16 fontWidth = _G(fontMgr)->getFont()->getDataWidth();
-							strcpy(zstring + stelle - 1, zstring + stelle);
+							Common::strcpy_s(zstring + stelle - 1, sizeof(zstring) - (stelle - 1), zstring + stelle);
 							plot_scan_cur((x + disp_akt * fontWidth), _G(gcury), bcol, bcol, scrwidth, cursor_z);
 							--stelle;
 							--stellemax;
@@ -604,7 +604,7 @@ int16 McgaGraphics::scanxy(int16 x, int16 y, int16 fcol, int16 bcol, int16 cur_c
 							while (kbhit())
 								getch();
 							eing = 1;
-							strcpy(zstring + stelle, zstring + stelle + 1);
+							Common::strcpy_s(zstring + stelle, sizeof(zstring) - stelle, zstring + stelle + 1);
 							--stellemax;
 						}
 
@@ -655,8 +655,8 @@ int16 McgaGraphics::scanxy(int16 x, int16 y, int16 fcol, int16 bcol, int16 cur_c
 								++stelle;
 							}
 						} else {
-							strcpy(z1string, zstring);
-							strcpy(zstring + stelle + 1, z1string + stelle);
+							Common::strcpy_s(z1string, zstring);
+							Common::strcpy_s(zstring + stelle + 1, sizeof(zstring) - (stelle + 1), z1string + stelle);
 							zstring[stelle] = izahl;
 							zstring[(int)zaehler] = 0;
 							if (stellemax < zaehler) {
@@ -700,7 +700,7 @@ int16 McgaGraphics::scanxy(int16 x, int16 y, int16 fcol, int16 bcol, int16 cur_c
 			longzahl[0] = atol(zstring);
 			break;
 		case 3:
-			strcpy(charstr, zstring);
+			Common::strcpy_s(charstr, 81, zstring);
 			break;
 		case 4:
 			intzahl1[0] = atoi(zstring);


Commit: c618b7fe91d63a94db9db438b2ca9fee396eb53f
    https://github.com/scummvm/scummvm/commit/c618b7fe91d63a94db9db438b2ca9fee396eb53f
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CINE: Don't use unsafe strcat and strcpy

Changed paths:
    engines/cine/anim.cpp
    engines/cine/cine.cpp
    engines/cine/main_loop.cpp
    engines/cine/pal.cpp
    engines/cine/part.cpp
    engines/cine/saveload.cpp
    engines/cine/script_fw.cpp
    engines/cine/various.cpp
    engines/cine/various.h


diff --git a/engines/cine/anim.cpp b/engines/cine/anim.cpp
index b51d833ecdb..814ab2c1536 100644
--- a/engines/cine/anim.cpp
+++ b/engines/cine/anim.cpp
@@ -243,7 +243,7 @@ AnimData::AnimData(const AnimData &src) : _width(src._width),
 	}
 
 	memset(_name, 0, sizeof(_name));
-	strcpy(_name, src._name);
+	Common::strcpy_s(_name, src._name);
 }
 
 /**
@@ -276,7 +276,7 @@ AnimData &AnimData::operator=(const AnimData &src) {
 	_fileIdx = tmp._fileIdx;
 	_frameIdx = tmp._frameIdx;
 	memset(_name, 0, sizeof(_name));
-	strcpy(_name, tmp._name);
+	Common::strcpy_s(_name, tmp._name);
 	_realWidth = tmp._realWidth;
 	_size = tmp._size;
 
@@ -458,7 +458,7 @@ void freeAnimDataTable() {
 static byte getAnimTransparentColor(const char *animName) {
 	char name[15];
 
-	removeExtention(name, animName);
+	removeExtention(name, animName, sizeof(name));
 
 	for (int i = 0; i < ARRAYSIZE(transparencyData); i++) {
 		if (!strcmp(name, transparencyData[i].name)) {
@@ -867,7 +867,7 @@ int loadResource(const char *resourceName, int16 idx, int16 frameIndex) {
 		g_sound->musicType() != MT_MT32 &&
 		(strstr(resourceName, ".SPL") || strstr(resourceName, ".H32"))) {
 		char base[20];
-		removeExtention(base, resourceName);
+		removeExtention(base, resourceName, sizeof(base));
 
 		for (uint i = 0; i < ARRAYSIZE(resNameMapping); i++) {
 			if (scumm_stricmp(base, resNameMapping[i].from) == 0) {
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
index 25adb2a8e45..7e44cdf3a5e 100644
--- a/engines/cine/cine.cpp
+++ b/engines/cine/cine.cpp
@@ -263,7 +263,7 @@ void CineEngine::initialize() {
 	if (getGameType() == Cine::GType_OS && !(getFeatures() & GF_DEMO) &&
 		(getPlatform() == Common::kPlatformDOS || getPlatform() == Common::kPlatformAtariST)) {
 		loadPrc(BOOT_PRC_NAME);
-		strcpy(currentPrcName, BOOT_PRC_NAME);
+		Common::strcpy_s(currentPrcName, BOOT_PRC_NAME);
 		addScriptToGlobalScripts(BOOT_SCRIPT_INDEX);
 		runOnlyUntilFreePartRangeFirst200 = true;
 		executeGlobalScripts();
@@ -279,7 +279,7 @@ void CineEngine::initialize() {
 
 	if (!_preLoad) {
 		loadPrc(BOOT_PRC_NAME);
-		strcpy(currentPrcName, BOOT_PRC_NAME);
+		Common::strcpy_s(currentPrcName, BOOT_PRC_NAME);
 		setMouseCursor(MOUSE_CURSOR_NORMAL);
 	}
 }
diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp
index 1d5b733082b..446bd9141bf 100644
--- a/engines/cine/main_loop.cpp
+++ b/engines/cine/main_loop.cpp
@@ -454,12 +454,12 @@ void CineEngine::mainLoop(int bootScriptIdx) {
 
 		renderer->setBlackPalette(true); // Sets _changePal = true
 
-		strcpy(newPrcName, "");
-		strcpy(newRelName, "");
-		strcpy(newObjectName, "");
-		strcpy(newMsgName, "");
-		strcpy(currentCtName, "");
-		strcpy(currentPartName, "");
+		newPrcName[0] = '\0';
+		newRelName[0] = '\0';
+		newObjectName[0] = '\0';
+		newMsgName[0] = '\0';
+		currentCtName[0] = '\0';
+		currentPartName[0] = '\0';
 
 		g_sound->stopMusic();
 	}
diff --git a/engines/cine/pal.cpp b/engines/cine/pal.cpp
index 3d54ce7e980..7f457714242 100644
--- a/engines/cine/pal.cpp
+++ b/engines/cine/pal.cpp
@@ -35,9 +35,9 @@ static byte paletteBuffer2[16];
 void loadPal(const char *fileName) {
 	char buffer[20];
 
-	removeExtention(buffer, fileName);
+	removeExtention(buffer, fileName, sizeof(buffer));
 
-	strcat(buffer, ".PAL");
+	Common::strcat_s(buffer, ".PAL");
 	g_cine->_palArray.clear();
 
 	Common::File palFileHandle;
@@ -86,7 +86,7 @@ void loadRelatedPalette(const char *fileName) {
 	byte i;
 	int16 paletteIndex;
 
-	removeExtention(localName, fileName);
+	removeExtention(localName, fileName, sizeof(localName));
 
 	paletteIndex = findPaletteFromName(localName);
 
diff --git a/engines/cine/part.cpp b/engines/cine/part.cpp
index 93aca3b9d25..d38cf513685 100644
--- a/engines/cine/part.cpp
+++ b/engines/cine/part.cpp
@@ -289,7 +289,7 @@ byte *readBundleSoundFileFW(const char *entryName, uint32 *size) {
 	char previousPartName[15] = "";
 
 	if (g_cine->getGameType() == Cine::GType_FW) {
-		strcpy(previousPartName, currentPartName);
+		Common::strcpy_s(previousPartName, currentPartName);
 		loadPart("BASESON.SND");
 	}
 	index = findFileInBundle((const char *)entryName);
@@ -354,7 +354,7 @@ void checkDataDisk(int16 diskNum) {
 void dumpBundle(const char *fileName) {
 	char tmpPart[15];
 
-	strcpy(tmpPart, currentPartName);
+	Common::strcpy_s(tmpPart, currentPartName);
 
 	loadPart(fileName);
 	for (uint i = 0; i < g_cine->_partBuffer.size(); i++) {
diff --git a/engines/cine/saveload.cpp b/engines/cine/saveload.cpp
index fa7bf1d2049..6ff9ca446c1 100644
--- a/engines/cine/saveload.cpp
+++ b/engines/cine/saveload.cpp
@@ -710,7 +710,7 @@ bool CineEngine::loadPlainSaveFW(Common::SeekableReadStream &in, CineSaveGameFor
 	if (strlen(bgName)) {
 		if (g_cine->getGameType() == GType_FW && (g_cine->getFeatures() & GF_CD)) {
 			char buffer[20];
-			removeExtention(buffer, bgName);
+			removeExtention(buffer, bgName, sizeof(buffer));
 			g_sound->setBgMusic(atoi(buffer + 1));
 		}
 		loadBg(bgName);
@@ -1049,7 +1049,7 @@ void loadResourcesFromSave(Common::SeekableReadStream &fHandle, enum CineSaveGam
 	int16 foundFileIdx;
 	char *animName, part[256], name[10];
 
-	strcpy(part, currentPartName);
+	Common::strcpy_s(part, currentPartName);
 
 	// We only support these variations of the savegame format at the moment.
 	assert(saveGameFormat == ANIMSIZE_23 || saveGameFormat == ANIMSIZE_30_PTRS_INTACT);
diff --git a/engines/cine/script_fw.cpp b/engines/cine/script_fw.cpp
index ba6796d3db6..617c0e7ec36 100644
--- a/engines/cine/script_fw.cpp
+++ b/engines/cine/script_fw.cpp
@@ -1380,7 +1380,7 @@ int FWScript::o1_loadBg() {
 
 	if (g_cine->getGameType() == GType_FW && (g_cine->getFeatures() & GF_CD)) {
 		char buffer[20];
-		removeExtention(buffer, param);
+		removeExtention(buffer, param, sizeof(buffer));
 		g_sound->setBgMusic(atoi(buffer + 1));
 	}
 
@@ -2212,7 +2212,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			opcode = 0;
 		}
 
-		strcpy(lineBuffer, "");
+		Common::strcpy_s(lineBuffer, "");
 
 		switch (opcode - 1) {
 		case -1: {
@@ -3222,7 +3222,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 		}
 
 		//printf(lineBuffer);
-		strcpy(decompileBuffer[decompileBufferPosition++], lineBuffer);
+		Common::strcpy_s(decompileBuffer[decompileBufferPosition++], lineBuffer);
 
 		exitScript = 0;
 		if (position >= scriptSize) {
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index f57057b55d9..a1b0e0c3225 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -312,11 +312,11 @@ void CineEngine::resetEngine() {
 	bgVar0 = 0;
 	var2 = var3 = var4 = lastType20OverlayBgIdx = 0;
 
-	strcpy(newPrcName, "");
-	strcpy(newRelName, "");
-	strcpy(newObjectName, "");
-	strcpy(newMsgName, "");
-	strcpy(currentCtName, "");
+	newPrcName[0] = '\0';
+	newRelName[0] = '\0';
+	newObjectName[0] = '\0';
+	newMsgName[0] = '\0';
+	currentCtName[0] = '\0';
 
 	allowPlayerInput = 0;
 	waitForPlayerClick = 0;
@@ -609,7 +609,7 @@ int16 buildObjectListCommand(int16 param) {
 
 	for (i = 0; i < 255; i++) {
 		if (g_cine->_objectTable[i].name[0] && g_cine->_objectTable[i].costume == param) {
-			strcpy(objectListCommand[j], g_cine->_objectTable[i].name);
+			Common::strcpy_s(objectListCommand[j], g_cine->_objectTable[i].name);
 			objListTab[j] = i;
 			j++;
 		}
@@ -1471,8 +1471,8 @@ void checkForPendingDataLoad() {
 	if (newPrcName[0] != 0) {
 		bool loadPrcOk = loadPrc(newPrcName);
 
-		strcpy(currentPrcName, newPrcName);
-		strcpy(newPrcName, "");
+		Common::strcpy_s(currentPrcName, newPrcName);
+		newPrcName[0] = '\0';
 
 		// Check that the loading of the script file was successful before
 		// trying to add script 1 from it to the global scripts list. This
@@ -1490,8 +1490,8 @@ void checkForPendingDataLoad() {
 	if (newRelName[0] != 0) {
 		loadRel(newRelName);
 
-		strcpy(currentRelName, newRelName);
-		strcpy(newRelName, "");
+		Common::strcpy_s(currentRelName, newRelName);
+		newRelName[0] = '\0';
 	}
 
 	if (newObjectName[0] != 0) {
@@ -1499,23 +1499,23 @@ void checkForPendingDataLoad() {
 
 		loadObject(newObjectName);
 
-		strcpy(currentObjectName, newObjectName);
-		strcpy(newObjectName, "");
+		Common::strcpy_s(currentObjectName, newObjectName);
+		newObjectName[0] = '\0';
 	}
 
 	if (newMsgName[0] != 0) {
 		loadMsg(newMsgName);
 
-		strcpy(currentMsgName, newMsgName);
-		strcpy(newMsgName, "");
+		Common::strcpy_s(currentMsgName, newMsgName);
+		newMsgName[0] = '\0';
 	}
 }
 
 void hideMouse() {
 }
 
-void removeExtention(char *dest, const char *source) {
-	strcpy(dest, source);
+void removeExtention(char *dest, const char *source, size_t sz) {
+	Common::strcpy_s(dest, sz, source);
 
 	byte *ptr = (byte *) strchr(dest, '.');
 
@@ -1954,7 +1954,7 @@ bool makeTextEntryMenu(const char *messagePtr, char *inputString, int stringMaxL
 				if (inputPos != inputLength) {
 					strncat(tempString, &inputString[inputPos], inputLength - inputPos);
 				}
-				strcpy(inputString, tempString);
+				Common::strcpy_s(inputString, stringMaxLength, tempString);
 				inputLength = strlen(inputString);
 				redraw = true;
 			}
@@ -1980,16 +1980,16 @@ bool makeTextEntryMenu(const char *messagePtr, char *inputString, int stringMaxL
 					ch[0] = ascii;
 					if (inputPos != 1) {
 						strncpy(tempString, inputString, inputPos - 1);
-						strcat(tempString, ch);
+						Common::strcat_s(tempString, ch);
 					}
 					if ((inputLength == 0) || (inputPos == 1)) {
-						strcpy(tempString, ch);
+						Common::strcpy_s(tempString, ch);
 					}
 					if ((inputLength != 0) && (inputPos != inputLength)) {
 						strncat(tempString, &inputString[inputPos - 1], inputLength - inputPos + 1);
 					}
 
-					strcpy(inputString, tempString);
+					Common::strcpy_s(inputString, stringMaxLength, tempString);
 					inputLength = strlen(inputString);
 					inputPos++;
 					redraw = true;
diff --git a/engines/cine/various.h b/engines/cine/various.h
index 830e3d460d1..9cdbff3f577 100644
--- a/engines/cine/various.h
+++ b/engines/cine/various.h
@@ -133,7 +133,7 @@ void checkForPendingDataLoad();
 
 void hideMouse();
 
-void removeExtention(char *dest, const char *source);
+void removeExtention(char *dest, const char *source, size_t sz);
 
 struct SelectedObjStruct {
 	int16 idx;


Commit: f2ddbbea917a3b41d5576bac0aef7868a3193619
    https://github.com/scummvm/scummvm/commit/f2ddbbea917a3b41d5576bac0aef7868a3193619
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CRUISE: Don't use unsafe strcat and strcpy

Changed paths:
    engines/cruise/backgroundIncrust.cpp
    engines/cruise/cruise_main.cpp
    engines/cruise/cruise_main.h
    engines/cruise/dataLoader.cpp
    engines/cruise/decompiler.cpp
    engines/cruise/font.cpp
    engines/cruise/function.cpp
    engines/cruise/linker.cpp
    engines/cruise/perso.cpp
    engines/cruise/saveload.cpp
    engines/cruise/volume.cpp


diff --git a/engines/cruise/backgroundIncrust.cpp b/engines/cruise/backgroundIncrust.cpp
index c896f56edcb..ec8e4a4c871 100644
--- a/engines/cruise/backgroundIncrust.cpp
+++ b/engines/cruise/backgroundIncrust.cpp
@@ -138,7 +138,7 @@ backgroundIncrustStruct *addBackgroundIncrust(int16 overlayIdx,	int16 objectIdx,
 	newElement->frame = params.fileIdx;
 	newElement->spriteId = filesDatabase[params.fileIdx].subData.index;
 	newElement->ptr = nullptr;
-	strcpy(newElement->name, filesDatabase[params.fileIdx].subData.name);
+	Common::strcpy_s(newElement->name, filesDatabase[params.fileIdx].subData.name);
 
 	if (filesDatabase[params.fileIdx].subData.resourceType == OBJ_TYPE_SPRITE) {
 		// sprite
diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp
index 6da5c507149..f9a7c4d14e0 100644
--- a/engines/cruise/cruise_main.cpp
+++ b/engines/cruise/cruise_main.cpp
@@ -309,18 +309,18 @@ void printInfoBlackBox(const char *string) {
 void waitForPlayerInput() {
 }
 
-void getFileExtention(const char *name, char *buffer) {
+void getFileExtention(const char *name, char *buffer, size_t ln) {
 	while (*name != '.' && *name) {
 		name++;
 	}
 
-	strcpy(buffer, name);
+	Common::strcpy_s(buffer, ln, name);
 }
 
-void removeExtention(const char *name, char *buffer) {	// not like in original
+void removeExtention(const char *name, char *buffer, size_t ln) {	// not like in original
 	char *ptr;
 
-	strcpy(buffer, name);
+	Common::strcpy_s(buffer, ln, name);
 
 	ptr = strchr(buffer, '.');
 
@@ -344,19 +344,19 @@ int loadFileSub1(uint8 **ptr, const char *name, uint8 *ptr2) {
 		}
 	}
 
-	getFileExtention(name, buffer);
+	getFileExtention(name, buffer, sizeof(buffer));
 
 	if (!strcmp(buffer, ".SPL")) {
-		removeExtention(name, buffer);
+		removeExtention(name, buffer, sizeof(buffer));
 
 		/* if (useH32)
 		 *{
-		 *	strcat(buffer, ".H32");
+		 *	Common::strcat_s(buffer,".H32");
 		 *}
 		 * else
 		 * if (useAdLib)
 		 * { */
-		 strcat(buffer,".ADL");
+		Common::strcat_s(buffer,".ADL");
 		/* }
 		 * else
 		 * {
@@ -563,7 +563,7 @@ void CruiseEngine::initAllData() {
 		scriptFunc2(bootOverlayNumber, &procHead, 1, 0);
 	}
 
-	strcpy(lastOverlay, "AUTO00");
+	Common::strcpy_s(lastOverlay, "AUTO00");
 
 	_gameSpeed = GAME_FRAME_DELAY_1;
 	_speedFlag = false;
@@ -1622,9 +1622,9 @@ int CruiseEngine::processInput() {
 							changeCursor(CURSOR_NORMAL);
 						} else { // else create the message for the linked relation
 							char text[80];
-							strcpy(text, menuTable[0]->stringPtr);
-							strcat(text, ":");
-							strcat(text, currentMenuElement->string);
+							Common::strcpy_s(text, menuTable[0]->stringPtr);
+							Common::strcat_s(text, ":");
+							Common::strcat_s(text, currentMenuElement->string);
 							linkedMsgList = renderText(320, (const char *)text);
 							changeCursor(CURSOR_CROSS);
 						}
@@ -1761,9 +1761,9 @@ void CruiseEngine::mainLoop() {
 
 	int enableUser = 0;
 
-	strcpy(nextOverlay, "");
-	strcpy(lastOverlay, "");
-	strcpy(cmdLine, "");
+	nextOverlay[0] = '\0';
+	lastOverlay[0] = '\0';
+	cmdLine[0] = '\0';
 
 	currentActiveMenu = -1;
 	autoMsg = -1;
diff --git a/engines/cruise/cruise_main.h b/engines/cruise/cruise_main.h
index 5a76762bf6e..6fc78f034e0 100644
--- a/engines/cruise/cruise_main.h
+++ b/engines/cruise/cruise_main.h
@@ -94,9 +94,9 @@ void resetFileEntryRange(int param1, int param2);
 int getProcParam(int overlayIdx, int param2, const char * name);
 void changeScriptParamInList(int param1, int param2, scriptInstanceStruct * pScriptInstance, int newValue, int param3);
 uint8 *getDataFromData3(ovlData3Struct * ptr, int param);
-void removeExtention(const char *name, char *buffer);
+void removeExtention(const char *name, char *buffer, size_t ln);
 void resetPtr2(scriptInstanceStruct * ptr);
-void getFileExtention(const char *name, char *buffer);
+void getFileExtention(const char *name, char *buffer, size_t ln);
 void *allocAndZero(int size);
 void freeStuff2();
 void mainLoop();
diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp
index b127bb47b88..0d04d1228f0 100644
--- a/engines/cruise/dataLoader.cpp
+++ b/engines/cruise/dataLoader.cpp
@@ -216,7 +216,7 @@ fileTypeEnum getFileType(const char *name) {
 
 	fileTypeEnum newFileType = type_UNK;
 
-	getFileExtention(name, extentionBuffer);
+	getFileExtention(name, extentionBuffer, sizeof(extentionBuffer));
 
 	if (!strcmp(extentionBuffer, ".SPL")) {
 		newFileType = type_SPL;
diff --git a/engines/cruise/decompiler.cpp b/engines/cruise/decompiler.cpp
index 9bfb4d10555..e6caa2eed63 100644
--- a/engines/cruise/decompiler.cpp
+++ b/engines/cruise/decompiler.cpp
@@ -297,12 +297,13 @@ void addDecomp(char *string, ...) {
 
 void resolveVarName(char *ovlIdxString, int varType, char *varIdxString,
 					char *outputName) {
+	// outputName is 256 length
 	int varIdx = atoi(varIdxString);
 
-	strcpy(outputName, "");
+	outputName[0] = '\0';
 
 	if (varType == 2) {
-		strcpy(outputName, getStringNameFromIdx(varType,
+		Common::strlcpy(outputName, 256, getStringNameFromIdx(varType,
 		                                        varIdxString));
 		return;
 	}
@@ -333,7 +334,7 @@ void resolveVarName(char *ovlIdxString, int varType, char *varIdxString,
 		sprintf(outputName, "ovl(%s).[%d][%s]", ovlIdxString, varType,
 		        varIdxString);
 	} else {
-		strcpy(outputName, ovlIdxString);
+		Common::strcpy_s(outputName, 256,  ovlIdxString);
 	}
 }
 
@@ -451,7 +452,7 @@ int decompSaveVar() {
 		break;
 	}
 	case 4: {
-		strcpy(decompSaveOpcodeVar, popDecomp());
+		Common::strcpy_s(decompSaveOpcodeVar,  popDecomp());
 		break;
 	}
 	case 5: {
@@ -685,8 +686,8 @@ int decompSwapStack() {
 	stack1 = popDecomp();
 	stack2 = popDecomp();
 
-	strcpy(buffer1, stack1);
-	strcpy(buffer2, stack2);
+	Common::strcpy_s(buffer1,  stack1);
+	Common::strcpy_s(buffer2,  stack2);
 
 	pushDecomp(buffer1);
 	pushDecomp(buffer2);
@@ -722,7 +723,7 @@ int decompFunction() {
 
 	case 0x6: {
 		unsigned long int numArg = atoi(popDecomp());
-		char functionName[100];
+		char functionName[256];
 
 		char *idxStr = popDecomp();
 		char *ovlStr = popDecomp();
diff --git a/engines/cruise/font.cpp b/engines/cruise/font.cpp
index 31f5eca42b8..bc05695a743 100644
--- a/engines/cruise/font.cpp
+++ b/engines/cruise/font.cpp
@@ -146,7 +146,7 @@ void initSystem() {
 	subColor = 10;
 
 	for (i = 0; i < 64; i++) {
-		strcpy(preloadData[i].name, "");
+		preloadData[i].name[0] = '\0';
 		preloadData[i].ptr = nullptr;
 		preloadData[i].nofree = 0;
 	}
@@ -161,7 +161,7 @@ void initSystem() {
 	changeCursor(CURSOR_NORMAL);
 	mouseOn();
 
-	strcpy(cmdLine, "");
+	cmdLine[0] = '\0';
 
 	loadFNT("system.fnt");
 }
diff --git a/engines/cruise/function.cpp b/engines/cruise/function.cpp
index 12a91c048f5..a5d04bdb512 100644
--- a/engines/cruise/function.cpp
+++ b/engines/cruise/function.cpp
@@ -19,6 +19,9 @@
  *
  */
 
+// For Op_BgName
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+
 #include "cruise/cruise.h"
 #include "cruise/cruise_main.h"
 #include "cruise/cell.h"
@@ -46,7 +49,7 @@ int16 Op_LoadOverlay() {
 	if (strlen(pOverlayName) == 0)
 		return 0;
 
-	strcpy(overlayName, pOverlayName);
+	Common::strcpy_s(overlayName, pOverlayName);
 	strToUpper(overlayName);
 
 	//gfxModuleData.field_84();
@@ -790,7 +793,7 @@ int16 Op_ClearScreen() {
 	if ((bgIdx >= 0) && (bgIdx < NBSCREENS) && (backgroundScreens[bgIdx])) {
 		memset(backgroundScreens[bgIdx], 0, 320 * 200);
 		backgroundChanged[bgIdx] = true;
-		strcpy(backgroundTable[0].name, "");
+		backgroundTable[0].name[0] = '\0';
 	}
 
 	return 0;
@@ -944,9 +947,9 @@ int16 Op_RemoveBackground() {
 			backgroundChanged[0] = true;
 		}
 
-		strcpy(backgroundTable[backgroundIdx].name, "");
+		backgroundTable[backgroundIdx].name[0] = '\0';
 	} else {
-		strcpy(backgroundTable[0].name, "");
+		backgroundTable[0].name[0] = '\0';
 	}
 
 	return (0);
@@ -1524,11 +1527,9 @@ int16 Op_Itoa() {
 		sprintf(txt, "%d", val);
 	else {
 		char format[30];
-		char nbf[20];
-		strcpy(format, "%");
-		sprintf(nbf, "%d", param[0]);
-		strcat(format, nbf);
-		strcat(format, "d");
+		format[0] = '%';
+		sprintf(&format[1], "%d", param[0]);
+		Common::strcat_s(format, "d");
 		sprintf(txt, format, val);
 	}
 
diff --git a/engines/cruise/linker.cpp b/engines/cruise/linker.cpp
index 0370893dae9..9e2ebd6d101 100644
--- a/engines/cruise/linker.cpp
+++ b/engines/cruise/linker.cpp
@@ -45,7 +45,7 @@ exportEntryStruct *parseExport(int *out1, int *pExportedFuncionIdx, char *buffer
 		Common::strlcpy(functionName, dotPtr + 1, sizeof(functionName));
 		*dotPtr = 0;
 
-		strcpy(overlayName, localBuffer);
+		Common::strcpy_s(overlayName, localBuffer);
 	} else {
 		overlayName[0] = 0;
 
diff --git a/engines/cruise/perso.cpp b/engines/cruise/perso.cpp
index 950c83cfb97..001ba7606c9 100644
--- a/engines/cruise/perso.cpp
+++ b/engines/cruise/perso.cpp
@@ -51,7 +51,7 @@ void freeCTP() {
 	ctpVar17 = nullptr;
 	_vm->_polyStruct = nullptr;
 
-	strcpy((char *)currentCtpName, "");
+	currentCtpName[0] = '\0';
 }
 
 int pathVar0;
diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp
index e5445475571..fcdae64892c 100644
--- a/engines/cruise/saveload.cpp
+++ b/engines/cruise/saveload.cpp
@@ -71,7 +71,7 @@ WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegam
 void writeSavegameHeader(Common::OutSaveFile *out, CruiseSavegameHeader &header) {
 	// Write out a savegame header
 	char saveIdentBuffer[6];
-	strcpy(saveIdentBuffer, "SVMCR");
+	Common::strcpy_s(saveIdentBuffer, "SVMCR");
 	out->write(saveIdentBuffer, 6);
 
 	out->writeByte(CRUISE_SAVEGAME_VERSION);
@@ -645,7 +645,7 @@ void resetPreload() {
 				MemFree(preloadData[i].ptr);
 				preloadData[i].ptr = nullptr;
 			}
-			strcpy(preloadData[i].name, "");
+			preloadData[i].name[0] = '\0';
 			preloadData[i].nofree = 0;
 		}
 	}
@@ -654,7 +654,7 @@ void resetPreload() {
 void unloadOverlay(const char*name, int overlayNumber) {
 	releaseOverlay(name);
 
-	strcpy(overlayTable[overlayNumber].overlayName, "");
+	overlayTable[overlayNumber].overlayName[0] = '\0';
 	overlayTable[overlayNumber].ovlData = nullptr;
 	overlayTable[overlayNumber].alreadyLoaded = 0;
 }
diff --git a/engines/cruise/volume.cpp b/engines/cruise/volume.cpp
index 47e1f8d859a..0724e2dd2af 100644
--- a/engines/cruise/volume.cpp
+++ b/engines/cruise/volume.cpp
@@ -70,7 +70,7 @@ int closeBase() {
 
 		MemFree(volumePtrToFileDescriptor);
 
-		strcpy(currentBaseName, "");
+		currentBaseName[0] = '\0';
 	}
 
 	if (_vm->_PAL_file.isOpen()) {
@@ -91,7 +91,7 @@ int getVolumeDataEntry(volumeDataStruct *entry) {
 
 	askDisk(-1);
 
-	strcpy(buffer, entry->ident);
+	Common::strcpy_s(buffer, entry->ident);
 
 	_vm->_currentVolumeFile.open(buffer);
 
@@ -125,7 +125,7 @@ int getVolumeDataEntry(volumeDataStruct *entry) {
 		volumePtrToFileDescriptor[i].unk3 = _vm->_currentVolumeFile.readSint32BE();
 	}
 
-	strcpy(currentBaseName, entry->ident);
+	Common::strcpy_s(currentBaseName, entry->ident);
 
 	loadPal(entry);
 


Commit: f25c8239b1f9065de9495013dcb1a8bdfca8e159
    https://github.com/scummvm/scummvm/commit/f25c8239b1f9065de9495013dcb1a8bdfca8e159
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CRYO: Don't use unsafe strcat and strcpy

Changed paths:
    engines/cryo/eden.cpp


diff --git a/engines/cryo/eden.cpp b/engines/cryo/eden.cpp
index 5f588b0909e..3c704cd8605 100644
--- a/engines/cryo/eden.cpp
+++ b/engines/cryo/eden.cpp
@@ -5294,7 +5294,7 @@ void EdenGame::load() {
 //	if(OpenDialog(0, 0)) //TODO: write me
 	{
 		// TODO
-		strcpy(name, "edsave1.000");
+		Common::strcpy_s(name, "edsave1.000");
 		loadgame(name);
 	}
 	_vm->hideMouse();
@@ -5363,7 +5363,7 @@ void EdenGame::save() {
 	FlushEvents(-1, 0);
 	//SaveDialog(byte_37150, byte_37196->ff_A);
 	//TODO
-	strcpy(name, "edsave1.000");
+	Common::strcpy_s(name, "edsave1.000");
 	saveGame(name);
 	_vm->hideMouse();
 	CLBlitter_FillScreenView(0xFFFFFFFF);


Commit: b6a1284bafea88c991fd70b93b8d151c5177db43
    https://github.com/scummvm/scummvm/commit/b6a1284bafea88c991fd70b93b8d151c5177db43
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CRYOMNI3D: Don't use unsafe strcat and strcpy

Changed paths:
    engines/cryomni3d/versailles/logic.cpp


diff --git a/engines/cryomni3d/versailles/logic.cpp b/engines/cryomni3d/versailles/logic.cpp
index 4dd66cb907a..cee28b17168 100644
--- a/engines/cryomni3d/versailles/logic.cpp
+++ b/engines/cryomni3d/versailles/logic.cpp
@@ -4766,7 +4766,7 @@ FILTER_EVENT(7, 20) {
 // Countdown
 
 void CryOmni3DEngine_Versailles::initCountdown() {
-	strcpy(_countdownValue, "05:00");
+	Common::strcpy_s(_countdownValue, "05:00");
 	if (_gameVariables[GameVariables::kSavedCountdown]) {
 		uint counter = _gameVariables[GameVariables::kSavedCountdown];
 		_countdownValue[4] = counter;


Commit: 667ea2f88e2d16ff7ae849a99a4f050d473c736b
    https://github.com/scummvm/scummvm/commit/667ea2f88e2d16ff7ae849a99a4f050d473c736b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
DM: Don't use unsafe strcat and strcpy

Changed paths:
    engines/dm/champion.cpp
    engines/dm/dialog.cpp
    engines/dm/dm.cpp
    engines/dm/dungeonman.cpp
    engines/dm/dungeonman.h
    engines/dm/gfx.cpp
    engines/dm/inventory.cpp
    engines/dm/menus.cpp
    engines/dm/movesens.cpp
    engines/dm/timeline.cpp


diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp
index 39ea2d7d843..ef854e31809 100644
--- a/engines/dm/champion.cpp
+++ b/engines/dm/champion.cpp
@@ -1951,7 +1951,8 @@ void ChampionMan::addCandidateChampionToParty(uint16 championPortraitIndex) {
 
 	char L0807_ac_DecodedChampionText[77];
 	char *decodedStringPtr = L0807_ac_DecodedChampionText;
-	dungeon.decodeText(decodedStringPtr, curThing, (TextType)(kDMTextTypeScroll | kDMMaskDecodeEvenIfInvisible));
+	dungeon.decodeText(decodedStringPtr, sizeof(L0807_ac_DecodedChampionText),
+			curThing, (TextType)(kDMTextTypeScroll | kDMMaskDecodeEvenIfInvisible));
 
 	uint16 charIdx = 0;
 	char tmpChar;
@@ -2308,21 +2309,21 @@ void ChampionMan::drawChampionState(ChampionIndex champIndex) {
 		}
 
 		maxLoad = curChampion->_load / 10;
-		strcpy(_vm->_stringBuildBuffer, getStringFromInteger(maxLoad, true, 3).c_str());
+		Common::strcpy_s(_vm->_stringBuildBuffer, getStringFromInteger(maxLoad, true, 3).c_str());
 
 		switch (_vm->getGameLanguage()) { // localized
 		default:
-		case Common::EN_ANY: strcat(_vm->_stringBuildBuffer, "."); break;
-		case Common::DE_DEU: strcat(_vm->_stringBuildBuffer, ","); break;
-		case Common::FR_FRA: strcat(_vm->_stringBuildBuffer, "KG,"); break;
+		case Common::EN_ANY: Common::strcat_s(_vm->_stringBuildBuffer, "."); break;
+		case Common::DE_DEU: Common::strcat_s(_vm->_stringBuildBuffer, ","); break;
+		case Common::FR_FRA: Common::strcat_s(_vm->_stringBuildBuffer, "KG,"); break;
 		}
 
 		maxLoad = curChampion->_load - (maxLoad * 10);
-		strcat(_vm->_stringBuildBuffer, getStringFromInteger(maxLoad, false, 1).c_str());
-		strcat(_vm->_stringBuildBuffer, "/");
+		Common::strcat_s(_vm->_stringBuildBuffer, getStringFromInteger(maxLoad, false, 1).c_str());
+		Common::strcat_s(_vm->_stringBuildBuffer, "/");
 		maxLoad = (getMaximumLoad(curChampion) + 5) / 10;
-		strcat(_vm->_stringBuildBuffer, getStringFromInteger(maxLoad, true, 3).c_str());
-		strcat(_vm->_stringBuildBuffer, " KG");
+		Common::strcat_s(_vm->_stringBuildBuffer, getStringFromInteger(maxLoad, true, 3).c_str());
+		Common::strcat_s(_vm->_stringBuildBuffer, " KG");
 		txtMan.printToViewport(148, 132, loadColor, _vm->_stringBuildBuffer);
 		setFlag(championAttributes, kDMAttributeViewport);
 	}
@@ -2509,7 +2510,7 @@ void ChampionMan::renameChampion(Champion *champ) {
 					int16 characterIndexBackup = curCharacterIndex;
 					char championNameBackupString[8];
 					renamedChampionString = champ->_name;
-					strcpy(championNameBackupString, renamedChampionString);
+					Common::strcpy_s(championNameBackupString, renamedChampionString);
 					curCharacterIndex = strlen(renamedChampionString);
 					// Replace space characters on the right of the champion name by '\0' characters
 					while (renamedChampionString[--curCharacterIndex] == ' ')
@@ -2529,7 +2530,8 @@ void ChampionMan::renameChampion(Champion *champ) {
 					if (renamedChampionStringMode == kDMRenameChampionTitle)
 						renamedChampionString = champ->_title;
 
-					strcpy(renamedChampionString = champ->_name, championNameBackupString);
+					Common::strcpy_s(champ->_name, championNameBackupString);
+					renamedChampionString = champ->_name;
 					curCharacterIndex = characterIndexBackup;
 				} else {
 					if ((mousePos.x >= 107) && (mousePos.x <= 175) && (mousePos.y >= 147) && (mousePos.y <= 155)) { /* Coordinates of 'BACKSPACE' button */
diff --git a/engines/dm/dialog.cpp b/engines/dm/dialog.cpp
index 4064d4f122b..a19294d6499 100644
--- a/engines/dm/dialog.cpp
+++ b/engines/dm/dialog.cpp
@@ -150,13 +150,13 @@ bool DialogMan::isMessageOnTwoLines(const char *str, char *part1, char *part2) {
 	if (strLength <= 30)
 		return false;
 
-	strcpy(part1, str);
+	Common::strcpy_s(part1, 70, str);
 	uint16 splitPosition = strLength >> 1;
 	while ((splitPosition < strLength) && (part1[splitPosition] != ' '))
 		splitPosition++;
 
 	part1[splitPosition] = '\0';
-	strcpy(part2, &part1[splitPosition + 1]);
+	Common::strcpy_s(part2, 70, &part1[splitPosition + 1]);
 	return true;
 }
 
diff --git a/engines/dm/dm.cpp b/engines/dm/dm.cpp
index cf172bc3835..224ab37ce2f 100644
--- a/engines/dm/dm.cpp
+++ b/engines/dm/dm.cpp
@@ -1003,7 +1003,8 @@ void DMEngine::fuseSequence() {
 	while (textStringThingCount--) {
 		for (int16 idx = 0; idx < maxCount; idx++) {
 			char decodedString[200];
-			_dungeonMan->decodeText(decodedString, textStringThings[idx], (TextType)(kDMTextTypeMessage | kDMMaskDecodeEvenIfInvisible));
+			_dungeonMan->decodeText(decodedString, sizeof(decodedString),
+					textStringThings[idx], (TextType)(kDMTextTypeMessage | kDMMaskDecodeEvenIfInvisible));
 			if (decodedString[1] == textFirstChar) {
 				_textMan->clearAllRows();
 				decodedString[1] = '\n'; /* New line */
diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp
index 20fe78a0788..b585ca68733 100644
--- a/engines/dm/dungeonman.cpp
+++ b/engines/dm/dungeonman.cpp
@@ -1046,7 +1046,7 @@ Thing DungeonMan::getNextThing(Thing thing) {
 	return Thing(getThingData(thing)[0]);
 }
 
-void DungeonMan::decodeText(char *destString, Thing thing, TextType type) {
+void DungeonMan::decodeText(char *destString, size_t maxSize, Thing thing, TextType type) {
 	static char messageAndScrollEscReplacementStrings[32][8] = { // @ G0255_aac_Graphic559_MessageAndScrollEscapeReplacementStrings
 		{'x',   0,   0,   0, 0, 0, 0, 0}, /* Atari ST Version 1.0 1987-12-08 1987-12-11 1.1 1.2EN 1.2GE: { '?',  0,  0,  0, 0, 0, 0, 0 }, */
 		{'y',   0,   0,   0, 0, 0, 0, 0}, /* Atari ST Version 1.0 1987-12-08 1987-12-11 1.1 1.2EN 1.2GE: { '!',  0,  0,  0, 0, 0, 0, 0 }, */
@@ -1145,7 +1145,8 @@ void DungeonMan::decodeText(char *destString, Thing thing, TextType type) {
 		uint16 *codeWord = _dungeonTextData + textString.getWordOffset();
 		uint16 code = 0, codes = 0;
 		char *escReplString = nullptr;
-		for (;;) { /*infinite loop*/
+		char *endDestString = destString + maxSize;
+		for (; destString < endDestString; ) {
 			if (!codeCounter) {
 				codes = *codeWord++;
 				code = (codes >> 10) & 0x1F;
@@ -1167,8 +1168,8 @@ void DungeonMan::decodeText(char *destString, Thing thing, TextType type) {
 				} else
 					escReplString = escReplacementCharacters[code];
 
-				strcat(destString, escReplString);
-				destString += strlen(escReplString);
+				size_t ln = Common::strlcpy(destString, escReplString, endDestString - destString);
+				destString += ln;
 				escChar = 0;
 			} else if (code < 28) {
 				if (type != kDMTextTypeInscription) {
@@ -1187,6 +1188,7 @@ void DungeonMan::decodeText(char *destString, Thing thing, TextType type) {
 			else
 				break;
 		}
+		assert(destString < endDestString);
 	}
 	*destString = ((type == kDMTextTypeInscription) ? 0x81 : '\0');
 }
diff --git a/engines/dm/dungeonman.h b/engines/dm/dungeonman.h
index ac5f287b79f..66ca67c61a3 100644
--- a/engines/dm/dungeonman.h
+++ b/engines/dm/dungeonman.h
@@ -641,7 +641,7 @@ public:
 		return Square(getRelSquare(dir, stepsForward, stepsRight, posX, posY)).getType();
 	} // @ F0153_DUNGEON_GetRelativeSquareType
 	void setSquareAspect(uint16 *aspectArray, Direction dir, int16 mapX, int16 mapY); // @ F0172_DUNGEON_SetSquareAspect
-	void decodeText(char *destString, Thing thing, TextType type); // F0168_DUNGEON_DecodeText
+	void decodeText(char *destString, size_t maxSize, Thing thing, TextType type); // F0168_DUNGEON_DecodeText
 	Thing getUnusedThing(uint16 thingType); // @ F0166_DUNGEON_GetUnusedThing
 
 	uint16 getObjectWeight(Thing thing); // @ F0140_DUNGEON_GetObjectWeight
diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 486d87c53a7..a423a11c642 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -2755,7 +2755,7 @@ bool DisplayMan::isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex
 	unsigned char inscriptionString[70];
 	bool isInscription = (wallOrnamentIndex == dungeon._currMapInscriptionWallOrnIndex);
 	if (isInscription)
-		dungeon.decodeText((char *)inscriptionString, _inscriptionThing, kDMTextTypeInscription);
+		dungeon.decodeText((char *)inscriptionString, sizeof(inscriptionString), _inscriptionThing, kDMTextTypeInscription);
 
 	int16 blitPosX;
 	byte *ornBlitBitmap;
diff --git a/engines/dm/inventory.cpp b/engines/dm/inventory.cpp
index cefd766ae33..a1b3a6bd16d 100644
--- a/engines/dm/inventory.cpp
+++ b/engines/dm/inventory.cpp
@@ -316,7 +316,8 @@ void InventoryMan::drawPanelScroll(Scroll *scroll) {
 	DisplayMan &dispMan = *_vm->_displayMan;
 
 	char stringFirstLine[300];
-	_vm->_dungeonMan->decodeText(stringFirstLine, Thing(scroll->getTextStringThingIndex()), (TextType)(kDMTextTypeScroll | kDMMaskDecodeEvenIfInvisible));
+	_vm->_dungeonMan->decodeText(stringFirstLine, sizeof(stringFirstLine),
+			Thing(scroll->getTextStringThingIndex()), (TextType)(kDMTextTypeScroll | kDMMaskDecodeEvenIfInvisible));
 	char *charRed = stringFirstLine;
 	while (*charRed && (*charRed != '\n'))
 		charRed++;
@@ -414,27 +415,27 @@ void InventoryMan::buildObjectAttributeString(int16 potentialAttribMask, int16 a
 		return;
 	}
 
-	strcpy(destString, prefixString);
+	Common::strcpy_s(destString, 40, prefixString);
 
 	attribMask = 1;
 	for (uint16 stringIndex = 0; stringIndex < 16; stringIndex++, attribMask <<= 1) {
 		if (attribMask & potentialAttribMask & actualAttribMask) {
-			strcat(destString, attribStrings[stringIndex]);
+			Common::strcat_s(destString, 40, attribStrings[stringIndex]);
 			if (identicalBitCount-- > 2) {
-				strcat(destString, ", ");
+				Common::strcat_s(destString, 40, ", ");
 			} else if (identicalBitCount == 1) {
 
 				switch (_vm->getGameLanguage()) { // localized
 				default:
-				case Common::EN_ANY: strcat(destString, " AND "); break;
-				case Common::DE_DEU: strcat(destString, " UND "); break;
-				case Common::FR_FRA: strcat(destString, " ET "); break;
+				case Common::EN_ANY: Common::strcat_s(destString, 40, " AND "); break;
+				case Common::DE_DEU: Common::strcat_s(destString, 40, " UND "); break;
+				case Common::FR_FRA: Common::strcat_s(destString, 40, " ET "); break;
 				}
 			}
 		}
 	}
 
-	strcat(destString, suffixString);
+	Common::strcat_s(destString, 40, suffixString);
 }
 
 void InventoryMan::drawPanelObjectDescriptionString(const char *descString) {
@@ -446,7 +447,7 @@ void InventoryMan::drawPanelObjectDescriptionString(const char *descString) {
 
 	if (descString[0]) {
 		char stringTmpBuff[128];
-		strcpy(stringTmpBuff, descString);
+		Common::strcpy_s(stringTmpBuff, descString);
 
 		char *stringLine = stringTmpBuff;
 		bool severalLines = false;
diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp
index 7395b30dccf..8747273341b 100644
--- a/engines/dm/menus.cpp
+++ b/engines/dm/menus.cpp
@@ -1628,8 +1628,11 @@ void MenuMan::printMessageAfterReplacements(const char *str) {
 				replacementString = championMan._champions[_vm->ordinalToIndex(championMan._actingChampionOrdinal)]._name;
 
 			*curCharacter = '\0';
-			strcat(outputString, replacementString);
-			curCharacter += strlen(replacementString);
+			size_t ln = Common::strlcat(outputString, replacementString, sizeof(outputString));
+			if (ln >= sizeof(outputString)) {
+				error("Not enough space in outputString");
+			}
+			curCharacter = outputString + ln;
 			*curCharacter++ = ' ';
 		} else {
 			*curCharacter++ = *str;
diff --git a/engines/dm/movesens.cpp b/engines/dm/movesens.cpp
index db57f8f0629..6a2ddc3bc3c 100644
--- a/engines/dm/movesens.cpp
+++ b/engines/dm/movesens.cpp
@@ -736,7 +736,7 @@ void MovesensMan::processThingAdditionOrRemoval(uint16 mapX, uint16 mapY, Thing
 			if (curThingType == kDMThingTypeGroup)
 				squareContainsGroup = true;
 			else if ((curThingType == kDMstringTypeText) && (thingType == kDMThingTypeParty) && addThing && !partySquare) {
-				dungeon.decodeText(_vm->_stringBuildBuffer, curThing, kDMTextTypeMessage);
+				dungeon.decodeText(_vm->_stringBuildBuffer, sizeof(_vm->_stringBuildBuffer), curThing, kDMTextTypeMessage);
 				txtMan.printMessage(kDMColorWhite, _vm->_stringBuildBuffer);
 			} else if ((curThingType > kDMThingTypeGroup) && (curThingType < kDMThingTypeProjectile)) {
 				squareContainsObject = true;
diff --git a/engines/dm/timeline.cpp b/engines/dm/timeline.cpp
index 076b08a0dbb..42cc84dea34 100644
--- a/engines/dm/timeline.cpp
+++ b/engines/dm/timeline.cpp
@@ -720,7 +720,7 @@ void Timeline::processEventSquareCorridor(TimelineEvent *event) {
 				textString->setVisible((event->_Cu.A._effect == kDMSensorEffectSet));
 
 			if (!textCurrentlyVisible && textString->isVisible() && (_vm->_dungeonMan->_currMapIndex == _vm->_dungeonMan->_partyMapIndex) && (mapX == _vm->_dungeonMan->_partyMapX) && (mapY == _vm->_dungeonMan->_partyMapY)) {
-				_vm->_dungeonMan->decodeText(_vm->_stringBuildBuffer, curThing, kDMTextTypeMessage);
+				_vm->_dungeonMan->decodeText(_vm->_stringBuildBuffer, sizeof(_vm->_stringBuildBuffer), curThing, kDMTextTypeMessage);
 				_vm->_textMan->printMessage(kDMColorWhite, _vm->_stringBuildBuffer);
 			}
 		} else if (curThingType == kDMThingTypeSensor) {


Commit: b25335bd33199056b48ff8a7cba3485406963cb0
    https://github.com/scummvm/scummvm/commit/b25335bd33199056b48ff8a7cba3485406963cb0
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
DRASCULA: Don't use unsafe strcat and strcpy

Changed paths:
    engines/drascula/animation.cpp
    engines/drascula/converse.cpp
    engines/drascula/graphics.cpp
    engines/drascula/interface.cpp
    engines/drascula/objects.cpp
    engines/drascula/rooms.cpp


diff --git a/engines/drascula/animation.cpp b/engines/drascula/animation.cpp
index 3d301f5a025..67998babea7 100644
--- a/engines/drascula/animation.cpp
+++ b/engines/drascula/animation.cpp
@@ -763,7 +763,7 @@ void DrasculaEngine::animation_16_2() {
 		if (i < 4)
 			sprintf(curPic, "his%i.alg", i);
 		else
-			strcpy(curPic, "his4_2.alg");
+			Common::strcpy_s(curPic, "his4_2.alg");
 
 		loadPic(curPic, screenSurface, HALF_PAL);
 		centerText(_texthis[i], 180, 180);
@@ -2079,7 +2079,7 @@ void DrasculaEngine::animation_1_4() {
 	debug(4, "animation_1_4()");
 
 	if (flags[21] == 0) {
-		strcpy(objName[2], _textmisc[5]); // "igor"
+		Common::strcpy_s(objName[2], _textmisc[5]); // "igor"
 		talk(275);
 
 		updateRefresh_pre();
diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp
index 2261547bf1c..016b5e05f15 100644
--- a/engines/drascula/converse.cpp
+++ b/engines/drascula/converse.cpp
@@ -168,19 +168,19 @@ void DrasculaEngine::converse(int index) {
 
 	if (currentChapter == 2 && !strcmp(fileName, "op_5.cal") && flags[38] == 1 && flags[33] == 1) {
 		Common::strlcpy(phrase3, _text[405], 128);
-		strcpy(sound3, "405.als");
+		Common::strcpy_s(sound3, "405.als");
 		answer3 = 31;
 	}
 
 	if (currentChapter == 6 && !strcmp(fileName, "op_12.cal") && flags[7] == 1) {
 		Common::strlcpy(phrase3, _text[273], 128);
-		strcpy(sound3, "273.als");
+		Common::strcpy_s(sound3, "273.als");
 		answer3 = 14;
 	}
 
 	if (currentChapter == 6 && !strcmp(fileName, "op_12.cal") && flags[10] == 1) {
 		Common::strlcpy(phrase3, _text[274], 128);
-		strcpy(sound3, "274.als");
+		Common::strcpy_s(sound3, "274.als");
 		answer3 = 15;
 	}
 
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index 5e6bc321c49..3c90ceb9c64 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -406,7 +406,7 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) {
 		Common::strlcat(tmpMessageCurLine, curWord, 50);
 		if (textFitsCentered(tmpMessageCurLine, textX)) {
 			// Line fits, so add the word to the current message line
-			strcpy(messageCurLine, tmpMessageCurLine);
+			Common::strcpy_s(messageCurLine, tmpMessageCurLine);
 		} else {
 			// Line does't fit. Store the current line and start a new line.
 			Common::strlcpy(messageLines[curLine++], messageCurLine, 41);
@@ -424,7 +424,7 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) {
 			if (!textFitsCentered(messageCurLine, textX)) {
 				messageCurLine[strlen(messageCurLine) - 1] = '\0';
 				Common::strlcpy(messageLines[curLine++], messageCurLine, 41);
-				strcpy(messageLines[curLine++], " ");
+				Common::strcpy_s(messageLines[curLine++], " ");
 			} else
 				Common::strlcpy(messageLines[curLine++], messageCurLine, 41);
 		}
diff --git a/engines/drascula/interface.cpp b/engines/drascula/interface.cpp
index a49e83a0307..73b8a4d6233 100644
--- a/engines/drascula/interface.cpp
+++ b/engines/drascula/interface.cpp
@@ -165,7 +165,7 @@ void DrasculaEngine::showMap() {
 
 	for (int l = 0; l < numRoomObjs; l++) {
 		if (_objectRect[l].contains(Common::Point(_mouseX, _mouseY)) && visible[l] == 1) {
-			strcpy(textName, objName[l]);
+			Common::strcpy_s(textName, objName[l]);
 			_hasName = true;
 		}
 	}
diff --git a/engines/drascula/objects.cpp b/engines/drascula/objects.cpp
index c5f5cfcf393..4d31698c117 100644
--- a/engines/drascula/objects.cpp
+++ b/engines/drascula/objects.cpp
@@ -102,7 +102,7 @@ void DrasculaEngine::checkObjects() {
 
 	for (l = 0; l < numRoomObjs; l++) {
 		if (_objectRect[l].contains(Common::Point(_mouseX, _mouseY)) && visible[l] == 1 && isDoor[l] == 0) {
-			strcpy(textName, objName[l]);
+			Common::strcpy_s(textName, objName[l]);
 			_hasName = true;
 		}
 	}
@@ -110,7 +110,7 @@ void DrasculaEngine::checkObjects() {
 	if (_mouseX > curX + 2 && _mouseY > curY + 2
 			&& _mouseX < curX + curWidth - 2 && _mouseY < curY + curHeight - 2) {
 		if (currentChapter == 2 || !_hasName) {
-			strcpy(textName, _textmisc[3]); // "hacker"
+			Common::strcpy_s(textName, _textmisc[3]); // "hacker"
 			_hasName = true;
 		}
 	}
diff --git a/engines/drascula/rooms.cpp b/engines/drascula/rooms.cpp
index fe5404152de..32415202d25 100644
--- a/engines/drascula/rooms.cpp
+++ b/engines/drascula/rooms.cpp
@@ -403,7 +403,7 @@ bool DrasculaEngine::room_13(int fl) {
 		talk(411);
 		trackProtagonist = 3;
 		talk(412);
-		strcpy(objName[1], _textmisc[4]); // "yoda"
+		Common::strcpy_s(objName[1], _textmisc[4]); // "yoda"
 	} else if (pickedObject == kVerbTalk && fl == 51) {
 		converse(7);
 	} else if (pickedObject == 19 && fl == 51) {
@@ -1671,7 +1671,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
 
 	_hasName = false;
 
-	strcpy(currentData, fileName);
+	Common::strcpy_s(currentData, fileName);
 
 	Common::SeekableReadStream *stream = _archives.open(fileName);
 	if (!stream)
@@ -1706,7 +1706,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
 			p.parseString(surfaceName);
 			loadPic(surfaceName, backSurface);
 
-			strcpy(menuBackground, surfaceName);
+			Common::strcpy_s(menuBackground, surfaceName);
 		} else {
 			curWidth = CHARACTER_WIDTH;
 			curHeight = CHARACTER_HEIGHT;
@@ -1718,7 +1718,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
 			loadPic(96, frontSurface);
 			loadPic(99, backSurface);
 
-			strcpy(menuBackground, "99.alg");
+			Common::strcpy_s(menuBackground, "99.alg");
 		}
 	}
 


Commit: 93cdbbbf3911cfdd2de9107d7c02f0a829576b98
    https://github.com/scummvm/scummvm/commit/93cdbbbf3911cfdd2de9107d7c02f0a829576b98
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GLK: Don't use unsafe strcat and strcpy

Changed paths:
    engines/glk/adrift/os_glk.cpp
    engines/glk/adrift/scexpr.cpp
    engines/glk/adrift/scgamest.cpp
    engines/glk/adrift/scmemos.cpp
    engines/glk/adrift/scparser.cpp
    engines/glk/adrift/scprintf.cpp
    engines/glk/adrift/scprops.cpp
    engines/glk/adrift/scresour.cpp
    engines/glk/adrift/scrunner.cpp
    engines/glk/adrift/sctafpar.cpp
    engines/glk/adrift/sctasks.cpp
    engines/glk/adrift/scvars.cpp
    engines/glk/agt/agtread.cpp
    engines/glk/agt/exec.cpp
    engines/glk/agt/gamedata.cpp
    engines/glk/agt/object.cpp
    engines/glk/agt/os_glk.cpp
    engines/glk/alan2/debug.cpp
    engines/glk/alan2/exe.cpp
    engines/glk/alan2/glkio.cpp
    engines/glk/alan2/glkio.h
    engines/glk/alan2/main.cpp
    engines/glk/alan2/parse.cpp
    engines/glk/alan2/sysdep.cpp
    engines/glk/alan2/sysdep.h
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/glkio.cpp
    engines/glk/alan3/main.cpp
    engines/glk/alan3/scan.cpp
    engines/glk/alan3/sysdep.cpp
    engines/glk/alan3/sysdep.h
    engines/glk/comprehend/game_oo.cpp
    engines/glk/comprehend/game_tm.cpp
    engines/glk/hugo/hemisc.cpp
    engines/glk/hugo/heparse.cpp
    engines/glk/hugo/heres.cpp
    engines/glk/hugo/herun.cpp
    engines/glk/hugo/heset.cpp
    engines/glk/hugo/hugo.cpp
    engines/glk/hugo/stringfn.cpp
    engines/glk/jacl/display.cpp
    engines/glk/jacl/interpreter.cpp
    engines/glk/jacl/jacl_main.cpp
    engines/glk/jacl/jpp.cpp
    engines/glk/jacl/loader.cpp
    engines/glk/jacl/parser.cpp
    engines/glk/jacl/prototypes.h
    engines/glk/jacl/resolvers.cpp
    engines/glk/jacl/utils.cpp
    engines/glk/level9/level9_main.cpp
    engines/glk/level9/os_glk.cpp
    engines/glk/magnetic/glk.cpp
    engines/glk/scott/c64_checksums.cpp
    engines/glk/scott/scott.cpp
    engines/glk/scott/unp64/unp64.cpp
    engines/glk/tads/os_frob_tads.cpp
    engines/glk/tads/os_glk.cpp
    engines/glk/tads/tads2/built_in.cpp
    engines/glk/tads/tads2/character_map.cpp
    engines/glk/tads/tads2/execute_command.cpp
    engines/glk/tads/tads2/file_io.cpp
    engines/glk/tads/tads2/line_source_file.cpp
    engines/glk/tads/tads2/memory_cache_swap.cpp
    engines/glk/tads/tads2/output.cpp
    engines/glk/tads/tads2/play.cpp
    engines/glk/tads/tads2/runtime_driver.cpp
    engines/glk/tads/tads2/tads2.cpp
    engines/glk/tads/tads2/vocabulary.h
    engines/glk/tads/tads2/vocabulary_parser.cpp
    engines/glk/zcode/detection.cpp


diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index d38258b5b2b..599f401c435 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -921,7 +921,7 @@ static void gsc_status_print() {
 		char score[64];
 
 		/* Make an attempt at a status line, starting with player location. */
-		strcpy(buffer, "");
+		buffer[0] = '\0';
 		gsc_status_safe_strcat(buffer, sizeof(buffer), room);
 
 		/* Get the game's status line, or if none, format score. */
@@ -943,7 +943,7 @@ static void gsc_status_print() {
 			g_vm->glk_put_string(" ]\n");
 
 			/* Save the details of the printed status buffer. */
-			strcpy(current_status, buffer);
+			Common::strcpy_s(current_status, buffer);
 		}
 	}
 }
@@ -1147,8 +1147,9 @@ static void gsc_handle_font_tag(const sc_char *argument) {
 		}
 
 		/* Copy and convert argument to all lowercase. */
-		lower = (sc_char *)gsc_malloc(strlen(argument) + 1);
-		strcpy(lower, argument);
+		size_t ln = strlen(argument) + 1;
+		lower = (sc_char *)gsc_malloc(ln);
+		Common::strcpy_s(lower, ln, argument);
 		for (index_ = 0; lower[index_] != '\0'; index_++)
 			lower[index_] = g_vm->glk_char_to_lower(lower[index_]);
 
@@ -2192,8 +2193,9 @@ static int gsc_command_escape(const char *string) {
 		return FALSE;
 
 	/* Take a copy of the string, without any leading space or introducer. */
-	string_copy = (char *)gsc_malloc(strlen(string + posn) + 1 - strlen("glk"));
-	strcpy(string_copy, string + posn + strlen("glk"));
+	size_t ln = strlen(string + posn) + 1 - 3 /*strlen("glk")*/;
+	string_copy = (char *)gsc_malloc(ln);
+	Common::strcpy_s(string_copy, ln, string + posn + 3 /* strlen("glk") */);
 
 	/*
 	 * Find the subcommand; the first word in the string copy.  Find its end,
diff --git a/engines/glk/adrift/scexpr.cpp b/engines/glk/adrift/scexpr.cpp
index 36c8c9fd5cd..3f037858025 100644
--- a/engines/glk/adrift/scexpr.cpp
+++ b/engines/glk/adrift/scexpr.cpp
@@ -480,8 +480,9 @@ static void expr_eval_push_string(const sc_char *value) {
 		sc_fatal("expr_eval_push_string: stack overflow\n");
 
 	/* Push a copy of value. */
-	value_copy = (sc_char *)sc_malloc(strlen(value) + 1);
-	strcpy(value_copy, value);
+	size_t ln = strlen(value) + 1;
+	value_copy = (sc_char *)sc_malloc(ln);
+	Common::strcpy_s(value_copy, ln, value);
 	expr_eval_stack[expr_eval_stack_index].is_collectible = TRUE;
 	expr_eval_stack[expr_eval_stack_index++].value.mutable_string = value_copy;
 }
@@ -1023,8 +1024,9 @@ static void expr_eval_action(CONTEXT, sc_int token) {
 		 * Resize text1 to be long enough for both, and concatenate, then
 		 * free text2, and push back the concatenation.
 		 */
-		text1 = (sc_char *)sc_realloc(text1, strlen(text1) + strlen(text2) + 1);
-		strcat(text1, text2);
+		size_t ln = strlen(text1) + strlen(text2) + 1;
+		text1 = (sc_char *)sc_realloc(text1, ln);
+		Common::strcat_s(text1, ln, text2);
 		sc_free(text2);
 		expr_eval_push_alloced_string(text1);
 		break;
diff --git a/engines/glk/adrift/scgamest.cpp b/engines/glk/adrift/scgamest.cpp
index 9a79a751b40..679638c551b 100644
--- a/engines/glk/adrift/scgamest.cpp
+++ b/engines/glk/adrift/scgamest.cpp
@@ -812,8 +812,9 @@ static void gs_string_copy(sc_char **to_string, const sc_char *from_string) {
 
 	/* Copy from_string if set, otherwise set to_string to NULL. */
 	if (from_string) {
-		*to_string = (sc_char *)sc_malloc(strlen(from_string) + 1);
-		strcpy(*to_string, from_string);
+		size_t ln = strlen(from_string) + 1;
+		*to_string = (sc_char *)sc_malloc(ln);
+		Common::strcpy_s(*to_string, ln, from_string);
 	} else
 		*to_string = nullptr;
 }
diff --git a/engines/glk/adrift/scmemos.cpp b/engines/glk/adrift/scmemos.cpp
index d366b71b365..ad03f2255b3 100644
--- a/engines/glk/adrift/scmemos.cpp
+++ b/engines/glk/adrift/scmemos.cpp
@@ -363,7 +363,7 @@ void memo_save_command(sc_memo_setref_t memento, const sc_char *command, sc_int
 	}
 
 	/* Save the string into this slot, and normalize it for neatness. */
-	strcpy(history->command, command);
+	Common::strcpy_s(history->command, history->allocation, command);
 	sc_normalize_string(history->command);
 	history->sequence = memento->history_count + 1;
 	history->timestamp = timestamp;
diff --git a/engines/glk/adrift/scparser.cpp b/engines/glk/adrift/scparser.cpp
index ea5aeb51648..f9670e7b6b3 100644
--- a/engines/glk/adrift/scparser.cpp
+++ b/engines/glk/adrift/scparser.cpp
@@ -328,7 +328,7 @@ static sc_char *uip_new_word(const sc_char *word) {
 
 		/* Use the slot and update the pool cursor and free count. */
 		shortword = uip_word_pool + index_;
-		strcpy(shortword->word, word);
+		Common::strcpy_s(shortword->word, word);
 		shortword->is_in_use = TRUE;
 
 		uip_word_pool_cursor = index_;
@@ -341,7 +341,7 @@ static sc_char *uip_new_word(const sc_char *word) {
 
 		/* Fall back to less efficient allocations. */
 		word_copy = (sc_char *)sc_malloc(required);
-		strcpy(word_copy, word);
+		Common::strcpy_s(word_copy, required, word);
 		return word_copy;
 	}
 }
@@ -1580,7 +1580,7 @@ static sc_char *uip_cleanse_string(const sc_char *original, sc_char *buffer, sc_
 	 */
 	required = strlen(original) + 1;
 	string = (required < length) ? buffer : (sc_char *)sc_malloc(required);
-	strcpy(string, original);
+	Common::strcpy_s(string, required, original);
 
 	/* Trim, and return the string. */
 	sc_trim_string(string);
@@ -1758,7 +1758,7 @@ sc_char *uip_replace_pronouns(sc_gameref_t game, const sc_char *string) {
 			if (!buffer) {
 				buffer_allocation = strlen(string) + 1;
 				buffer = (sc_char *)sc_malloc(buffer_allocation);
-				strcpy(buffer, string);
+				Common::strcpy_s(buffer, buffer_allocation, string);
 				current = buffer + (current - string);
 			}
 
diff --git a/engines/glk/adrift/scprintf.cpp b/engines/glk/adrift/scprintf.cpp
index b393d94e9f0..d7a4027606f 100644
--- a/engines/glk/adrift/scprintf.cpp
+++ b/engines/glk/adrift/scprintf.cpp
@@ -238,17 +238,18 @@ static sc_char *pf_interpolate_vars(const sc_char *string, sc_var_setref_t vars)
 			sc_char value[32];
 
 			sprintf(value, "%ld", vt_rvalue.integer);
-			buffer = (sc_char *)sc_realloc(buffer, strlen(buffer) + strlen(value) + 1);
-			strcat(buffer, value);
+			size_t ln = strlen(buffer) + strlen(value) + 1;
+			buffer = (sc_char *)sc_realloc(buffer, ln);
+			Common::strcat_s(buffer, ln, value);
 			break;
 		}
 
-		case VAR_STRING:
-			buffer = (sc_char *)sc_realloc(buffer,
-			                               strlen(buffer) + strlen(vt_rvalue.string) + 1);
-			strcat(buffer, vt_rvalue.string);
+		case VAR_STRING: {
+			size_t ln = strlen(buffer) + strlen(vt_rvalue.string) + 1;
+			buffer = (sc_char *)sc_realloc(buffer, ln);
+			Common::strcat_s(buffer, ln, vt_rvalue.string);
 			break;
-
+		}
 		default:
 			sc_fatal("pf_interpolate_vars: invalid variable type, %ld\n", type);
 		}
@@ -266,8 +267,9 @@ static sc_char *pf_interpolate_vars(const sc_char *string, sc_var_setref_t vars)
 	 */
 	if (buffer) {
 		if (is_interpolated) {
-			buffer = (sc_char *)sc_realloc(buffer, strlen(buffer) + strlen(marker) + 1);
-			strcat(buffer, marker);
+			size_t ln = strlen(buffer) + strlen(marker) + 1;
+			buffer = (sc_char *)sc_realloc(buffer, ln);
+			Common::strcat_s(buffer, ln, marker);
 		} else {
 			sc_free(buffer);
 			buffer = nullptr;
@@ -318,15 +320,16 @@ static sc_bool pf_replace_alr(const sc_char *string, sc_char **buffer, sc_int al
 		 * copy; else append to the existing buffer: basic copy-on-write.
 		 */
 		if (!buffer_) {
-			buffer_ = (sc_char *)sc_malloc(cursor - marker + strlen(replacement) + 1);
+			size_t ln = cursor - marker + strlen(replacement) + 1;
+			buffer_ = (sc_char *)sc_malloc(ln);
 			memcpy(buffer_, marker, cursor - marker);
 			buffer_[cursor - marker] = NUL;
-			strcat(buffer_, replacement);
+			Common::strcat_s(buffer_, ln, replacement);
 		} else {
-			buffer_ = (sc_char *)sc_realloc(buffer_, strlen(buffer_) +
-			                                cursor - marker + strlen(replacement) + 1);
+			size_t ln = strlen(buffer_) + cursor - marker + strlen(replacement) + 1;
+			buffer_ = (sc_char *)sc_realloc(buffer_, ln);
 			strncat(buffer_, marker, cursor - marker);
-			strcat(buffer_, replacement);
+			Common::strcat_s(buffer_, ln, replacement);
 		}
 
 		/* Advance over the original. */
@@ -335,8 +338,9 @@ static sc_bool pf_replace_alr(const sc_char *string, sc_char **buffer, sc_int al
 
 	/* If any pending text, append it to the buffer. */
 	if (replacement) {
-		buffer_ = (sc_char *)sc_realloc(buffer_, strlen(buffer_) + strlen(marker) + 1);
-		strcat(buffer_, marker);
+		size_t ln = strlen(buffer_) + strlen(marker) + 1;
+		buffer_ = (sc_char *)sc_realloc(buffer_, ln);
+		Common::strcat_s(buffer_, ln, marker);
 	}
 
 	/* Write back buffer, and if replacement set, the buffer was altered. */
@@ -739,8 +743,9 @@ sc_char *pf_filter(const sc_char *string, sc_var_setref_t vars, sc_prop_setref_t
 
 	/* Our contract is to return an allocated string; copy if required. */
 	if (!current) {
-		current = (sc_char *)sc_malloc(strlen(string) + 1);
-		strcpy(current, string);
+		size_t ln = strlen(string) + 1;
+		current = (sc_char *)sc_malloc(ln);
+		Common::strcpy_s(current, ln, string);
 	}
 
 	return current;
@@ -763,8 +768,9 @@ sc_char *pf_filter_for_info(const sc_char *string, sc_var_setref_t vars) {
 
 	/* Our contract is to return an allocated string; copy if required. */
 	if (!current) {
-		current = (sc_char *)sc_malloc(strlen(string) + 1);
-		strcpy(current, string);
+		size_t ln = strlen(string) + 1;
+		current = (sc_char *)sc_malloc(ln);
+		Common::strcpy_s(current, ln, string);
 	}
 
 	return current;
@@ -845,7 +851,7 @@ static void pf_append_string(sc_filterref_t filter, const sc_char *string) {
 		filter->buffer[0] = NUL;
 
 	/* Append the string to the buffer and extend length. */
-	strcat(filter->buffer, string);
+	Common::strcat_s(filter->buffer, filter->buffer_allocation, string);
 	filter->buffer_length += length;
 }
 
@@ -1020,7 +1026,7 @@ void pf_prepend_string(sc_filterref_t filter, const sc_char *string) {
 			/* Take a copy of the current buffered string. */
 			assert(filter->buffer[filter->buffer_length] == NUL);
 			copy = (sc_char *)sc_malloc(filter->buffer_length + 1);
-			strcpy(copy, filter->buffer);
+			Common::strcpy_s(copy, filter->buffer_length + 1, filter->buffer);
 
 			/*
 			 * Now restart buffering with the input string passed in.  Removing
@@ -1218,8 +1224,9 @@ sc_char *pf_escape(const sc_char *string) {
 			escape = escape_buffer;
 		}
 
-		buffer = (sc_char *)sc_realloc(buffer, strlen(buffer) + strlen(escape) + 1);
-		strcat(buffer, escape);
+		size_t ln = strlen(buffer) + strlen(escape) + 1;
+		buffer = (sc_char *)sc_realloc(buffer, ln);
+		Common::strcat_s(buffer, ln, escape);
 
 		/* Pass over character escaped and continue. */
 		cursor++;
@@ -1354,7 +1361,7 @@ sc_char *pf_filter_input(const sc_char *string, sc_prop_setref_t bundle) {
 			if (!buffer) {
 				buffer_allocation = strlen(string) + 1;
 				buffer = (sc_char *)sc_malloc(buffer_allocation);
-				strcpy(buffer, string);
+				Common::strcpy_s(buffer, buffer_allocation, string);
 				current = buffer + (current - string);
 			}
 
diff --git a/engines/glk/adrift/scprops.cpp b/engines/glk/adrift/scprops.cpp
index f39371969dc..2f28f682e70 100644
--- a/engines/glk/adrift/scprops.cpp
+++ b/engines/glk/adrift/scprops.cpp
@@ -187,8 +187,9 @@ static const sc_char *prop_dictionary_lookup(sc_prop_setref_t bundle, const sc_c
 	}
 
 	/* Not found, so copy the string for dictionary insertion. */
-	dict_string = (sc_char *)sc_malloc(strlen(string) + 1);
-	strcpy(dict_string, string);
+	size_t ln = strlen(string) + 1;
+	dict_string = (sc_char *)sc_malloc(ln);
+	Common::strcpy_s(dict_string, ln, string);
 
 	/* Extend the dictionary if necessary. */
 	bundle->dictionary = (sc_char **)prop_ensure_capacity(bundle->dictionary,
diff --git a/engines/glk/adrift/scresour.cpp b/engines/glk/adrift/scresour.cpp
index 8b3a65f0c57..6f7388123a5 100644
--- a/engines/glk/adrift/scresour.cpp
+++ b/engines/glk/adrift/scresour.cpp
@@ -149,9 +149,9 @@ void res_handle_resource(sc_gameref_t game, const sc_char *partial_format,
 
 		/* Get soundfile property from the node supplied. */
 		vt_full[partial_length].string = "SoundFile";
-		strcpy(format, "S<-");
-		strcat(format, partial_format);
-		strcat(format, "s");
+		Common::strcpy_s(format, partial_length + 5, "S<-");
+		Common::strcat_s(format, partial_length + 5, partial_format);
+		Common::strcat_s(format, partial_length + 5, "s");
 		soundfile = prop_get_string(bundle, format, vt_full);
 
 		/* If a sound is defined, handle it. */
@@ -159,16 +159,16 @@ void res_handle_resource(sc_gameref_t game, const sc_char *partial_format,
 			if (embedded) {
 				/* Retrieve offset and length. */
 				vt_full[partial_length].string = "SoundOffset";
-				strcpy(format, "I<-");
-				strcat(format, partial_format);
-				strcat(format, "s");
+				Common::strcpy_s(format, partial_length + 5, "I<-");
+				Common::strcat_s(format, partial_length + 5, partial_format);
+				Common::strcat_s(format, partial_length + 5, "s");
 				soundoffset = prop_get_integer(bundle, format, vt_full)
 				              + resource_start_offset;
 
 				vt_full[partial_length].string = "SoundLen";
-				strcpy(format, "I<-");
-				strcat(format, partial_format);
-				strcat(format, "s");
+				Common::strcpy_s(format, partial_length + 5, "I<-");
+				Common::strcat_s(format, partial_length + 5, partial_format);
+				Common::strcat_s(format, partial_length + 5, "s");
 				soundlen = prop_get_integer(bundle, format, vt_full);
 			} else {
 				/* Coerce offset and length to zero. */
@@ -197,9 +197,9 @@ void res_handle_resource(sc_gameref_t game, const sc_char *partial_format,
 
 		/* Get graphicfile property from the node supplied. */
 		vt_full[partial_length].string = "GraphicFile";
-		strcpy(format, "S<-");
-		strcat(format, partial_format);
-		strcat(format, "s");
+		Common::strcpy_s(format, partial_length + 5, "S<-");
+		Common::strcat_s(format, partial_length + 5, partial_format);
+		Common::strcat_s(format, partial_length + 5, "s");
 		graphicfile = prop_get_string(bundle, format, vt_full);
 
 		/* If a graphic is defined, handle it. */
@@ -207,16 +207,16 @@ void res_handle_resource(sc_gameref_t game, const sc_char *partial_format,
 			if (embedded) {
 				/* Retrieve offset and length. */
 				vt_full[partial_length].string = "GraphicOffset";
-				strcpy(format, "I<-");
-				strcat(format, partial_format);
-				strcat(format, "s");
+				Common::strcpy_s(format, partial_length + 5, "I<-");
+				Common::strcat_s(format, partial_length + 5, partial_format);
+				Common::strcat_s(format, partial_length + 5, "s");
 				graphicoffset = prop_get_integer(bundle, format, vt_full)
 				                + resource_start_offset;
 
 				vt_full[partial_length].string = "GraphicLen";
-				strcpy(format, "I<-");
-				strcat(format, partial_format);
-				strcat(format, "s");
+				Common::strcpy_s(format, partial_length + 5, "I<-");
+				Common::strcat_s(format, partial_length + 5, partial_format);
+				Common::strcat_s(format, partial_length + 5, "s");
 				graphiclen = prop_get_integer(bundle, format, vt_full);
 			} else {
 				/* Coerce offset and length to zero. */
@@ -267,8 +267,9 @@ void res_sync_resources(sc_gameref_t game) {
 		name = game->requested_sound.name;
 		is_looping = !strcmp(name + strlen(name) - 2, "##");
 
-		clean_name = (sc_char *)sc_malloc(strlen(name) + 1);
-		strcpy(clean_name, name);
+		size_t ln = strlen(name) + 1;
+		clean_name = (sc_char *)sc_malloc(ln);
+		Common::strcpy_s(clean_name, ln, name);
 		if (is_looping)
 			clean_name[strlen(clean_name) - 2] = NUL;
 
diff --git a/engines/glk/adrift/scrunner.cpp b/engines/glk/adrift/scrunner.cpp
index 607b63acd48..c919b484203 100644
--- a/engines/glk/adrift/scrunner.cpp
+++ b/engines/glk/adrift/scrunner.cpp
@@ -1054,7 +1054,7 @@ static sc_bool run_player_input(sc_gameref_t game) {
 		}
 
 		/* Make the last element the current input element. */
-		strcpy(line_element, prior_element);
+		Common::strcpy_s(line_element, prior_element);
 	} else {
 		sc_int length, extent;
 
@@ -1205,7 +1205,7 @@ static sc_bool run_player_input(sc_gameref_t game) {
 		 * up as do_again set in the game, where it wasn't when we entered here.
 		 */
 		if (!game->do_again && !is_rerunning)
-			strcpy(prior_element, line_element);
+			Common::strcpy_s(prior_element, line_element);
 
 		/*
 		 * If this was a request to run a command from the history, copy that
@@ -1218,7 +1218,7 @@ static sc_bool run_player_input(sc_gameref_t game) {
 
 			redo_command = memo_find_command(memento, game->redo_sequence);
 			if (redo_command)
-				strcpy(prior_element, redo_command);
+				Common::strcpy_s(prior_element, redo_command);
 			else {
 				sc_error("run_player_input: invalid redo sequence request\n");
 				game->do_again = FALSE;
diff --git a/engines/glk/adrift/sctafpar.cpp b/engines/glk/adrift/sctafpar.cpp
index 7aa01502016..517ae8bef9e 100644
--- a/engines/glk/adrift/sctafpar.cpp
+++ b/engines/glk/adrift/sctafpar.cpp
@@ -1033,16 +1033,17 @@ static sc_char *parse_read_multiline(CONTEXT) {
 
 	/* Take a simple copy of the first line. */
 	R0FUNC0(parse_get_taf_string, line);
-	multiline = (sc_char *)sc_malloc(strlen(line) + 1);
-	strcpy(multiline, line);
+	size_t ln = strlen(line) + 1;
+	multiline = (sc_char *)sc_malloc(ln);
+	Common::strcpy_s(multiline, ln, line);
 
 	/* Now concatenate until separator found. */
 	R0FUNC0(parse_get_taf_string, line);
 	while (memcmp(line, separator, SEPARATOR_SIZE) != 0) {
-		multiline = (sc_char *)sc_realloc(multiline,
-		                                  strlen(multiline) + strlen(line) + 2);
-		strcat(multiline, "\n");
-		strcat(multiline, line);
+		ln = strlen(multiline) + strlen(line) + 2;
+		multiline = (sc_char *)sc_realloc(multiline, ln);
+		Common::strcat_s(multiline, ln, "\n");
+		Common::strcat_s(multiline, ln, line);
 		R0FUNC0(parse_get_taf_string, line);
 	}
 
@@ -1188,8 +1189,9 @@ static sc_int parse_get_v400_resource_offset(const sc_char *name,
 	 * Take a copy of the name, and remove any trailing "##" looping sound
 	 * indicator flag.  Who thinks this junk up?
 	 */
-	clean_name = (sc_char *)sc_malloc(strlen(name) + 1);
-	strcpy(clean_name, name);
+	size_t ln = strlen(name) + 1;
+	clean_name = (sc_char *)sc_malloc(ln);
+	Common::strcpy_s(clean_name, ln, name);
 	if (strcmp(clean_name + strlen(clean_name) - 2, "##") == 0)
 		clean_name[strlen(clean_name) - 2] = NUL;
 
@@ -2006,10 +2008,11 @@ static void parse_fixup_v390(CONTEXT, const sc_char *fixup) {
 			sc_char *restrmask;
 			sc_int index_;
 
-			restrmask = (sc_char *)sc_malloc(2 * restriction_count);
-			strcpy(restrmask, "#");
+			size_t ln = 2 * restriction_count;
+			restrmask = (sc_char *)sc_malloc(ln);
+			Common::strcpy_s(restrmask, ln, "#");
 			for (index_ = 1; index_ < restriction_count; index_++)
-				strcat(restrmask, "A#");
+				Common::strcat_s(restrmask, ln, "A#");
 
 			vt_key.string = "RestrMask";
 			parse_push_key(vt_key, PROP_KEY_STRING);
@@ -2754,10 +2757,11 @@ static void parse_fixup_v380(const sc_char *fixup) {
 			sc_char *restrmask;
 			sc_int index_;
 
-			restrmask = (sc_char *)sc_malloc(2 * restriction_count);
-			strcpy(restrmask, "#");
+			size_t ln = 2 * restriction_count;
+			restrmask = (sc_char *)sc_malloc(ln);
+			Common::strcpy_s(restrmask, ln, "#");
 			for (index_ = 1; index_ < restriction_count; index_++)
-				strcat(restrmask, "A#");
+				Common::strcat_s(restrmask, ln, "A#");
 
 			vt_key.string = "RestrMask";
 			parse_push_key(vt_key, PROP_KEY_STRING);
diff --git a/engines/glk/adrift/sctasks.cpp b/engines/glk/adrift/sctasks.cpp
index f44f1ac7c7e..ff616ab4ffd 100644
--- a/engines/glk/adrift/sctasks.cpp
+++ b/engines/glk/adrift/sctasks.cpp
@@ -670,8 +670,9 @@ static void task_run_change_variable_action(sc_gameref_t game,
 			if (!expr_eval_string_expression(expr, vars, &mutable_string)) {
 				sc_error("task_run_change_variable_action:"
 				         " invalid string expression, %s\n", expr);
-				mutable_string = (sc_char *)sc_malloc(strlen("[expr error]") + 1);
-				strcpy(mutable_string, "[expr error]");
+				size_t ln = strlen("[expr error]") + 1;
+				mutable_string = (sc_char *)sc_malloc(ln);
+				Common::strcpy_s(mutable_string, ln, "[expr error]");
 			}
 			if (task_trace) {
 				sc_trace("Task: variable %ld (%s) = %s, %s\n",
diff --git a/engines/glk/adrift/scvars.cpp b/engines/glk/adrift/scvars.cpp
index 01dcfe8a5c7..17800839d52 100644
--- a/engines/glk/adrift/scvars.cpp
+++ b/engines/glk/adrift/scvars.cpp
@@ -305,12 +305,13 @@ void var_put(sc_var_setref_t vars, const sc_char *name, sc_int type, sc_vartype_
 		var->value.integer = vt_value.integer;
 		break;
 
-	case VAR_STRING:
+	case VAR_STRING: {
+		size_t ln = strlen(vt_value.string) + 1;
 		/* Use mutable string instead of const string. */
-		var->value.mutable_string = (sc_char *)sc_realloc(var->value.mutable_string,
-		                            strlen(vt_value.string) + 1);
-		strcpy(var->value.mutable_string, vt_value.string);
+		var->value.mutable_string = (sc_char *)sc_realloc(var->value.mutable_string, ln);
+		Common::strcpy_s(var->value.mutable_string, ln, vt_value.string);
 		break;
+	}
 
 	default:
 		sc_fatal("var_put: invalid variable type, %ld\n", var->type);
@@ -350,16 +351,16 @@ static void var_append_temp(sc_var_setref_t vars, const sc_char *string) {
 		/* Create a new temporary area and copy string. */
 		new_sentence = TRUE;
 		noted = 0;
-		vars->temporary = (sc_char *)sc_malloc(strlen(string) + 1);
-		strcpy(vars->temporary, string);
+		size_t ln = strlen(string) + 1;
+		vars->temporary = (sc_char *)sc_malloc(ln);
+		Common::strcpy_s(vars->temporary, ln, string);
 	} else {
 		/* Append string to existing temporary. */
 		new_sentence = (vars->temporary[0] == NUL);
 		noted = strlen(vars->temporary);
-		vars->temporary = (sc_char *)sc_realloc(vars->temporary,
-		                                        strlen(vars->temporary) +
-		                                        strlen(string) + 1);
-		strcat(vars->temporary, string);
+		size_t ln = strlen(vars->temporary) + strlen(string) + 1;
+		vars->temporary = (sc_char *)sc_realloc(vars->temporary, ln);
+		Common::strcat_s(vars->temporary, ln, string);
 	}
 
 	if (new_sentence)
@@ -780,7 +781,7 @@ static sc_bool var_get_system(sc_var_setref_t vars, const sc_char *name,
 
 		/* Clear any current temporary for appends. */
 		vars->temporary = (sc_char *)sc_realloc(vars->temporary, 1);
-		strcpy(vars->temporary, "");
+		vars->temporary[0] = '\0';
 
 		/* Write what's in the object into temporary. */
 		var_list_in_object(game, vars->referenced_object);
@@ -835,17 +836,17 @@ static sc_bool var_get_system(sc_var_setref_t vars, const sc_char *name,
 			vt_key[2].string = "Prefix";
 			prefix = prop_get_string(bundle, "S<-sis", vt_key);
 
-			vars->temporary = (sc_char *)sc_realloc(vars->temporary, strlen(prefix) + 1);
-			strcpy(vars->temporary, prefix);
+			size_t ln = strlen(prefix) + 1;
+			vars->temporary = (sc_char *)sc_realloc(vars->temporary, ln);
+			Common::strcpy_s(vars->temporary, ln, prefix);
 
 			vt_key[2].string = "Short";
 			objname = prop_get_string(bundle, "S<-sis", vt_key);
 
-			vars->temporary = (sc_char *)sc_realloc(vars->temporary,
-			                                        strlen(vars->temporary)
-			                                        + strlen(objname) + 2);
-			strcat(vars->temporary, " ");
-			strcat(vars->temporary, objname);
+			ln = strlen(vars->temporary) + strlen(objname) + 2;
+			vars->temporary = (sc_char *)sc_realloc(vars->temporary, ln);
+			Common::strcat_s(vars->temporary, ln, " ");
+			Common::strcat_s(vars->temporary, ln, objname);
 
 			return var_return_string(vars->temporary, type, vt_rvalue);
 		} else {
@@ -886,8 +887,9 @@ static sc_bool var_get_system(sc_var_setref_t vars, const sc_char *name,
 			sc_error("var_get_system: invalid state for obstate\n");
 			return var_return_string("[Obstate unknown]", type, vt_rvalue);
 		}
-		vars->temporary = (sc_char *)sc_realloc(vars->temporary, strlen(state) + 1);
-		strcpy(vars->temporary, state);
+		size_t ln = strlen(state) + 1;
+		vars->temporary = (sc_char *)sc_realloc(vars->temporary, ln);
+		Common::strcpy_s(vars->temporary, ln, state);
 		sc_free(state);
 
 		/* Return temporary. */
@@ -952,7 +954,7 @@ static sc_bool var_get_system(sc_var_setref_t vars, const sc_char *name,
 
 		/* Clear any current temporary for appends. */
 		vars->temporary = (sc_char *)sc_realloc(vars->temporary, 1);
-		strcpy(vars->temporary, "");
+		vars->temporary[0] = '\0';
 
 		/* Write what's on the object into temporary. */
 		var_list_on_object(game, vars->referenced_object);
@@ -977,7 +979,7 @@ static sc_bool var_get_system(sc_var_setref_t vars, const sc_char *name,
 
 		/* Clear any current temporary for appends. */
 		vars->temporary = (sc_char *)sc_realloc(vars->temporary, 1);
-		strcpy(vars->temporary, "");
+		vars->temporary[0] = '\0';
 
 		/* Write what's on/in the object into temporary. */
 		var_list_onin_object(game, vars->referenced_object);
@@ -1063,8 +1065,9 @@ static sc_bool var_get_system(sc_var_setref_t vars, const sc_char *name,
 			sc_error("var_get_system: invalid state for state_\n");
 			return var_return_string("[State_ unknown]", type, vt_rvalue);
 		}
-		vars->temporary = (sc_char *)sc_realloc(vars->temporary, strlen(state) + 1);
-		strcpy(vars->temporary, state);
+		size_t ln = strlen(state) + 1;
+		vars->temporary = (sc_char *)sc_realloc(vars->temporary, ln);
+		Common::strcpy_s(vars->temporary, ln, state);
 		sc_free(state);
 
 		/* Restore saved referenced object and return. */
@@ -1202,30 +1205,31 @@ static sc_bool var_get_system(sc_var_setref_t vars, const sc_char *name,
 			vt_key[2].string = "Prefix";
 			prefix = prop_get_string(bundle, "S<-sis", vt_key);
 
-			vars->temporary = (sc_char *)sc_realloc(vars->temporary, strlen(prefix) + 5);
-			strcpy(vars->temporary, "");
+			size_t temporary_ln = strlen(prefix) + 5;
+			vars->temporary = (sc_char *)sc_realloc(vars->temporary, temporary_ln);
+			vars->temporary[0] = '\0';
 
 			normalized = prefix;
 			if (sc_compare_word(prefix, "a", 1)) {
-				strcat(vars->temporary, "the");
+				Common::strcat_s(vars->temporary, temporary_ln, "the");
 				normalized = prefix + 1;
 			} else if (sc_compare_word(prefix, "an", 2)) {
-				strcat(vars->temporary, "the");
+				Common::strcat_s(vars->temporary, temporary_ln, "the");
 				normalized = prefix + 2;
 			} else if (sc_compare_word(prefix, "the", 3)) {
-				strcat(vars->temporary, "the");
+				Common::strcat_s(vars->temporary, temporary_ln, "the");
 				normalized = prefix + 3;
 			} else if (sc_compare_word(prefix, "some", 4)) {
-				strcat(vars->temporary, "the");
+				Common::strcat_s(vars->temporary, temporary_ln, "the");
 				normalized = prefix + 4;
 			} else if (sc_strempty(prefix))
-				strcat(vars->temporary, "the ");
+				Common::strcat_s(vars->temporary, temporary_ln, "the ");
 
 			if (!sc_strempty(normalized)) {
-				strcat(vars->temporary, normalized);
-				strcat(vars->temporary, " ");
+				Common::strcat_s(vars->temporary, temporary_ln, normalized);
+				Common::strcat_s(vars->temporary, temporary_ln, " ");
 			} else if (normalized > prefix)
-				strcat(vars->temporary, " ");
+				Common::strcat_s(vars->temporary, temporary_ln, " ");
 
 			vt_key[2].string = "Short";
 			objname = prop_get_string(bundle, "S<-sis", vt_key);
@@ -1238,10 +1242,9 @@ static sc_bool var_get_system(sc_var_setref_t vars, const sc_char *name,
 			else if (sc_compare_word(objname, "some", 4))
 				objname += 4;
 
-			vars->temporary = (sc_char *)sc_realloc(vars->temporary,
-			                                        strlen(vars->temporary)
-			                                        + strlen(objname) + 1);
-			strcat(vars->temporary, objname);
+			temporary_ln = strlen(vars->temporary) + strlen(objname) + 1;
+			vars->temporary = (sc_char *)sc_realloc(vars->temporary, temporary_ln);
+			Common::strcat_s(vars->temporary, temporary_ln, objname);
 
 			return var_return_string(vars->temporary, type, vt_rvalue);
 		} else {
@@ -1546,8 +1549,9 @@ void var_set_ref_text(sc_var_setref_t vars, const sc_char *text) {
 	assert(var_is_valid(vars));
 
 	/* Take a copy of the string, and retain it. */
-	vars->referenced_text = (sc_char *)sc_realloc(vars->referenced_text, strlen(text) + 1);
-	strcpy(vars->referenced_text, text);
+	size_t ln = strlen(text) + 1;
+	vars->referenced_text = (sc_char *)sc_realloc(vars->referenced_text, ln);
+	Common::strcpy_s(vars->referenced_text, ln, text);
 }
 
 
diff --git a/engines/glk/agt/agtread.cpp b/engines/glk/agt/agtread.cpp
index 2c4199fee4e..2b1539e20fe 100644
--- a/engines/glk/agt/agtread.cpp
+++ b/engines/glk/agt/agtread.cpp
@@ -874,7 +874,7 @@ static void read_line(genfile fd, const char *typestr)
 		readln(fd, linebuffer, 80);
 		if (linebuffer[0] == 0 && texteof(fd)) {
 			unexpected_eof = 1;
-			strcpy(linebuffer, ">End Of File<");
+			Common::strcpy_s(linebuffer, ">End Of File<");
 		} else chop_newline(linebuffer);
 		linenum++;
 	}
diff --git a/engines/glk/agt/exec.cpp b/engines/glk/agt/exec.cpp
index 031bb6af964..d7c7f45c17e 100644
--- a/engines/glk/agt/exec.cpp
+++ b/engines/glk/agt/exec.cpp
@@ -219,9 +219,9 @@ static word it_pronoun(int item, rbool ind_form)
 /* (In particular, proper nouns shouldn't have a "the") */
 static void theset(char *buff, int item) {
 	if (it_proper(item))
-		strcpy(buff, "");
+		buff[0] = '\0';
 	else
-		strcpy(buff, "the ");
+		Common::strcpy_s(buff, FILL_SIZE, "the ");
 }
 
 
@@ -236,7 +236,7 @@ static void num_name_func(parse_rec *obj_rec, char *fill_buff, word prev_adj)
 	word w;
 
 	if (obj_rec == nullptr) {
-		strcpy(fill_buff, "");
+		fill_buff[0] = '\0';
 		return;
 	}
 
@@ -247,9 +247,9 @@ static void num_name_func(parse_rec *obj_rec, char *fill_buff, word prev_adj)
 
 	if (w == 0) {
 		if (obj_rec->info == D_NUM) sprintf(fill_buff, "%ld", (long)obj_rec->num);
-		else strcpy(fill_buff, "");
+		else fill_buff[0] = '\0';
 #if 0
-		strcpy(fill_buff, "that"); /* We can try and hope */
+		Common::strcpy_s(fill_buff, FILL_SIZE, "that"); /* We can try and hope */
 #endif
 		return;
 	}
@@ -269,7 +269,7 @@ static word get_adj(parse_rec *obj_rec, char *buff) {
 	if (obj_rec->adj != 0) w = obj_rec->adj;
 	else w = it_adj(obj_rec->obj);
 
-	if (w == 0) strcpy(buff, "");
+	if (w == 0) buff[0] = '\0';
 	else {
 		rstrncpy(buff, dict[w], FILL_SIZE);
 		if (it_proper(obj_rec->obj)) buff[0] = toupper(buff[0]);
@@ -283,7 +283,7 @@ static word get_adj(parse_rec *obj_rec, char *buff) {
 #define d2buff(i) {rstrncpy(fill_buff,dict[i],FILL_SIZE);return 1;}
 #define num_name(obj_rec,jsa)  {num_name_func(obj_rec,fill_buff,jsa);return 1;}
 /* jsa= Just seen adj */
-#define youme(mestr,youstr) {strcpy(fill_buff,irun_mode?mestr:youstr);\
+#define youme(mestr,youstr) {Common::strcpy_s(fill_buff,FILL_SIZE,irun_mode?mestr:youstr);\
 		return 1;}
 
 word just_seen_adj;  /* This determines if we just saw $adjective$; if so,
@@ -345,15 +345,15 @@ static int wordcode_match(const char **pvarname, char *fill_buff,
 		return 1;
 	} else if (match_str(pvarname, "OPEN")) {
 		hold_val = extract_number(pvarname, maxnoun, '$');
-		strcpy(fill_buff, it_open(hold_val) ? "open" : "closed");
+		Common::strcpy_s(fill_buff, FILL_SIZE, it_open(hold_val) ? "open" : "closed");
 		return 1;
 	} else if (match_str(pvarname, "ON")) {
 		hold_val = extract_number(pvarname, maxnoun, '$');
-		strcpy(fill_buff, it_on(hold_val) ? "on" : "off");
+		Common::strcpy_s(fill_buff, FILL_SIZE, it_on(hold_val) ? "on" : "off");
 		return 1;
 	} else if (match_str(pvarname, "LOCKED")) {
 		hold_val = extract_number(pvarname, maxnoun, '$');
-		strcpy(fill_buff, it_locked(hold_val, 0) ? "locked" : "unlocked");
+		Common::strcpy_s(fill_buff, FILL_SIZE, it_locked(hold_val, 0) ? "locked" : "unlocked");
 		return 1;
 	}
 
diff --git a/engines/glk/agt/gamedata.cpp b/engines/glk/agt/gamedata.cpp
index d02cbcdfce4..1c534c06b10 100644
--- a/engines/glk/agt/gamedata.cpp
+++ b/engines/glk/agt/gamedata.cpp
@@ -642,7 +642,7 @@ static word add0_dict(const char *s) {
 			dict[i] = (dict[i] - dictstr) + newstr;
 		dictstr = newstr;
 	}
-	strcpy(dictstr + dictstrptr, s); /* Copy word into memory */
+	Common::strcpy_s(dictstr + dictstrptr, dictstrsize - dictstrptr, s); /* Copy word into memory */
 	dict[dp] = dictstr + dictstrptr;
 	dictstrptr = newptr;
 
@@ -691,7 +691,7 @@ static void init0_dict(void)
 
 	dict = (char **)rmalloc(sizeof(char *));
 	dictstr = (char *)rmalloc(DICT_GRAN);
-	strcpy(dictstr, "any");
+	Common::strcpy_s(dictstr, DICT_GRAN, "any");
 	dict[0] = dictstr;
 
 	dictstrptr = 4; /* Point just after 'any' */
diff --git a/engines/glk/agt/object.cpp b/engines/glk/agt/object.cpp
index 97cf680f5a3..2c1525493fe 100644
--- a/engines/glk/agt/object.cpp
+++ b/engines/glk/agt/object.cpp
@@ -811,9 +811,9 @@ static char *build_position(word prep_, word name)
 	leng = strlen(dict[prep_]) + strlen(dict[name]) + 6; /* includes final '\0' */
 	s = (char *)rmalloc(leng * sizeof(char));
 
-	strcpy(s, dict[prep_]);
-	strcat(s, " the ");
-	strcat(s, dict[name]);
+	Common::strcpy_s(s, leng, dict[prep_]);
+	Common::strcat_s(s, leng, " the ");
+	Common::strcat_s(s, leng, dict[name]);
 	assert((int)strlen(s) + 1 == leng);
 	return s;
 }
diff --git a/engines/glk/agt/os_glk.cpp b/engines/glk/agt/os_glk.cpp
index 163304c40df..679921589d8 100644
--- a/engines/glk/agt/os_glk.cpp
+++ b/engines/glk/agt/os_glk.cpp
@@ -830,8 +830,9 @@ static void gagt_status_print() {
 
 	/* Save the details of the printed status buffer. */
 	free(gagt_status_buffer_printed);
-	gagt_status_buffer_printed = (char *)gagt_malloc(strlen(gagt_status_buffer) + 1);
-	strcpy(gagt_status_buffer_printed, gagt_status_buffer);
+	size_t ln = strlen(gagt_status_buffer) + 1;
+	gagt_status_buffer_printed = (char *)gagt_malloc(ln);
+	Common::strcpy_s(gagt_status_buffer_printed, ln, gagt_status_buffer);
 }
 
 
@@ -4523,8 +4524,9 @@ static int gagt_command_escape(const char *string) {
 		return FALSE;
 
 	/* Take a copy of the string, without any leading space or introducer. */
-	string_copy = (char *)gagt_malloc(strlen(string + posn) + 1 - strlen("glk"));
-	strcpy(string_copy, string + posn + strlen("glk"));
+	size_t ln = strlen(string + posn) + 1 - 3 /*strlen("glk")*/;
+	string_copy = (char *)gagt_malloc(ln);
+	Common::strcpy_s(string_copy, ln, string + posn + 3 /*strlen("glk")*/);
 
 	/*
 	 * Find the subcommand; the first word in the string copy.  Find its end,
diff --git a/engines/glk/alan2/debug.cpp b/engines/glk/alan2/debug.cpp
index 41cadcc41d3..b24ddb7a625 100644
--- a/engines/glk/alan2/debug.cpp
+++ b/engines/glk/alan2/debug.cpp
@@ -288,7 +288,7 @@ void debug() {
 			para();
 		do {
 			output("ABUG> ");
-			(void)readline(buf);
+			(void)readline(buf, sizeof(buf));
 
 			lin = 1;
 			c = buf[0];
diff --git a/engines/glk/alan2/exe.cpp b/engines/glk/alan2/exe.cpp
index f3fb9c16ef5..626c4fa4869 100644
--- a/engines/glk/alan2/exe.cpp
+++ b/engines/glk/alan2/exe.cpp
@@ -159,7 +159,7 @@ Boolean confirm(MsgKind msgno) {
 	   it could be affirmative, but for now any input is NOT! */
 	prmsg(msgno);
 
-	if (!readline(buf)) return TRUE;
+	if (!readline(buf, sizeof(buf))) return TRUE;
 	col = 1;
 
 	return (buf[0] == '\0');
@@ -173,7 +173,7 @@ void quit(CONTEXT) {
 		col = 1;
 		statusline();
 		prmsg(M_QUITACTION);
-		if (!readline(buf)) {
+		if (!readline(buf, sizeof(buf))) {
 			CALL1(terminate, 0)
 		}
 
diff --git a/engines/glk/alan2/glkio.cpp b/engines/glk/alan2/glkio.cpp
index 2a34a3bb24c..47e4119a463 100644
--- a/engines/glk/alan2/glkio.cpp
+++ b/engines/glk/alan2/glkio.cpp
@@ -59,14 +59,14 @@ void glkio_printf(const char *fmt, ...) {
   */
 
   /* 4f - length of user buffer should be used */
-Boolean readline(char usrbuf[]) {
+Boolean readline(char usrbuf[], size_t maxlen) {
 	if (g_vm->_pendingLook) {
 		g_vm->_pendingLook = false;
 		glkio_printf("look\n");
-		strcpy(usrbuf, "look");
+		Common::strcpy_s(usrbuf, maxlen, "look");
 	} else {
 		event_t event;
-		g_vm->glk_request_line_event(glkMainWin, usrbuf, 255, 0);
+		g_vm->glk_request_line_event(glkMainWin, usrbuf, maxlen, 0);
 
 		/* FIXME: buffer size should be infallible: all existing calls use 256 or
 		   80 character buffers, except parse which uses LISTLEN (currently 100)
diff --git a/engines/glk/alan2/glkio.h b/engines/glk/alan2/glkio.h
index 906ab16734d..72bb35226f3 100644
--- a/engines/glk/alan2/glkio.h
+++ b/engines/glk/alan2/glkio.h
@@ -44,7 +44,7 @@ void glkio_printf(const char *, ...);
 #define LINELENGTH 80
 #define HISTORYLENGTH 20
 
-extern Boolean readline(char usrbuf[]);
+extern Boolean readline(char usrbuf[], size_t maxlen);
 
 } // End of namespace Alan2
 } // End of namespace Glk
diff --git a/engines/glk/alan2/main.cpp b/engines/glk/alan2/main.cpp
index 299536c4596..fbd903f85d2 100644
--- a/engines/glk/alan2/main.cpp
+++ b/engines/glk/alan2/main.cpp
@@ -863,9 +863,9 @@ static void do_it(CONTEXT) {
 				if (alt[i]->action != 0) {
 					if (trcflg) {
 						if (i == 0)
-							strcpy(trace, "GLOBAL");
+							Common::strcpy_s(trace, "GLOBAL");
 						else if (i == 1)
-							strcpy(trace, "in LOCATION");
+							Common::strcpy_s(trace, "in LOCATION");
 						else
 							sprintf(trace, "in PARAMETER %d", i - 1);
 						if (alt[i]->qual == (Aword)Q_BEFORE)
@@ -889,9 +889,9 @@ static void do_it(CONTEXT) {
 				if (!done[i] && alt[i]->action != 0) {
 					if (trcflg) {
 						if (i == 0)
-							strcpy(trace, "GLOBAL");
+							Common::strcpy_s(trace, "GLOBAL");
 						else if (i == 1)
-							strcpy(trace, "in LOCATION");
+							Common::strcpy_s(trace, "in LOCATION");
 						else
 							sprintf(trace, "in PARAMETER %d", i - 1);
 						printf("\n<VERB %d, %s, Body:>\n", cur.vrb, trace);
@@ -910,9 +910,9 @@ static void do_it(CONTEXT) {
 			if (!done[i] && alt[i]->action != 0) {
 				if (trcflg) {
 					if (i == 0)
-						strcpy(trace, "GLOBAL");
+						Common::strcpy_s(trace, "GLOBAL");
 					else if (i == 1)
-						strcpy(trace, "in LOCATION");
+						Common::strcpy_s(trace, "in LOCATION");
 					else
 						sprintf(trace, "in PARAMETER %d", i - 1);
 					printf("\n<VERB %d, %s (AFTER), Body:>\n", cur.vrb, trace);
diff --git a/engines/glk/alan2/parse.cpp b/engines/glk/alan2/parse.cpp
index 28050afe807..fd579dc79a0 100644
--- a/engines/glk/alan2/parse.cpp
+++ b/engines/glk/alan2/parse.cpp
@@ -86,11 +86,12 @@ static Boolean eol = TRUE;  /* Looking at End of line? Yes, initially */
 
 
 static void unknown(CONTEXT, char token[]) {
-	char *str = (char *)allocate((int)strlen(token) + 4);
+	size_t ln = strlen(token) + 4;
+	char *str = (char *)allocate((int)ln);
 
 	str[0] = '\'';
-	strcpy(&str[1], token);
-	strcat(str, "'?");
+	Common::strcpy_s(&str[1], ln, token);
+	Common::strcat_s(str, ln, "'?");
 	output(str);
 	free(str);
 	eol = TRUE;
@@ -156,7 +157,7 @@ static void agetline(CONTEXT) {
 		if (logflg)
 			fprintf(logfil, "> ");
 
-		if (!readline(buf)) {
+		if (!readline(buf, sizeof(buf))) {
 			if (g_vm->shouldQuit())
 				return;
 
@@ -167,7 +168,7 @@ static void agetline(CONTEXT) {
 		anyOutput = FALSE;
 		if (logflg)
 			fprintf(logfil, "%s\n", buf);
-		strcpy(isobuf, buf);
+		Common::strcpy_s(isobuf, buf);
 
 		token = gettoken(isobuf);
 		if (token != nullptr && strcmp("debug", token) == 0 && header->debug) {
diff --git a/engines/glk/alan2/sysdep.cpp b/engines/glk/alan2/sysdep.cpp
index f07879fe798..276d9289a65 100644
--- a/engines/glk/alan2/sysdep.cpp
+++ b/engines/glk/alan2/sysdep.cpp
@@ -200,6 +200,7 @@ char *stringUpper(char str[]) { /* INOUT - ISO string to convert */
 }
 
 
+#if 0
 /*----------------------------------------------------------------------
   toIso
 
@@ -304,6 +305,7 @@ void toNative(char copy[],  /* OUT - Mapped  string */
 	if (NATIVECHARSET != 0)
 		fromIso(copy, copy);
 }
+#endif
 
 } // End of namespace Alan2
 } // End of namespace Glk
diff --git a/engines/glk/alan2/sysdep.h b/engines/glk/alan2/sysdep.h
index e383a8c003e..29b9d9f667d 100644
--- a/engines/glk/alan2/sysdep.h
+++ b/engines/glk/alan2/sysdep.h
@@ -70,6 +70,7 @@ extern char toUpperCase(int c); /* IN - ISO character to convert */
 extern char *stringLower(char str[]); /* INOUT - ISO string to convert */
 extern char *stringUpper(char str[]); /* INOUT - ISO string to convert */
 
+#if 0
 /* ISO string conversion functions */
 extern void toIso(char copy[],  /* OUT - Mapped string */
 				  char original[], /* IN - string to convert */
@@ -81,6 +82,7 @@ extern void fromIso(char copy[], /* OUT - Mapped string */
 extern void toNative(char copy[], /* OUT - Mapped string */
 					 char original[], /* IN - string to convert */
 					 int charset); /* IN - current character set */
+#endif
 
 } // End of namespace Alan2
 } // End of namespace Glk
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index de59f1b6b67..a8744114baf 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -327,9 +327,10 @@ void schedule(Aword event, Aword where, Aword after) {
 Aptr concat(Aptr as1, Aptr as2) {
 	char *s1 = (char *)fromAptr(as1);
 	char *s2 = (char *)fromAptr(as2);
-	char *result = (char *)allocate(strlen((char *)s1) + strlen((char *)s2) + 1);
-	strcpy(result, s1);
-	strcat(result, s2);
+	size_t ln = strlen(s1) + strlen(s2) + 1;
+	char *result = (char *)allocate(ln);
+	Common::strcpy_s(result, ln, s1);
+	Common::strcat_s(result, ln, s2);
 	return toAptr(result);
 }
 
diff --git a/engines/glk/alan3/glkio.cpp b/engines/glk/alan3/glkio.cpp
index 72b57568a9f..6ea8224b922 100644
--- a/engines/glk/alan3/glkio.cpp
+++ b/engines/glk/alan3/glkio.cpp
@@ -177,7 +177,7 @@ bool GlkIO::readLine(CONTEXT, char *buffer, size_t maxLen) {
 		// Return a "restore" command
 		forcePrint("> ");
 		forcePrint("restore\n");
-		strcpy(buffer, "restore");
+		Common::strcpy_s(buffer, maxLen, "restore");
 
 	} else if (readingCommands) {
 		if (glk_get_line_stream(commandFile, buffer, maxLen) == 0) {
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 426316d5105..8d86b519543 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -267,11 +267,11 @@ static void nonDevelopmentRunningDevelopmentStateGame(const byte version[]) {
 	char errorMessage[200];
 	char versionString[100];
 
-	strcpy(errorMessage, "Games generated by a development state compiler");
+	Common::strcpy_s(errorMessage, "Games generated by a development state compiler");
 	sprintf(versionString, "(this game is v%d.%d.%d%s)", version[0], version[1],
 	        version[2], decodeState(version[3]));
-	strcat(errorMessage, versionString);
-	strcat(errorMessage, "can only be run with a matching interpreter. Look for a game file generated with an alpha, beta or release state compiler.>\n");
+	Common::strcat_s(errorMessage, versionString);
+	Common::strcat_s(errorMessage, "can only be run with a matching interpreter. Look for a game file generated with an alpha, beta or release state compiler.>\n");
 	apperr(errorMessage);
 }
 
diff --git a/engines/glk/alan3/scan.cpp b/engines/glk/alan3/scan.cpp
index 387c693bb5a..bf6f6ea490e 100644
--- a/engines/glk/alan3/scan.cpp
+++ b/engines/glk/alan3/scan.cpp
@@ -166,7 +166,7 @@ static void getLine(CONTEXT) {
 			LONG_JUMP_LABEL("forfeit")
 		}
 
-		strcpy(isobuf, buf);
+		Common::strcpy_s(isobuf, buf);
 		token = gettoken(isobuf);
 		if (token != nullptr) {
 			if (strcmp("debug", token) == 0 && header->debug) {
diff --git a/engines/glk/alan3/sysdep.cpp b/engines/glk/alan3/sysdep.cpp
index c259321d352..3df40536663 100644
--- a/engines/glk/alan3/sysdep.cpp
+++ b/engines/glk/alan3/sysdep.cpp
@@ -208,6 +208,7 @@ int compareStrings(char *str1, char *str2) {
 }
 
 
+#if 0
 
 /*----------------------------------------------------------------------
   toIso
@@ -313,6 +314,8 @@ void toNative(char copy[], char original[], int charset) {
 		fromIso(copy, copy);
 }
 
+#endif
+
 
 /*======================================================================*/
 char *baseNameStart(char *fullPathName) {
diff --git a/engines/glk/alan3/sysdep.h b/engines/glk/alan3/sysdep.h
index 47626e1b6c9..420814a4df8 100644
--- a/engines/glk/alan3/sysdep.h
+++ b/engines/glk/alan3/sysdep.h
@@ -99,6 +99,7 @@ extern char *stringLower(char str[]); /* INOUT - ISO string to convert */
 extern char *stringUpper(char str[]); /* INOUT - ISO string to convert */
 extern int compareStrings(char str1[], char str2[]); /* Case-insensitive compare */
 
+#if 0
 /* ISO string conversion functions */
 extern void toIso(char copy[],  /* OUT - Mapped string */
 				  char original[], /* IN - string to convert */
@@ -110,6 +111,7 @@ extern void fromIso(char copy[], /* OUT - Mapped string */
 extern void toNative(char copy[], /* OUT - Mapped string */
 					 char original[], /* IN - string to convert */
 					 int charset); /* IN - current character set */
+#endif
 
 extern char *baseNameStart(char *fullPathName);
 
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index 0c924b07e5b..9e63f3bb728 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -176,7 +176,7 @@ void OOToposGame::afterPrompt() {
 
 	// WORKAROUND: Allow for the Apple 2 password in the DOS version
 	if (!scumm_stricmp(_inputLine, "vug957a"))
-		strcpy(_inputLine, "tse957x");
+		Common::strcpy_s(_inputLine, "tse957x");
 
 	if (_currentRoom != _currentRoomCopy)
 		_updateFlags |= UPDATE_GRAPHICS;
diff --git a/engines/glk/comprehend/game_tm.cpp b/engines/glk/comprehend/game_tm.cpp
index c1a89ce2019..553d90cff42 100644
--- a/engines/glk/comprehend/game_tm.cpp
+++ b/engines/glk/comprehend/game_tm.cpp
@@ -137,7 +137,7 @@ void TalismanGame::afterPrompt() {
 		if (_redoLine == REDO_NONE && _flags[3])
 			_redoLine = REDO_PROMPT;
 	} else {
-		strcpy(_inputLine, _savedAction.c_str());
+		Common::strcpy_s(_inputLine, _savedAction.c_str());
 		_savedAction.clear();
 	}
 }
diff --git a/engines/glk/hugo/hemisc.cpp b/engines/glk/hugo/hemisc.cpp
index a0d343ebb55..81b2ba5dd1a 100644
--- a/engines/glk/hugo/hemisc.cpp
+++ b/engines/glk/hugo/hemisc.cpp
@@ -290,7 +290,7 @@ AddFontCode:
 			bufferbreak = 0;
 			bufferbreaklen = 0;
 #endif
-			strcpy(pbuffer, "");
+			pbuffer[0] = '\0';
 			plen = 0;
 			linebreak = 0;
 			linebreaklen = 0;
@@ -435,7 +435,7 @@ AddFontCode:
 		hugo_font(currentfont = lastfont);
 		Printout(pbuffer, 0);
 		lastfont = currentfont;
-		strcpy(pbuffer, "");
+		pbuffer[0] = '\0';
 		linebreak = 0;
 		linebreaklen = 0;
 		thisline = 0;
@@ -573,7 +573,7 @@ unsigned int Hugo::Dict() {
 	codeptr += 2;                           /* "(" */
 
 	if (MEM(codeptr)==PARSE_T || MEM(codeptr)==WORD_T)
-		strcpy(line, GetWord(GetValue()));
+		Common::strcpy_s(line, GetWord(GetValue()));
 	else
 	{
 		/* Get the array address to read the to-be-
@@ -760,7 +760,7 @@ void Hugo::FileIO() {
 	ioerror = 0;
 
 	/* Make sure the filename is legal, 8 alphanumeric characters or less */
-	strcpy(line, GetWord(fnameval));
+	Common::strcpy_s(line, GetWord(fnameval));
 	if (strlen(line) > 8) goto LeaveFileIO;
 	for (i=0; i<(int)strlen(line); i++)
 	{
@@ -779,7 +779,7 @@ void Hugo::FileIO() {
 	hugo_splitpath(program_path, drive, dir, fname, ext);
 	hugo_makepath(fileiopath, drive, dir, GetWord(fnameval), "");
 #else
-	strcpy(fileiopath, GetWord(fnameval));
+	Common::strcpy_s(fileiopath, GetWord(fnameval));
 #endif
 
 	if (iotype==WRITEFILE_T)        /* "writefile" */
@@ -863,7 +863,7 @@ void Hugo::Flushpbuffer() {
 	pbuffer[strlen(pbuffer)] = (char)NO_NEWLINE;
 	Printout(Ltrim(pbuffer), 0);
 	currentpos = hugo_textwidth(pbuffer);	/* -charwidth; */
-	strcpy(pbuffer, "");
+	pbuffer[0] = '\0';
 }
 
 void Hugo::GetCommand() {
@@ -918,9 +918,9 @@ void Hugo::GetCommand() {
 	hugo_getline(a);
 #endif
 	during_player_input = false;
-	strcpy(buffer, Rtrim(buffer));
+	Common::strcpy_s(buffer, Rtrim(buffer));
 
-	strcpy(parseerr, "");
+	parseerr[0] = '\0';
 
 	full = 1;
 	remaining = 0;
@@ -1072,7 +1072,7 @@ void Hugo::InitGame() {
 	if (_savegameSlot == -1) {
 #endif
 #if defined (DEBUGGER)
-	for (i=0; i<MAXLOCALS; i++) strcpy(localname[i], "");
+	for (i=0; i<MAXLOCALS; i++) localname[i][0] = '\0';
 	window[VIEW_LOCALS].count = current_locals = 0;
 
 	PassLocals(0);
@@ -1103,7 +1103,7 @@ void Hugo::LoadGame() {
 	if (!strcmp(gamefile, ""))
 	{
 		game = nullptr;
-		strcpy(gamefile, "(no file)");
+		Common::strcpy_s(gamefile, "(no file)");
 		return;
 	}
 #endif
@@ -1303,15 +1303,15 @@ void Hugo::LoadGame() {
 
 	/* build punctuation string (additional user-specified punctuation) */
 	synptr = 2;
-	strcpy(punc_string, "");
+	punc_string[0] = '\0';
 	for (i=1; i<=syncount; i++)
 	{
 		defseg = syntable;
 		if (Peek(synptr)==3)	/* 3 = punctuation */
 		{
-			strcpy(line, GetWord(PeekWord(synptr+1)));
+			Common::strcpy_s(line, GetWord(PeekWord(synptr+1)));
 			if (strlen(line) + strlen(punc_string) > 63) break;
-			strcat(punc_string, line);
+			Common::strcat_s(punc_string, line);
 		}
 		synptr+=5;
 	}
@@ -1452,7 +1452,7 @@ const char *Hugo::PrintHex(long a) {
 	static char hex[7];
 	int h = 0;
 
-	strcpy(hex, "");
+	hex[0] = '\0';
 
 	if (a < 0L) a = 0;
 
diff --git a/engines/glk/hugo/heparse.cpp b/engines/glk/hugo/heparse.cpp
index 51f87be11e9..b15d1f49f6a 100644
--- a/engines/glk/hugo/heparse.cpp
+++ b/engines/glk/hugo/heparse.cpp
@@ -398,7 +398,7 @@ int Hugo::MatchCommand() {
 
 	if (!strcmp(word[1], "~oops"))
 	{
-		strcpy(parseerr, "");
+		parseerr[0] = '\0';
 
 		/* "oops" on its own */
 		if (words==1 || !strcmp(oops, ""))
@@ -423,18 +423,18 @@ int Hugo::MatchCommand() {
 
 		/* Rebuild the corrected buffer */
 		oopscount = 1;
-		strcpy(line, word[2]);
+		Common::strcpy_s(line, word[2]);
 		for (i=1; i<=(int)strlen(errbuf); i++)
 		{
 			if (!strcmp(Mid(errbuf, i, strlen(oops)), oops))
 				break;
 		}
 
-		strcpy(buffer, errbuf);
+		Common::strcpy_s(buffer, errbuf);
 		buffer[i-1] = '\0';
-		strcat(buffer, line);
+		Common::strcat_s(buffer, line);
 
-		strcat(buffer, Right(errbuf, strlen(errbuf) - i - strlen(oops) + 1));
+		Common::strcat_s(buffer, Right(errbuf, strlen(errbuf) - i - strlen(oops) + 1));
 
 		SeparateWords();
 		if (!Parse())
@@ -588,7 +588,7 @@ MatchVerb:
 		/* No match, ergo an invalid command */
 		if (flag==0 && nextverb==true)
 		{
-			strcpy(parseerr, "");
+			parseerr[0] = '\0';
 			ParseError(6, 0);        /* "...doesn't make any sense..." */
 			return 0;
 		}
@@ -596,7 +596,7 @@ MatchVerb:
 		/* No provision made for addressing objects (characters) */
 		if (flag==0 || speaktoaddr==0)
 		{
-			strcpy(parseerr, "");
+			parseerr[0] = '\0';
 			ParseError(2, 0);        /* "Better start with a verb..." */
 			return 0;
 		}
@@ -651,7 +651,7 @@ GotVerb:
 
 	obj_match_state = 0;
 	starts_with_verb = 1;
-	strcpy(parseerr, word[1]);
+	Common::strcpy_s(parseerr, word[1]);
 
 	if (Peek(grammaraddr)==XVERB_T) xverb = true;
 	grammaraddr += 2 + numverbs * 2;
@@ -750,7 +750,7 @@ NextStructure:
 			/* ...or if we reached the end without a sensible
 			   syntax matched:
 			*/
-			strcpy(parseerr, "");
+			parseerr[0] = '\0';
 
 			/* "...doesn't make any sense..." */
 			ParseError(6, 0);
@@ -822,7 +822,7 @@ bool Hugo::MatchObject(int *wordnum) {
 #ifdef DEBUG_PARSER
 	Printout("MatchObject(): Entering");
 #endif
-	strcpy(parseerr, "");
+	parseerr[0] = '\0';
 
 	do                                 /* starting at word #a */
 	{
@@ -831,8 +831,8 @@ bool Hugo::MatchObject(int *wordnum) {
 		*/
 		if (word[*wordnum][0]!='~' && word[*wordnum][0]!='\0')
 		{
-			if (parseerr[0]!='\0') strcat(parseerr, " ");
-			strcat(parseerr, word[*wordnum]);
+			if (parseerr[0]!='\0') Common::strcat_s(parseerr, " ");
+			Common::strcat_s(parseerr, word[*wordnum]);
 
 			flag = 0;
 			for (i=0; i<objects; i++)
@@ -903,7 +903,7 @@ bool Hugo::MatchObject(int *wordnum) {
 				/* If checking the xobject */
 				if (obj_match_state==1)
 				{
-					strcpy(parseerr, word[1]);
+					Common::strcpy_s(parseerr, word[1]);
 					/* "...can't use multiple objects..."
 					   (as indirect objects) */
 					ParseError(7, 0);
@@ -973,7 +973,7 @@ Clarify:
 		/* If checking the xobject or addressing a command */
 		if (obj_match_state==1 || speaking)
 		{
-			strcpy(parseerr, word[1]);
+			Common::strcpy_s(parseerr, word[1]);
 			/* "...can't use multiple objects..."
 			   (as indirect objects) */
 			ParseError(7, 0);
@@ -1017,7 +1017,7 @@ Clarify:
 		{
 			if (!objcount && !speaking)
 			{
-				strcpy(parseerr, word[1]);
+				Common::strcpy_s(parseerr, word[1]);
 				ParseError(9, 0);   /* "Nothing to (verb)..." */
 				return false;
 			}
@@ -1425,11 +1425,11 @@ Clarify:
 
 RestoreTempArrays:
 		/* Rebuild <buffer> and word[] array */
-			strcpy(buffer, "");
+			buffer[0] = '\0';
 			for (i=1; i<=wtemp; i++)
 			{
-				strcat(buffer, GetWord(wdtemp[i]));
-				strcat(buffer, " ");
+				Common::strcat_s(buffer, GetWord(wdtemp[i]));
+				Common::strcat_s(buffer, " ");
 			}
 			SeparateWords();
 
@@ -1448,7 +1448,7 @@ RestoreTempArrays:
 			i = Peek(grammaraddr);
 			if (objcount>1 && i!=MULTI_T && i!=MULTIHELD_T && i!=MULTINOTHELD_T)
 			{
-				strcpy(parseerr, word[1]);
+				Common::strcpy_s(parseerr, word[1]);
 				/* "You can't...multiple objects." */
 				ParseError(3, 0);
 				return false;
@@ -1578,7 +1578,7 @@ RestoreTempArrays:
 			else
 			{
 				/* No objects found */
-				strcpy(parseerr, word[1]);
+				Common::strcpy_s(parseerr, word[1]);
 				ParseError(9, 0);   /* "Nothing to (verb)..." */
 				return false;
 			}
@@ -1588,7 +1588,7 @@ RestoreTempArrays:
 	/* Go back for the next object phrase */
 	pobjcount = 0;
 	mobjs = 0;
-	strcpy(parseerr, "");
+	parseerr[0] = '\0';
 
 	goto NextLoop;
 }
@@ -1771,7 +1771,7 @@ CheckWordorString:
 							multicheck != MULTIHELD_T &&
 							multicheck != MULTINOTHELD_T)
 						{
-							strcpy(parseerr, word[1]);
+							Common::strcpy_s(parseerr, word[1]);
 							/* "You can't...multiple objects." */
 							ParseError(3, 0);
 							return 2;
@@ -1968,14 +1968,14 @@ int Hugo::Parse() {
 	period = FindWord(".");
 	comma = FindWord(",");
 
-	strcpy(parsestr, "");           /* for storing any unknown string */
+	parsestr[0] = '\0';             /* for storing any unknown string */
 	parsed_number = 0;              /*  "     "     "  parsed number  */
 
 	for (i=1; i<=words; i++)        /* find dictionary addresses */
 	{
 		if (word[i][0]=='\"' && foundstring==0)
 		{
-			strcpy(parsestr, word[i]);
+			Common::strcpy_s(parsestr, word[i]);
 			foundstring = 1;
 			wd[i] = UNKNOWN_WORD;
 		}
@@ -1992,7 +1992,7 @@ int Hugo::Parse() {
 #endif
 				parsed_number = atoi(word[i]);
 				if (parseerr[0]=='\0')
-					strcpy(parseerr, word[i]);
+					Common::strcpy_s(parseerr, word[i]);
 			}
 
 			/* Otherwise it must be a dictionary entry */
@@ -2004,8 +2004,8 @@ int Hugo::Parse() {
 NotinDictionary:
 					if (!notfound_word)
 					{
-						strcpy(parseerr, word[i]);
-						strcpy(oops, word[i]);
+						Common::strcpy_s(parseerr, word[i]);
+						Common::strcpy_s(oops, word[i]);
 
 						notfound_word = i;
 					}
@@ -2023,11 +2023,11 @@ NotinDictionary:
 
 		/* "...can't use the word..." */
 		ParseError(1, 0);
-		strcpy(errbuf, "");
+		errbuf[0] = '\0';
 		for (i=1; i<=words; i++)
 		{
-			strcat(errbuf, word[i]);
-			if (i != words) strcat(errbuf, " ");
+			Common::strcat_s(errbuf, word[i]);
+			if (i != words) Common::strcat_s(errbuf, " ");
 		}
 
 		return 0;
@@ -2058,19 +2058,19 @@ NotinDictionary:
 						if (m)
 						{
 							if (m + (int)strlen(buffer) > 81)
-								{strcpy(buffer, "");
+								{buffer[0] = '\0';
 								words = 0;
 								ParseError(0, 0);
 								return 0;}
 
 							for (k=words; k>i; k--)
 							{
-								strcpy(tempword, word[k]);
+								Common::strcpy_s(tempword, word[k]);
 								word[k] += m;
-								strcpy(word[k], tempword);
+								Common::strcpy_s(word[k], sizeof(buffer) - (word[k] - buffer), tempword);
 							}
 						}
-						strcpy(word[i], GetWord(wd[i]));
+						Common::strcpy_s(word[i], sizeof(buffer) - (word[i] - buffer), GetWord(wd[i]));
 						i--;
 						break;
 					}
@@ -2086,7 +2086,7 @@ NotinDictionary:
 					{
 						if (wd[i+1]==PeekWord(synptr+3))
 						{
-							strcat(word[i], word[i+1]);
+							Common::strcat_s(word[i], sizeof(buffer) - (word[i] - buffer), word[i+1]);
 							wd[i] = FindWord(word[i]);
 							KillWord(i+1);
 						}
@@ -2120,7 +2120,7 @@ NextSyn:
 
 	defseg = gameseg;
 
-	if (strcmp(word[1], "~oops")) strcpy(oops, "");
+	if (strcmp(word[1], "~oops")) oops[0] = '\0';
 
 	if (words==0)
 	{
@@ -2211,13 +2211,13 @@ void Hugo::ParseError(int e, int a) {
 				{
 					if (count==pobjcount)
 					{
-						if (count > 2) strcat(line, ",");
-						strcat(line, " or ");
+						if (count > 2) Common::strcat_s(line, ",");
+						Common::strcat_s(line, " or ");
 					}
 					else
 					{
 						if (count != 1)
-							strcat(line, ", ");
+							Common::strcat_s(line, ", ");
 					}
 					if (GetProp(i, article, 1, 0))
 					{
@@ -2225,18 +2225,18 @@ void Hugo::ParseError(int e, int a) {
 						/* Don't use "a" or "an" in listing */
 						/*
 						if (!strcmp(w, "a") || !strcmp(w, "an"))
-							strcat(line, "the ");
+							Common::strcat_s(line, "the ");
 						else
 							sprintf(line+strlen(line), "%s ", w);
 						*/
 						/* We'll just use "the" */
-						if (w) strcat(line, "the ");
+						if (w) Common::strcat_s(line, "the ");
 					}
-					strcat(line, Name(i));
+					Common::strcat_s(line, Name(i));
 					count++;
 				}
 			}
-			strcat(line, "?");
+			Common::strcat_s(line, "?");
 			AP(line);
 			break;
 		}
@@ -2338,8 +2338,8 @@ void Hugo::SeparateWords() {
 	}
 	word[1] = buffer;
 
-	strcpy(a, buffer);
-	strcpy(buffer, "");
+	Common::strcpy_s(a, buffer);
+	buffer[0] = '\0';
 
 	for (i=1; i<=(int)strlen(a); i++)
 	{
@@ -2350,7 +2350,7 @@ void Hugo::SeparateWords() {
 
 		if (b[0]=='\"' && inquote==1)
 		{
-			strcpy(buffer+bloc, b);
+			Common::strcpy_s(buffer+bloc, sizeof(buffer)-bloc, b);
 			bloc++;
 			inquote++;
 		}
@@ -2362,12 +2362,12 @@ void Hugo::SeparateWords() {
 				bloc++;
 				if (++words > MAXWORDS) words = MAXWORDS;
 				word[words] = buffer + bloc;
-				strcpy(word[words], "");
+				word[words][0] = '\0';
 			}
 
 			if (b[0]=='\"' && inquote==0)
 			{
-				strcpy(buffer+bloc, b);
+				Common::strcpy_s(buffer+bloc, sizeof(buffer)-bloc, b);
 				bloc++;
 				inquote = 1;
 			}
@@ -2382,15 +2382,15 @@ void Hugo::SeparateWords() {
 					if (++words > MAXWORDS) words = MAXWORDS;
 				}
 				word[words] = buffer + bloc;
-				strcpy(word[words], b);
+				Common::strcpy_s(word[words], sizeof(buffer)-bloc, b);
 				bloc += strlen(b) + 1;
 				if (++words > MAXWORDS) words = MAXWORDS;
 				word[words] = buffer + bloc;
-				strcpy(word[words], "");
+				word[words][0] = '\0';
 			}
 			else
 			{
-				strcpy(buffer+bloc, b);
+				Common::strcpy_s(buffer+bloc, sizeof(buffer)-bloc, b);
 				bloc++;
 			}
 		}
@@ -2403,13 +2403,13 @@ void Hugo::SeparateWords() {
 		/* Convert hours:minutes time to minutes only */
 		if (strcspn(word[i], ":")!=strlen(word[i]) && strlen(word[i])<=5)
 		{
-			strcpy(w1, Left(word[i], strcspn(word[i], ":")));
-			strcpy(w2, Right(word[i], strlen(word[i]) - strcspn(word[i], ":") - 1));
+			Common::strcpy_s(w1, Left(word[i], strcspn(word[i], ":")));
+			Common::strcpy_s(w2, Right(word[i], strlen(word[i]) - strcspn(word[i], ":") - 1));
 			n1 = (short)atoi(w1);
 			n2 = (short)atoi(w2);
 
 			if (!strcmp(Left(w2, 1), "0"))
-				strcpy(w2, Right(w2, strlen(w2) - 1));
+				Common::strcpy_s(w2, Right(w2, strlen(w2) - 1));
 
 			/* If this is indeed a hh:mm time, write it back
 			   as the modified word, storing the original hh:mm
@@ -2417,7 +2417,7 @@ void Hugo::SeparateWords() {
 			*/
 			if (!strcmp(w1, itoa((int)n1, temp, 10)) && !strcmp(w2, itoa((int)n2, temp, 10)) && (n1 > 0 && n1 < 25) && (n2 >= 0 && n2 < 60))
 			{
-				strcpy(parseerr, word[i]);
+				Common::strcpy_s(parseerr, word[i]);
 				itoa(n1 * 60 + n2, word[i], 10);
 			}
 		}
@@ -2538,10 +2538,10 @@ int Hugo::ValidObj(int obj) {
 			{
 				if (obj != (int)PeekWord(grammaraddr+2))
 				{
-					strcpy(parseerr, "");
+					parseerr[0] = '\0';
 					if (GetProp(obj, article, 1, 0))
-						strcpy(parseerr, "the ");
-					strcat(parseerr, Name(obj));
+						Common::strcpy_s(parseerr, "the ");
+					Common::strcat_s(parseerr, Name(obj));
 
 					/* "...can't do that with..." */
 					ParseError(12, obj);
@@ -2562,10 +2562,10 @@ int Hugo::ValidObj(int obj) {
 			*/
 			if (!TestAttribute(obj, attr, nattr))
 			{
-				strcpy(parseerr, "");
+				parseerr[0] = '\0';
 				if (GetProp(obj, article, 1, 0))
-					strcpy(parseerr, "the ");
-				strcat(parseerr, Name(obj));
+					Common::strcpy_s(parseerr, "the ");
+				Common::strcat_s(parseerr, Name(obj));
 
 				/* "...can't do that with..." */
 				ParseError(12, obj);
diff --git a/engines/glk/hugo/heres.cpp b/engines/glk/hugo/heres.cpp
index dddd9862aed..db8a0a75ce4 100644
--- a/engines/glk/hugo/heres.cpp
+++ b/engines/glk/hugo/heres.cpp
@@ -255,9 +255,9 @@ long Hugo::FindResource(const char *filename, const char *resname) {
 
 	resource_file = nullptr;
 
-	strcpy(loaded_filename, filename);
-	strcpy(loaded_resname, resname);
-	if (!strcmp(filename, "")) strcpy(loaded_filename, resname);
+	Common::strcpy_s(loaded_filename, filename);
+	Common::strcpy_s(loaded_resname, resname);
+	if (!strcmp(filename, "")) Common::strcpy_s(loaded_filename, resname);
 
 	/* See if the file is supposed to be in a resourcefile to
 	   begin with
@@ -433,12 +433,12 @@ int Hugo::GetResourceParameters(char *filename, char *resname, int restype) {
 		return 0;
 	}
 
-	strcpy(filename, GetWord((unsigned int)f));
+	Common::strcpy_s(filename, MAX_RES_PATH, GetWord((unsigned int)f));
 
 	if (MEM(codeptr++)!=EOL_T)	/* two or more parameters */
 	{
 		strupr(filename);
-		strcpy(resname, GetWord(GetValue()));
+		Common::strcpy_s(resname, MAX_RES_PATH, GetWord(GetValue()));
 		if (MEM(codeptr++)==COMMA_T)
 		{
 			extra_param = GetValue();
@@ -447,8 +447,8 @@ int Hugo::GetResourceParameters(char *filename, char *resname, int restype) {
 	}
 	else				/* only one parameter */
 	{
-		strcpy(resname, filename);
-		strcpy(filename, "");
+		Common::strcpy_s(resname, MAX_RES_PATH, filename);
+		filename[0] = '\0';
 	}
 
 	return true;
diff --git a/engines/glk/hugo/herun.cpp b/engines/glk/hugo/herun.cpp
index 31eaac68ea1..8815d40352b 100644
--- a/engines/glk/hugo/herun.cpp
+++ b/engines/glk/hugo/herun.cpp
@@ -176,8 +176,8 @@ RestartDebugger:
 
 Start:
 	stack_depth = 0;
-	strcpy(errbuf, "");
-	strcpy(oops, "");
+	errbuf[0] = '\0';
+	oops[0] = '\0';
 
 #if defined (GLK)
 	// Handle any savegame selected directly from the ScummVM launcher
@@ -277,7 +277,7 @@ FreshInput:
 							// Trigger a "look" command so that players will get some initial text
 							// after loading a savegame directly from the launcher
 							_savegameSlot = -1;
-							strcpy(buffer, "look");
+							Common::strcpy_s(buffer, "look");
 						}
 						else
 #endif
@@ -349,7 +349,7 @@ RecordedNewline:;
 
 					if (!strcmp(buffer, "") || buffer[0]=='.')
 					{
-						strcpy(parseerr, "");
+						parseerr[0] = '\0';
 
 						/* "What?" */
 						ParseError(0, 0);
@@ -412,13 +412,13 @@ Skipmc:;
 		{
 			if (parsestr[0]=='\"')
 			{
-				strcpy(parseerr, Right(parsestr, strlen(parsestr)-1));
+				Common::strcpy_s(parseerr, Right(parsestr, strlen(parsestr)-1));
 				if (parseerr[strlen(parseerr)-1]=='\"')
 					parseerr[strlen(parseerr)-1] = '\0';
 			}
 		}
 		else
-			strcpy(parseerr, "");
+			parseerr[0] = '\0';
 
 		/* default actor */
 		var[actor] = var[player];
@@ -487,7 +487,7 @@ NextPerform:
 					   trash passlocal[])
 					*/
 					if (parseerr[0]=='\0' && parsestr[0]=='\0')
-						strcpy(parseerr, Name(objlist[i]));
+						Common::strcpy_s(parseerr, Name(objlist[i]));
 
 					/* Set up arguments for Perform */
 					passlocal[0] = var[verbroutine];
@@ -544,7 +544,7 @@ NextPerform:
 					for (i=0; i<objcount; i++)
 					{
 						if (parseerr[0]=='\0' && parsestr[0]=='\0')
-							strcpy(parseerr, Name(objlist[i]));
+							Common::strcpy_s(parseerr, Name(objlist[i]));
 
 						if (ValidObj(objlist[i]) &&
 							((objcount>1 && objlist[i]!=var[xobject]) || objcount==1))
@@ -830,7 +830,7 @@ PasstoBlock:
 void Hugo::RunInput() {
 	int i;
 
-	strcpy(parseerr, "");
+	parseerr[0] = '\0';
 
 	Flushpbuffer();
 
@@ -842,7 +842,7 @@ void Hugo::RunInput() {
 	if (debugger_collapsing) return;
 #endif
 
-	strcpy(buffer, Rtrim(strlwr(buffer)));
+	Common::strcpy_s(buffer, Rtrim(strlwr(buffer)));
 
 	SeparateWords();
 
@@ -854,10 +854,10 @@ void Hugo::RunInput() {
 		if (wd[i]==UNKNOWN_WORD)
 		{
 			wd[i] = 0;
-			strcpy(parseerr, word[i]);
+			Common::strcpy_s(parseerr, word[i]);
 			if (parseerr[0]=='\"')
 			{
-				strcpy(parseerr, Right(parseerr, strlen(parseerr)-1));
+				Common::strcpy_s(parseerr, Right(parseerr, strlen(parseerr)-1));
 				if (parseerr[strlen(parseerr)-1]=='\"')
 					parseerr[strlen(parseerr)-1] = '\0';
 			}
@@ -933,7 +933,7 @@ void Hugo::RunPrint() {
 
 	while (MEM(codeptr) != EOL_T)
 	{
-		strcpy(line, "");
+		line[0] = '\0';
 
 		switch (MEM(codeptr))
 		{
@@ -968,7 +968,7 @@ void Hugo::RunPrint() {
 					a = (int)(ACTUAL_LINELENGTH() / ratio);
 				}
 #endif
-				strcpy(line, "");
+				line[0] = '\0';
 				l = 0;
 				if (a*FIXEDCHARWIDTH >
 					hugo_textwidth(pbuffer)+currentpos-hugo_charwidth(' '))
@@ -1031,7 +1031,7 @@ void Hugo::RunPrint() {
 				a = GetValue();
 				if (!number)
 				{
-					strcpy(line, GetWord(a));
+					Common::strcpy_s(line, GetWord(a));
 				}
 				else
 				{
@@ -1061,7 +1061,7 @@ void Hugo::RunPrint() {
 		if (MEM(codeptr)==SEMICOLON_T)
 		{
 			codeptr++;
-			strcat(line, "\\;");
+			Common::strcat_s(line, "\\;");
 		}
 		if (capital)
 		{
@@ -1329,14 +1329,14 @@ void Hugo::RunRoutine(long addr) {
 			/* If not object.property or an event */
 			if (strchr(debug_line, '.')==nullptr && strstr(debug_line, "vent ")==nullptr)
 			{
-				strcat(debug_line, "(");
+				Common::strcat_s(debug_line, "(");
 				for (i=0; i<arguments_passed; i++)
 				{
 					sprintf(debug_line+strlen(debug_line), "%d", var[MAXGLOBALS+i]);
 					if (i<arguments_passed-1)
-						strcat(debug_line, ", ");
+						Common::strcat_s(debug_line, ", ");
 				}
-				strcat(debug_line, ")");
+				Common::strcat_s(debug_line, ")");
 			}
 			AddStringtoCodeWindow(debug_line);
 		}
@@ -1556,7 +1556,7 @@ ProcessToken:
 						/* If it doesn't exist, add it */
 						if (i==current_locals)
 						{
-							strcpy(localname[current_locals], line);
+							Common::strcpy_s(localname[current_locals], line);
 							if (++current_locals==MAXLOCALS)
 								current_locals--;
 							window[VIEW_LOCALS].count = current_locals;
@@ -1576,10 +1576,10 @@ ProcessToken:
 			case TEXTDATA_T:        /* printed text from file */
 			{
 				textaddr = Peek(codeptr+1)*65536L+(long)PeekWord(codeptr+2);
-				strcpy(line, GetText(textaddr));
+				Common::strcpy_s(line, GetText(textaddr));
 				codeptr += 4;
 				if (Peek(codeptr)==SEMICOLON_T)
-					{strcat(line, "\\;");
+					{Common::strcat_s(line, "\\;");
 					codeptr++;}
 				if (capital)
 					{line[0] = (char)toupper((int)line[0]);
@@ -2104,7 +2104,7 @@ ReturnfromRoutine:
 			{
 				sprintf(debug_line+strlen(debug_line), " to %s", RoutineName(old_currentroutine));
 			}
-			strcat(debug_line, ")");
+			Common::strcat_s(debug_line, ")");
 			AddStringtoCodeWindow(debug_line);
 			AddStringtoCodeWindow("");
 
@@ -2253,7 +2253,7 @@ int Hugo::RunString() {
 		maxlen = GetValue();
 	if (Peek(codeptr)==CLOSE_BRACKET_T) codeptr++;
 
-	strcpy(line, GetWord(dword));
+	Common::strcpy_s(line, GetWord(dword));
 
 	defseg = arraytable;
 	pos = 0;
diff --git a/engines/glk/hugo/heset.cpp b/engines/glk/hugo/heset.cpp
index a187b6b1d99..eda485c5be9 100644
--- a/engines/glk/hugo/heset.cpp
+++ b/engines/glk/hugo/heset.cpp
@@ -137,12 +137,12 @@ GetNextWord:
 			/* Have to (rather unfortunately) rebuild the entire
 			   input buffer and word array here
 			*/
-			strcpy(buffer, "");
+			buffer[0] = '\0';
 			t = 0;
 			for (a=1; a<=(int)MAXWORDS; a++)
 			{
 				if ((unsigned short)wd[a]!=UNKNOWN_WORD)
-					strcpy(buffer+t, GetWord(wd[a]));
+					Common::strcpy_s(buffer+t, sizeof(buffer) - t, GetWord(wd[a]));
 				else
 					itoa(parsed_number, buffer+t, 10);
 			        word[a] = buffer + t;
diff --git a/engines/glk/hugo/hugo.cpp b/engines/glk/hugo/hugo.cpp
index 21257fdbab8..8d3fd34579a 100644
--- a/engines/glk/hugo/hugo.cpp
+++ b/engines/glk/hugo/hugo.cpp
@@ -83,7 +83,7 @@ Hugo::Hugo(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gam
 #endif
 		{
 	g_vm = this;
-	strcpy(gamefile, "");
+	gamefile[0] = '\0';
 
 	// heexpr
 	Common::fill(&eval[0], &eval[MAX_EVAL_ELEMENTS], 0);
@@ -146,8 +146,8 @@ void Hugo::runGame() {
 
 	SetupDisplay();
 
-	strcpy(gamefile, getFilename().c_str());
-	strcpy(pbuffer, "");
+	Common::strcpy_s(gamefile, getFilename().c_str());
+	pbuffer[0] = '\0';
 
 	ResourceArchive *res = new ResourceArchive();
 	SearchMan.add("Resouces", res);
diff --git a/engines/glk/hugo/stringfn.cpp b/engines/glk/hugo/stringfn.cpp
index 1b518495e5b..0aa01b4b855 100644
--- a/engines/glk/hugo/stringfn.cpp
+++ b/engines/glk/hugo/stringfn.cpp
@@ -43,7 +43,7 @@ char *StringFunctions::Ltrim(char a[]) {
 	int len = strlen(a);
 
 	temp = GetTempString();
-	strcpy(temp, a);
+	Common::strcpy_s(temp, sizeof(_tempString[0]), a);
 	while (temp[0]==' ' || temp[0]=='\t')
 		memmove(temp, temp+1, len + 1);
 	return temp;
@@ -81,9 +81,9 @@ char *StringFunctions::Rtrim(char a[]) {
 	int len;
 
 	temp = GetTempString();
-	strcpy(temp, a);
+	Common::strcpy_s(temp, sizeof(_tempString[0]), a);
 	while (((len = strlen(temp))) && (temp[len-1]==' ' || temp[len-1]=='\t'))
-		strcpy(temp, Left(temp, len-1));
+		Common::strcpy_s(temp, sizeof(_tempString[0]), Left(temp, len-1));
 	return temp;
 }
 
diff --git a/engines/glk/jacl/display.cpp b/engines/glk/jacl/display.cpp
index 6c9fe7e1a93..9d30a4d0e49 100644
--- a/engines/glk/jacl/display.cpp
+++ b/engines/glk/jacl/display.cpp
@@ -59,11 +59,11 @@ int check_light(int where) {
 
 char *sentence_output(int index, int capital) {
 	if (!strcmp(object[index]->article, "name")) {
-		strcpy(temp_buffer, object[index]->inventory);
+		Common::strcpy_s(temp_buffer, 1024, object[index]->inventory);
 	} else {
-		strcpy(temp_buffer, object[index]->definite);
-		strcat(temp_buffer, " ");
-		strcat(temp_buffer, object[index]->inventory);
+		Common::strcpy_s(temp_buffer, 1024, object[index]->definite);
+		Common::strcat_s(temp_buffer, 1024, " ");
+		Common::strcat_s(temp_buffer, 1024, object[index]->inventory);
 	}
 
 	if (capital)
@@ -88,18 +88,18 @@ char *is_output(int index, bool) {
 
 char *sub_output(int index, int capital) {
 	if (object[index]->attributes & PLURAL) {
-		strcpy(temp_buffer, cstring_resolve("THEY_WORD")->value);
+		Common::strcpy_s(temp_buffer, 1024, cstring_resolve("THEY_WORD")->value);
 	} else {
 		if (index == player) {
-			strcpy(temp_buffer, cstring_resolve("YOU_WORD")->value);
+			Common::strcpy_s(temp_buffer, 1024, cstring_resolve("YOU_WORD")->value);
 		} else if (object[index]->attributes & ANIMATE) {
 			if (object[index]->attributes & FEMALE) {
-				strcpy(temp_buffer, cstring_resolve("SHE_WORD")->value);
+				Common::strcpy_s(temp_buffer, 1024, cstring_resolve("SHE_WORD")->value);
 			} else {
-				strcpy(temp_buffer, cstring_resolve("HE_WORD")->value);
+				Common::strcpy_s(temp_buffer, 1024, cstring_resolve("HE_WORD")->value);
 			}
 		} else {
-			strcpy(temp_buffer, cstring_resolve("IT_WORD")->value);
+			Common::strcpy_s(temp_buffer, 1024, cstring_resolve("IT_WORD")->value);
 		}
 	}
 
@@ -111,18 +111,18 @@ char *sub_output(int index, int capital) {
 
 char *obj_output(int index, int capital) {
 	if (object[index]->attributes & PLURAL) {
-		strcpy(temp_buffer, cstring_resolve("THEM_WORD")->value);
+		Common::strcpy_s(temp_buffer, 1024, cstring_resolve("THEM_WORD")->value);
 	} else {
 		if (index == player) {
-			strcpy(temp_buffer, cstring_resolve("YOURSELF_WORD")->value);
+			Common::strcpy_s(temp_buffer, 1024, cstring_resolve("YOURSELF_WORD")->value);
 		} else if (object[index]->attributes & ANIMATE) {
 			if (object[index]->attributes & FEMALE) {
-				strcpy(temp_buffer, cstring_resolve("HER_WORD")->value);
+				Common::strcpy_s(temp_buffer, 1024, cstring_resolve("HER_WORD")->value);
 			} else {
-				strcpy(temp_buffer, cstring_resolve("HIM_WORD")->value);
+				Common::strcpy_s(temp_buffer, 1024, cstring_resolve("HIM_WORD")->value);
 			}
 		} else {
-			strcpy(temp_buffer, cstring_resolve("IT_WORD")->value);
+			Common::strcpy_s(temp_buffer, 1024, cstring_resolve("IT_WORD")->value);
 		}
 	}
 
@@ -146,9 +146,9 @@ char *it_output(int index, bool) {
 
 char *that_output(int index, int capital) {
 	if (object[index]->attributes & PLURAL) {
-		strcpy(temp_buffer, cstring_resolve("THOSE_WORD")->value);
+		Common::strcpy_s(temp_buffer, 1024, cstring_resolve("THOSE_WORD")->value);
 	} else {
-		strcpy(temp_buffer, cstring_resolve("THAT_WORD")->value);
+		Common::strcpy_s(temp_buffer, 1024, cstring_resolve("THAT_WORD")->value);
 	}
 
 	if (capital)
@@ -173,11 +173,11 @@ char *does_output(int index, bool) {
 
 char *list_output(int index, int capital) {
 	if (!strcmp(object[index]->article, "name")) {
-		strcpy(temp_buffer, object[index]->inventory);
+		Common::strcpy_s(temp_buffer, 1024, object[index]->inventory);
 	} else {
-		strcpy(temp_buffer, object[index]->article);
-		strcat(temp_buffer, " ");
-		strcat(temp_buffer, object[index]->inventory);
+		Common::strcpy_s(temp_buffer, 1024, object[index]->article);
+		Common::strcat_s(temp_buffer, 1024, " ");
+		Common::strcat_s(temp_buffer, 1024, object[index]->inventory);
 	}
 
 	if (capital)
@@ -187,7 +187,7 @@ char *list_output(int index, int capital) {
 }
 
 char *plain_output(int index, int capital) {
-	strcpy(temp_buffer, object[index]->inventory);
+	Common::strcpy_s(temp_buffer, 1024, object[index]->inventory);
 
 	if (capital)
 		temp_buffer[0] = toupper(temp_buffer[0]);
@@ -197,8 +197,8 @@ char *plain_output(int index, int capital) {
 
 char *long_output(int index) {
 	if (!strcmp(object[index]->described, "function")) {
-		strcpy(function_name, "long_");
-		strcat(function_name, object[index]->label);
+		Common::strcpy_s(function_name, 1024, "long_");
+		Common::strcat_s(function_name, 1024, object[index]->label);
 		if (execute(function_name) == FALSE) {
 			unkfunrun(function_name);
 		}
@@ -241,8 +241,8 @@ void look_around() {
 		object[HERE]->attributes &= ~1L;
 	}
 
-	strcpy(function_name, "look_");
-	strcat(function_name, object[HERE]->label);
+	Common::strcpy_s(function_name, 81, "look_");
+	Common::strcat_s(function_name, 81, object[HERE]->label);
 	execute(function_name);
 
 	/* GIVE THE LOCATION THE ATTRIBUTES 'VISITED', 'KNOWN', AND 'MAPPED' NOW
@@ -253,8 +253,8 @@ void look_around() {
 
 	execute("+object_descriptions");
 
-	strcpy(function_name, "after_look_");
-	strcat(function_name, object[HERE]->label);
+	Common::strcpy_s(function_name, 81, "after_look_");
+	Common::strcat_s(function_name, 81, object[HERE]->label);
 	execute(function_name);
 
 	execute("+after_look");
diff --git a/engines/glk/jacl/interpreter.cpp b/engines/glk/jacl/interpreter.cpp
index 2a4830a0f9a..93e5c95ad1f 100644
--- a/engines/glk/jacl/interpreter.cpp
+++ b/engines/glk/jacl/interpreter.cpp
@@ -307,7 +307,7 @@ void build_proxy() {
 	/* LOOP THROUGH ALL THE PARAMETERS OF THE PROXY COMMAND
 	   AND BUILD THE MOVE TO BE ISSUED ON THE PLAYER'S BEHALF */
 	for (index = 1; word[index] != nullptr; index++) {
-		strcat(proxy_buffer, text_of_word(index));
+		Common::strcat_s(proxy_buffer, 1024, text_of_word(index));
 	}
 
 	for (index = 0; index < (int)strlen(proxy_buffer); index++) {
@@ -588,11 +588,11 @@ int execute(const char *funcname) {
 				// infile REMAINS OPEN DURING THE ITERATION, ONLY NEEDS
 				// OPENING THE FIRST TIME
 				if (infile == nullptr) {
-					strcpy(temp_buffer, data_directory);
-					strcat(temp_buffer, prefix);
-					strcat(temp_buffer, "-");
-					strcat(temp_buffer, text_of_word(1));
-					strcat(temp_buffer, ".csv");
+					Common::strcpy_s(temp_buffer, 1024, data_directory);
+					Common::strcat_s(temp_buffer, 1024, prefix);
+					Common::strcat_s(temp_buffer, 1024, "-");
+					Common::strcat_s(temp_buffer, 1024, text_of_word(1));
+					Common::strcat_s(temp_buffer, 1024, ".csv");
 
 					infile = File::openForReading(temp_buffer);
 
@@ -662,24 +662,24 @@ int execute(const char *funcname) {
 				// infile REMAINS OPEN DURING THE ITERATION, ONLY NEEDS
 				// OPENING THE FIRST TIME
 				if (infile == nullptr) {
-					strcpy(in_name, data_directory);
-					strcat(in_name, prefix);
-					strcat(in_name, "-");
-					strcat(in_name, text_of_word(1));
-					strcat(in_name, ".csv");
+					Common::strcpy_s(in_name, data_directory);
+					Common::strcat_s(in_name, prefix);
+					Common::strcat_s(in_name, "-");
+					Common::strcat_s(in_name, text_of_word(1));
+					Common::strcat_s(in_name, ".csv");
 
 					infile = File::openForReading(in_name);
 				}
 
 				if (outfile == nullptr) {
 					// OPEN A TEMPORARY OUTPUT FILE TO WRITE THE MODIFICATIONS TO
-					strcpy(out_name, data_directory);
-					strcat(out_name, prefix);
-					strcat(out_name, "-");
-					strcat(out_name, text_of_word(1));
-					strcat(out_name, "-");
-					strcat(out_name, user_id);
-					strcat(out_name, ".csv");
+					Common::strcpy_s(out_name, data_directory);
+					Common::strcat_s(out_name, prefix);
+					Common::strcat_s(out_name, "-");
+					Common::strcat_s(out_name, text_of_word(1));
+					Common::strcat_s(out_name, "-");
+					Common::strcat_s(out_name, user_id);
+					Common::strcat_s(out_name, ".csv");
 
 					outfile = File::openForWriting(out_name);
 				}
@@ -874,10 +874,10 @@ int execute(const char *funcname) {
 
 				if (word[1][0] == '!') {
 					criterion_negate = TRUE;
-					strcpy(argument_buffer, &word[1][1]);
+					Common::strcpy_s(argument_buffer, &word[1][1]);
 				} else {
 					criterion_negate = FALSE;
-					strcpy(argument_buffer, word[1]);
+					Common::strcpy_s(argument_buffer, word[1]);
 				}
 
 				// DETERMINE THE CRITERION FOR SELETION
@@ -1629,7 +1629,7 @@ int execute(const char *funcname) {
 					string_buffer[0] = 0;
 
 					for (counter = 1; word[counter] != nullptr && counter < MAX_WORDS; counter++) {
-						strcat(string_buffer, arg_text_of_word(counter));
+						Common::strcat_s(string_buffer, arg_text_of_word(counter));
 					}
 
 					if (function_resolve(string_buffer) == nullptr && !strcmp(word[0], "execute")) {
@@ -1734,7 +1734,7 @@ int execute(const char *funcname) {
 						} else if (text_buffer[index - 1] != '^') {
 							// ADD AN IMPLICIT SPACE IF THE PREVIOUS LINE
 							// DIDN'T END WITH A CARRIAGE RETURN
-							strcat(text_buffer, " ");
+							Common::strcat_s(text_buffer, 1024, " ");
 						}
 
 						// OUTPUT THE LINE READ AS PLAIN TEXT
@@ -1838,8 +1838,8 @@ int execute(const char *funcname) {
 				char *match = nullptr;
 				struct string_type *resolved_splitstring = nullptr;
 
-				strcpy(split_buffer, text_of_word(2));
-				strcpy(delimiter, text_of_word(3));
+				Common::strcpy_s(split_buffer, text_of_word(2));
+				Common::strcpy_s(delimiter, text_of_word(3));
 
 				char *source = split_buffer;
 
@@ -1860,32 +1860,32 @@ int execute(const char *funcname) {
 
 						while ((match = strstr(source, delimiter))) {
 							*match = 0;
-							strcpy(container_buffer, var_text_of_word(4));
-							strcat(container_buffer, "[");
+							Common::strcpy_s(container_buffer, var_text_of_word(4));
+							Common::strcat_s(container_buffer, "[");
 							sprintf(integer_buffer, "%d", *split_container);
-							strcat(container_buffer, integer_buffer);
-							strcat(container_buffer, "]");
+							Common::strcat_s(container_buffer, integer_buffer);
+							Common::strcat_s(container_buffer, "]");
 
 							if ((resolved_splitstring = string_resolve(container_buffer)) == nullptr) {
 								unkstrrun(var_text_of_word(4));
 								return (exit_function(TRUE));
 							} else {
-								strcpy(resolved_splitstring->value, source);
+								Common::strcpy_s(resolved_splitstring->value, source);
 								source = match + strlen(delimiter);
 								(*split_container)++;
 							}
 						}
-						strcpy(container_buffer, var_text_of_word(4));
-						strcat(container_buffer, "[");
+						Common::strcpy_s(container_buffer, var_text_of_word(4));
+						Common::strcat_s(container_buffer, "[");
 						sprintf(integer_buffer, "%d", *split_container);
-						strcat(container_buffer, integer_buffer);
-						strcat(container_buffer, "]");
+						Common::strcat_s(container_buffer, integer_buffer);
+						Common::strcat_s(container_buffer, "]");
 
 						if ((resolved_splitstring = string_resolve(container_buffer)) == nullptr) {
 							unkstrrun(word[1]);
 							return (exit_function(TRUE));
 						} else {
-							strcpy(resolved_splitstring->value, source);
+							Common::strcpy_s(resolved_splitstring->value, source);
 							(*split_container)++;
 						}
 					}
@@ -1908,7 +1908,7 @@ int execute(const char *funcname) {
 
 					/* RESOLVE ALL THE TEXT AND STORE IT IN A TEMPORARY BUFFER*/
 					for (counter = 2; word[counter] != nullptr && counter < MAX_WORDS; counter++) {
-						strcat(setstring_buffer, text_of_word(counter));
+						Common::strcat_s(setstring_buffer, text_of_word(counter));
 					}
 
 					/* setstring_buffer IS NOW FILLED, COPY THE UP TO 256 BYTES OF
@@ -1941,7 +1941,7 @@ int execute(const char *funcname) {
 					index = value_of(word[3], TRUE);
 
 					for (counter = 0; counter < index; counter++) {
-						strcat(setstring_buffer, text_of_word(2));
+						Common::strcat_s(setstring_buffer, text_of_word(2));
 					}
 
 					/* setstring_buffer IS NOW FILLED, COPY THE UP TO 256 BYTES OF
@@ -2184,11 +2184,11 @@ int execute(const char *funcname) {
 					noproprun();
 					return (exit_function(TRUE));
 				} else {
-					strcpy(temp_buffer, data_directory);
-					strcat(temp_buffer, prefix);
-					strcat(temp_buffer, "-");
-					strcat(temp_buffer, text_of_word(1));
-					strcat(temp_buffer, ".csv");
+					Common::strcpy_s(temp_buffer, 1024, data_directory);
+					Common::strcat_s(temp_buffer, 1024, prefix);
+					Common::strcat_s(temp_buffer, 1024, "-");
+					Common::strcat_s(temp_buffer, 1024, text_of_word(1));
+					Common::strcat_s(temp_buffer, 1024, ".csv");
 
 					outfile = File::openForWriting(temp_buffer);
 
@@ -2310,7 +2310,7 @@ int execute(const char *funcname) {
 					string_buffer[0] = 0;
 
 					for (counter = 1; word[counter] != nullptr && counter < MAX_WORDS; counter++) {
-						strcat(string_buffer, arg_text_of_word(counter));
+						Common::strcat_s(string_buffer, arg_text_of_word(counter));
 					}
 
 					if (execute(string_buffer)) {
@@ -2397,8 +2397,8 @@ char *object_names(int object_index, char *names_buffer) {
 	names_buffer[0] = 0;
 
 	while (current_name != nullptr) {
-		strcat(names_buffer, " ");
-		strcat(names_buffer, current_name->name);
+		Common::strcat_s(names_buffer, 1024, " ");
+		Common::strcat_s(names_buffer, 1024, current_name->name);
 		current_name = current_name->next_name;
 	}
 
diff --git a/engines/glk/jacl/jacl_main.cpp b/engines/glk/jacl/jacl_main.cpp
index 8334d75784c..4f5cfb968ca 100644
--- a/engines/glk/jacl/jacl_main.cpp
+++ b/engines/glk/jacl/jacl_main.cpp
@@ -283,7 +283,7 @@ void glk_main() {
 		status_line();
 
 		if (current_command != nullptr) {
-			strcpy(last_command, current_command);
+			Common::strcpy_s(last_command, current_command);
 		}
 
 		if (inputwin == promptwin) {
@@ -404,7 +404,7 @@ void glk_main() {
 		if (text_buffer[0] == 0) {
 			/* NO COMMAND WAS SPECIFIED, FILL THE COMMAND IN AS 'blankjacl'
 			 * FOR THE GAME TO PROCESS AS DESIRED */
-			strcpy(text_buffer, "blankjacl");
+			Common::strcpy_s(text_buffer, 1024, "blankjacl");
 			current_command = blank_command;
 		}
 
@@ -438,7 +438,7 @@ void glk_main() {
 		} else {
 			/* NO COMMAND WAS SPECIFIED, FILL THE COMMAND IN AS 'blankjacl'
 			 * FOR THE GAME TO PROCESS AS DESIRED */
-			strcpy(text_buffer, "blankjacl");
+			Common::strcpy_s(text_buffer, 1024, "blankjacl");
 			command_encapsulate();
 			preparse();
 		}
@@ -530,8 +530,8 @@ void word_check() {
 					TIME->value = FALSE;
 				}
 			} else {
-				strcpy(oops_buffer, word[wp]);
-				strcpy(text_buffer, last_command);
+				Common::strcpy_s(oops_buffer, word[wp]);
+				Common::strcpy_s(text_buffer, 1024, last_command);
 				command_encapsulate();
 				//printf("--- trying to replace %s with %s\n", word[oops_word], oops_buffer);
 				jacl_truncate();
@@ -543,10 +543,10 @@ void word_check() {
 
 				while (word[index] != nullptr) {
 					if (oopsed_current[0] != 0) {
-						strcat(oopsed_current, " ");
+						Common::strcat_s(oopsed_current, " ");
 					}
 
-					strcat(oopsed_current, word[index]);
+					Common::strcat_s(oopsed_current, word[index]);
 
 					index++;
 				}
@@ -570,7 +570,7 @@ void word_check() {
 			write_text(cstring_resolve("NOT_CLEVER")->value);
 			TIME->value = FALSE;
 		} else {
-			strcpy(text_buffer, last_command);
+			Common::strcpy_s(text_buffer, 1024, last_command);
 			current_command = last_command;
 			command_encapsulate();
 			jacl_truncate();
@@ -1186,7 +1186,7 @@ void walking_thru() {
 		}
 	}
 
-	strcpy(script_line, text_buffer);
+	Common::strcpy_s(script_line, text_buffer);
 
 	while (result && INTERRUPTED->value == FALSE) {
 		/* THERE COULD BE A LOT OF PROCESSING GOING ON HERE BEFORE GETTING
@@ -1222,7 +1222,7 @@ void walking_thru() {
 			}
 		}
 
-		strcpy(script_line, text_buffer);
+		Common::strcpy_s(script_line, text_buffer);
 	}
 
 	/* CLOSE THE STREAM */
diff --git a/engines/glk/jacl/jpp.cpp b/engines/glk/jacl/jpp.cpp
index 5e1a2b64051..f05ab9c63bf 100644
--- a/engines/glk/jacl/jpp.cpp
+++ b/engines/glk/jacl/jpp.cpp
@@ -96,7 +96,7 @@ int jpp() {
 						return (FALSE);
 					}
 				}
-				strcpy(processed_file, game_file);
+				Common::strcpy_s(processed_file, 256, game_file);
 
 				return (TRUE);
 			}
@@ -183,10 +183,10 @@ int process_file(const char *sourceFile1, char *sourceFile2) {
 			includeFile = strchr(text_buffer, '"');
 
 			if (includeFile != nullptr) {
-				strcpy(temp_buffer1, game_path);
-				strcat(temp_buffer1, includeFile + 1);
-				strcpy(temp_buffer2, include_directory);
-				strcat(temp_buffer2, includeFile + 1);
+				Common::strcpy_s(temp_buffer1, game_path);
+				Common::strcat_s(temp_buffer1, includeFile + 1);
+				Common::strcpy_s(temp_buffer2, include_directory);
+				Common::strcat_s(temp_buffer2, includeFile + 1);
 				if (process_file(temp_buffer1, temp_buffer2) == FALSE) {
 					return (FALSE);
 				}
diff --git a/engines/glk/jacl/loader.cpp b/engines/glk/jacl/loader.cpp
index 4a3f552439e..c8654ab9657 100644
--- a/engines/glk/jacl/loader.cpp
+++ b/engines/glk/jacl/loader.cpp
@@ -238,7 +238,7 @@ void read_gamefile() {
 		outofmem();
 	else {
 		current_function = function_table;
-		strcpy(current_function->name, "JACL*Internal");
+		Common::strcpy_s(current_function->name, "JACL*Internal");
 		current_function->position = 0;
 		current_function->self = 0;
 		current_function->call_count = 0;
@@ -329,10 +329,10 @@ void read_gamefile() {
 						object[objects]->label[40] = 0;
 						object[objects]->first_plural = nullptr;
 
-						strcpy(object[objects]->described, object[objects]->label);
-						strcpy(object[objects]->inventory, object[objects]->label);
-						strcpy(object[objects]->article, "the");
-						strcpy(object[objects]->definite, "the");
+						Common::strcpy_s(object[objects]->described, object[objects]->label);
+						Common::strcpy_s(object[objects]->inventory, object[objects]->label);
+						Common::strcpy_s(object[objects]->article, "the");
+						Common::strcpy_s(object[objects]->definite, "the");
 						object[objects]->attributes = FALSE;
 						object[objects]->user_attributes = FALSE;
 
@@ -694,8 +694,9 @@ void read_gamefile() {
 						errors++;
 					} else {
 						strncpy(function_name, word[wp], 59);
-						strcat(function_name, "_");
-						strcat(function_name, object[object_count]->label);
+						function_name[60] = '\0';
+						Common::strcat_s(function_name, "_");
+						Common::strcat_s(function_name, object[object_count]->label);
 						self_parent = object_count;
 					}
 					if (function_table == nullptr) {
@@ -708,7 +709,7 @@ void read_gamefile() {
 							functions++;
 
 							current_function = function_table;
-							strcpy(current_function->name, function_name);
+							Common::strcpy_s(current_function->name, function_name);
 
 							current_function->position = g_vm->glk_stream_get_position(game_stream);
 							current_function->call_count = 0;
@@ -727,7 +728,7 @@ void read_gamefile() {
 							functions++;
 
 							current_function = current_function->next_function;
-							strcpy(current_function->name, function_name);
+							Common::strcpy_s(current_function->name, function_name);
 
 							current_function->position = g_vm->glk_stream_get_position(game_stream);
 							current_function->call_count = 0;
diff --git a/engines/glk/jacl/parser.cpp b/engines/glk/jacl/parser.cpp
index f3184857ddc..2c14dbf0a55 100644
--- a/engines/glk/jacl/parser.cpp
+++ b/engines/glk/jacl/parser.cpp
@@ -386,32 +386,32 @@ void call_functions(const char *base_name) {
 	TIME->value = TRUE;
 
 	strncpy(base_function, base_name + 1, 80);
-	strcat(base_function, "_");
+	Common::strcat_s(base_function, "_");
 
 	strncpy(override_, base_function, 80);
 
-	strcpy(before_function, "+before_");
-	strcat(before_function, base_name + 1);
+	Common::strcpy_s(before_function, "+before_");
+	Common::strcat_s(before_function, base_name + 1);
 
-	strcpy(after_function, "+after_");
-	strcat(after_function, base_name + 1);
+	Common::strcpy_s(after_function, "+after_");
+	Common::strcat_s(after_function, base_name + 1);
 
-	strcpy(local_after_function, "after_");
-	strcat(local_after_function, base_name + 1);
+	Common::strcpy_s(local_after_function, "after_");
+	Common::strcat_s(local_after_function, base_name + 1);
 	if (noun[1] != FALSE) {
-		strcat(local_after_function, "_");
-		strcat(local_after_function, object[noun[1]]->label);
+		Common::strcat_s(local_after_function, "_");
+		Common::strcat_s(local_after_function, object[noun[1]]->label);
 	}
 	if (noun[0] != FALSE) {
-		strcat(local_after_function, "_");
-		strcat(local_after_function, object[noun[0]]->label);
+		Common::strcat_s(local_after_function, "_");
+		Common::strcat_s(local_after_function, object[noun[0]]->label);
 	}
 
 	/* THIS IS CALLED IF AN 'override' COMMAND IS EXECUTED
 	 * IN A LIBRARY FUNCTION BUT THE OBJECT-OR-LOCATION-SPECIFIC
 	 * OVERRIDE DOES NOT EXIST. IT IS SET TO '+default_func' */
-	strcpy(default_function, "+default_");
-	strcat(default_function, base_name + 1);
+	Common::strcpy_s(default_function, "+default_");
+	Common::strcat_s(default_function, base_name + 1);
 
 	/* EXECUTE THE GLOBAL *DEFAULT* BEFORE FUNCTION
 	 * AND RETURN IF IT RETURNS TRUE */
@@ -424,7 +424,7 @@ void call_functions(const char *base_name) {
 		return;
 
 	if (noun[0] == FALSE) { /* USER'S COMMAND HAS NO NOUNS */
-		strcat(base_function, object[HERE]->label);
+		Common::strcat_s(base_function, object[HERE]->label);
 		/* EXECUTE THE FUNCTION 'func_here' */
 		if (execute(base_function) == FALSE) {
 			/* THIS LOCATION-SPECIFIC FUNCTION DOES NOT
@@ -438,19 +438,19 @@ void call_functions(const char *base_name) {
 
 			/* PREPARE THE OVERRIDE FUNCTION NAME IN CASE IT
 			 * IS NEEDED */
-			strcat(override_, "override_");
-			strcat(override_, object[HERE]->label);
+			Common::strcat_s(override_, 81, "override_");
+			Common::strcat_s(override_, 81, object[HERE]->label);
 
 			/* CREATE THE FUNCTION NAME '+func' */
-			strcpy(base_function, "+");
-			strcat(base_function, base_name + 1);
+			Common::strcpy_s(base_function, "+");
+			Common::strcat_s(base_function, base_name + 1);
 
 			/* CALL THE LIBRARY'S DEFAULT BEHAVIOR */
 			if (execute(base_function) == FALSE)
 				unkfunrun(base_function);
 		}
 	} else if (noun[1] == FALSE) { /* USER'S COMMAND HAS ONE NOUN */
-		strcat(base_function, object[noun[0]]->label);
+		Common::strcat_s(base_function, object[noun[0]]->label);
 		/* EXECUTE THE FUNCTION 'func_noun1' */
 		if (execute(base_function) == FALSE) {
 			/* THIS OBJECT-SPECIFIC FUNCTION DOES NOT
@@ -464,21 +464,21 @@ void call_functions(const char *base_name) {
 
 			/* PREPARE THE OVERRIDE FUNCTION NAME IN CASE IT
 			 * IS NEEDED */
-			strcat(override_, "override_");
-			strcat(override_, object[noun[0]]->label);
+			Common::strcat_s(override_, 81, "override_");
+			Common::strcat_s(override_, 81, object[noun[0]]->label);
 
 			/* CREATE THE FUNCTION NAME '+func' */
-			strcpy(base_function, "+");
-			strcat(base_function, base_name + 1);
+			Common::strcpy_s(base_function, "+");
+			Common::strcat_s(base_function, base_name + 1);
 
 			/* CALL THE LIBRARY'S DEFAULT BEHAVIOR */
 			if (execute(base_function) == FALSE)
 				unkfunrun(base_function);
 		}
 	} else { /* USER'S COMMAND HAS TWO NOUNS */
-		strcat(base_function, object[noun[1]]->label);
-		strcat(base_function, "_");
-		strcat(base_function, object[noun[0]]->label);
+		Common::strcat_s(base_function, object[noun[1]]->label);
+		Common::strcat_s(base_function, "_");
+		Common::strcat_s(base_function, object[noun[0]]->label);
 		/* EXECUTE THE FUNCTION 'func_noun2_noun1'
 		 * IE give_to_fred THAT IS ASSOCIATED WITH
 		 * THE OBJECT flint_stone */
@@ -494,13 +494,13 @@ void call_functions(const char *base_name) {
 
 			/* PREPARE THE OVERRIDE FUNCTION NAME IN CASE IT
 			 * IS NEEDED */
-			strcat(override_, object[noun[1]]->label);
-			strcat(override_, "_override_");
-			strcat(override_, object[noun[0]]->label);
+			Common::strcat_s(override_, 81, object[noun[1]]->label);
+			Common::strcat_s(override_, 81, "_override_");
+			Common::strcat_s(override_, 81, object[noun[0]]->label);
 
 			/* CREATE THE FUNCTION NAME '+func' */
-			strcpy(base_function, "+");
-			strcat(base_function, base_name + 1);
+			Common::strcpy_s(base_function, "+");
+			Common::strcat_s(base_function, base_name + 1);
 
 			/* CALL THE LIBRARY'S DEFAULT BEHAVIOR */
 			if (execute(base_function) == FALSE)
@@ -1128,9 +1128,9 @@ int noun_resolve(struct word_type *scope_word, int finding_from, int noun_number
 			}
 
 			object_expected = TRUE;
-			strcpy(object_name, word[wp]);
-			strcat(object_name, " ");
-			strcat(object_name, cstring_resolve("OF_WORD")->value);
+			Common::strcpy_s(object_name, word[wp]);
+			Common::strcat_s(object_name, " ");
+			Common::strcat_s(object_name, cstring_resolve("OF_WORD")->value);
 
 			/* MOVE THE WORD POINTER TO AFTER THE 'OF' */
 			wp = wp + 2;
@@ -1147,9 +1147,9 @@ int noun_resolve(struct word_type *scope_word, int finding_from, int noun_number
 		// ADD THE WORDS USED TO error_buffer FOR POSSIBLE USE
 		// IN A DISABMIGUATE EMESSAGE
 		if (first_word == FALSE) {
-			strcat(error_buffer, " ");
+			Common::strcat_s(error_buffer, 1024, " ");
 		}
-		strcat(error_buffer, word[wp]);
+		Common::strcat_s(error_buffer, 1024, word[wp]);
 		first_word = FALSE;
 
 		/* LOOP THROUGH WORDS IN THE PLAYER'S INPUT */
@@ -1203,9 +1203,9 @@ int noun_resolve(struct word_type *scope_word, int finding_from, int noun_number
 		 * IS TRYING TO REFER TO FOR USE IN AN ERROR MESSAGE IF
 		 * LATER REQUIRED */
 		if (object_name[0] != 0)
-			strcat(object_name, " ");
+			Common::strcat_s(object_name, " ");
 
-		strcat(object_name, word[wp]);
+		Common::strcat_s(object_name, word[wp]);
 
 		if (!strcmp("everything", word[wp])) {
 			/* ALL THIS NEEDS TO SIGNIFY IS THAT IT IS OKAY TO RETURN MULTIPLE
diff --git a/engines/glk/jacl/prototypes.h b/engines/glk/jacl/prototypes.h
index 91b66986a72..dd840f72b11 100644
--- a/engines/glk/jacl/prototypes.h
+++ b/engines/glk/jacl/prototypes.h
@@ -65,7 +65,9 @@ extern void create_cinteger(const char *name, int value);
 extern void scripting();
 extern void undoing();
 extern void walking_thru();
+#ifndef GLK
 extern void create_paths(char *full_path);
+#endif
 extern int get_key();
 extern char get_character(const char *message);
 extern int get_yes_or_no();
diff --git a/engines/glk/jacl/resolvers.cpp b/engines/glk/jacl/resolvers.cpp
index 6307524d082..c74a001b64d 100644
--- a/engines/glk/jacl/resolvers.cpp
+++ b/engines/glk/jacl/resolvers.cpp
@@ -747,10 +747,10 @@ const char *expand_function(const char *name) {
 		 * ELEMENT, SO TAKE NOTE OF THAT */
 		sprintf(function_name, "%ld", value_of(&expression[delimiter], TRUE));
 	} else {
-		strcpy(function_name, &expression[delimiter]);
+		Common::strcpy_s(function_name, 81, &expression[delimiter]);
 	}
-	strcat(function_name, "_");
-	strcat(function_name, object[index]->label);
+	Common::strcat_s(function_name, 81, "_");
+	Common::strcat_s(function_name, 81, object[index]->label);
 
 	return ((const char *) function_name);
 }
@@ -872,9 +872,10 @@ char *macro_resolve(const char *testString) {
 			return (nullptr);
 		} else {
 			if (object[index]->attributes & PLURAL) {
-				strcpy(temp_buffer, "");
+				temp_buffer[0] = '\0';
 			} else {
-				strcpy(temp_buffer, "s");
+				temp_buffer[0] = 's';
+				temp_buffer[1] = '\0';
 			}
 			return (temp_buffer);
 		}
@@ -970,11 +971,11 @@ char *macro_resolve(const char *testString) {
 			return (sentence_output(index, TRUE));
 		}
 	} else {
-		strcpy(macro_function, "+macro_");
-		strcat(macro_function, &expression[delimiter]);
-		strcat(macro_function, "<");
+		Common::strcpy_s(macro_function, "+macro_");
+		Common::strcat_s(macro_function, &expression[delimiter]);
+		Common::strcat_s(macro_function, "<");
 		sprintf(temp_buffer, "%d", index);
-		strcat(macro_function, temp_buffer);
+		Common::strcat_s(macro_function, temp_buffer);
 
 		// BUILD THE FUNCTION NAME AND PASS THE OBJECT AS
 		// THE ONLY ARGUMENT
diff --git a/engines/glk/jacl/utils.cpp b/engines/glk/jacl/utils.cpp
index 36a5b755c64..ffbbdf315cf 100644
--- a/engines/glk/jacl/utils.cpp
+++ b/engines/glk/jacl/utils.cpp
@@ -53,8 +53,8 @@ void eachturn() {
 	 * OCCURING DUE TO THE PASSING OF TIME */
 	TOTAL_MOVES->value++;
 	execute("+eachturn");
-	strcpy(function_name, "eachturn_");
-	strcat(function_name, object[HERE]->label);
+	Common::strcpy_s(function_name, 81, "eachturn_");
+	Common::strcat_s(function_name, 81, object[HERE]->label);
 	execute(function_name);
 	execute("+system_eachturn");
 
@@ -106,6 +106,7 @@ int random_number() {
 	return g_vm->getRandomNumber(0x7fffffff);
 }
 
+#ifndef GLK
 void create_paths(char *full_path) {
 	int       index;
 	char      *last_slash;
@@ -181,6 +182,7 @@ void create_paths(char *full_path) {
 		strcat(data_directory, DATA_DIR);
 	}
 }
+#endif
 
 int jacl_whitespace(char character) {
 	/* CHECK IF A CHARACTER IS CONSIDERED WHITE SPACE IN THE JACL LANGUAGE */
diff --git a/engines/glk/level9/level9_main.cpp b/engines/glk/level9/level9_main.cpp
index de0d3c3d90e..bc101089245 100644
--- a/engines/glk/level9/level9_main.cpp
+++ b/engines/glk/level9/level9_main.cpp
@@ -1227,7 +1227,7 @@ void calldriver() {
 		*list9startptr = *a6;
 	} else if (d0 == 0x0b) {
 		char NewName[MAX_PATH];
-		strcpy(NewName, LastGame);
+		Common::strcpy_s(NewName, LastGame);
 		if (*a6 == 0) {
 			printstring("\rSearching for next sub-game file.\r");
 			if (!os_get_game_file(NewName, MAX_PATH)) {
@@ -1553,7 +1553,7 @@ L9BOOL GetWordV3(char *buff, int Word) {
 			Word++; /* force unpack again */
 		}
 	}
-	strcpy(buff, threechars);
+	Common::strcpy_s(buff, IBUFFSIZE, threechars);
 	for (i = 0; i < (int)strlen(buff); i++) buff[i] &= 0x7f;
 	return TRUE;
 }
@@ -2991,7 +2991,7 @@ L9BOOL LoadGame2(const char *filename, char *picname) {
 		randomseed = constseed;
 	else
 		randomseed = (L9UINT16)g_system->getMillis();
-	strcpy(LastGame, filename);
+	Common::strcpy_s(LastGame, filename);
 	return Running = TRUE;
 }
 
diff --git a/engines/glk/level9/os_glk.cpp b/engines/glk/level9/os_glk.cpp
index 34248896d26..cb7b76e4dfb 100644
--- a/engines/glk/level9/os_glk.cpp
+++ b/engines/glk/level9/os_glk.cpp
@@ -3517,8 +3517,9 @@ static int gln_command_escape(const char *string) {
 		return FALSE;
 
 	/* Take a copy of the string, without any leading space or introducer. */
-	string_copy = (char *)gln_malloc(strlen(string + posn) + 1 - strlen("glk"));
-	strcpy(string_copy, string + posn + strlen("glk"));
+	size_t ln = strlen(string + posn) + 1 - 3/*strlen("glk")*/;
+	string_copy = (char *)gln_malloc(ln);
+	Common::strcpy_s(string_copy, ln, string + posn + 3/*strlen("glk")*/);
 
 	/*
 	 * Find the subcommand; the first word in the string copy.  Find its end,
@@ -3625,8 +3626,9 @@ static int gln_command_intercept(char *string) {
 
 	/* Take a copy of the string, excluding any leading whitespace. */
 	posn = strspn(string, "\t ");
-	string_copy = (char *)gln_malloc(strlen(string + posn) + 1);
-	strcpy(string_copy, string + posn);
+	size_t ln = strlen(string + posn) + 1;
+	string_copy = (char *)gln_malloc(ln);
+	Common::strcpy_s(string_copy, ln, string + posn);
 
 	/*
 	 * Find the space or NUL after the first word, and check that anything
@@ -4500,8 +4502,9 @@ static void gln_establish_picture_filename(const char *name, char **graphics) {
 	assert(name && graphics);
 
 	/* Take a destroyable copy of the input filename. */
-	base = (char *)gln_malloc(strlen(name) + 1);
-	strcpy(base, name);
+	size_t ln = strlen(name) + 1;
+	base = (char *)gln_malloc(ln);
+	Common::strcpy_s(base, ln, name);
 
 	/* If base has an extension .LEV, .SNA, or similar, remove it. */
 	if (strrchr(base, '.')) {
@@ -4509,44 +4512,45 @@ static void gln_establish_picture_filename(const char *name, char **graphics) {
 	}
 
 	/* Allocate space for the return graphics file. */
-	graphics_file = (char *)gln_malloc(strlen(base) + strlen(".___") + 1);
+	ln = strlen(base) + 4/*strlen(".___")*/ + 1;
+	graphics_file = (char *)gln_malloc(ln);
 
 	/* Form a candidate graphics file, using a .PIC extension. */
 	if (!f.isOpen()) {
-		strcpy(graphics_file, base);
-		strcat(graphics_file, ".PIC");
+		Common::strcpy_s(graphics_file, ln, base);
+		Common::strcat_s(graphics_file, ln, ".PIC");
 		f.open(graphics_file);
 	}
 
 	if (!f.isOpen()) {
-		strcpy(graphics_file, base);
-		strcat(graphics_file, ".pic");
+		Common::strcpy_s(graphics_file, ln, base);
+		Common::strcat_s(graphics_file, ln, ".pic");
 		f.open(graphics_file);
 	}
 
 	/* Form a candidate graphics file, using a .CGA extension. */
 	if (!f.isOpen()) {
-		strcpy(graphics_file, base);
-		strcat(graphics_file, ".CGA");
+		Common::strcpy_s(graphics_file, ln, base);
+		Common::strcat_s(graphics_file, ln, ".CGA");
 		f.open(graphics_file);
 	}
 
 	if (!f.isOpen()) {
-		strcpy(graphics_file, base);
-		strcat(graphics_file, ".cga");
+		Common::strcpy_s(graphics_file, ln, base);
+		Common::strcat_s(graphics_file, ln, ".cga");
 		f.open(graphics_file);
 	}
 
 	/* Form a candidate graphics file, using a .HRC extension. */
 	if (!f.isOpen()) {
-		strcpy(graphics_file, base);
-		strcat(graphics_file, ".HRC");
+		Common::strcpy_s(graphics_file, ln, base);
+		Common::strcat_s(graphics_file, ln, ".HRC");
 		f.open(graphics_file);
 	}
 
 	if (!f.isOpen()) {
-		strcpy(graphics_file, base);
-		strcat(graphics_file, ".hrc");
+		Common::strcpy_s(graphics_file, ln, base);
+		Common::strcat_s(graphics_file, ln, ".hrc");
 		f.open(graphics_file);
 	}
 
@@ -4566,16 +4570,17 @@ static void gln_establish_picture_filename(const char *name, char **graphics) {
 	}
 
 	/* Again, allocate space for the return graphics file. */
-	graphics_file = (char *)gln_malloc(strlen(base) + strlen("PICTURE.DAT") + 1);
+	ln = strlen(base) + strlen("PICTURE.DAT") + 1;
+	graphics_file = (char *)gln_malloc(ln);
 
 	/* As above, form a candidate graphics file. */
-	strcpy(graphics_file, base);
-	strcat(graphics_file, "PICTURE.DAT");
+	Common::strcpy_s(graphics_file, ln, base);
+	Common::strcat_s(graphics_file, ln, "PICTURE.DAT");
 
 	if (!f.open(graphics_file)) {
 		/* Retry, using picture.dat extension instead. */
-		strcpy(graphics_file, base);
-		strcat(graphics_file, "picture.dat");
+		Common::strcpy_s(graphics_file, ln, base);
+		Common::strcat_s(graphics_file, ln, "picture.dat");
 		if (!f.open(graphics_file)) {
 			/*
 			 * No access to this graphics file.  In this case, free memory
diff --git a/engines/glk/magnetic/glk.cpp b/engines/glk/magnetic/glk.cpp
index 18307fc0d4c..e00a0c372e6 100644
--- a/engines/glk/magnetic/glk.cpp
+++ b/engines/glk/magnetic/glk.cpp
@@ -3329,8 +3329,9 @@ int Magnetic::gms_command_escape(const char *string_, int *undo_command) {
 		return false;
 
 	/* Take a copy of the string_, without any leading space or introducer. */
+	size_t ln = strlen(string_ + posn) + 1 - 3/*strlen("glk")*/;
 	string_copy = (char *)gms_malloc(strlen(string_ + posn) + 1 - strlen("glk"));
-	strcpy(string_copy, string_ + posn + strlen("glk"));
+	Common::strcpy_s(string_copy, ln, string_ + posn + 3/*strlen("glk")*/);
 
 	/*
 	 * Find the subcommand; the first word in the string copy.  Find its end,
@@ -3725,8 +3726,9 @@ void Magnetic::gms_establish_filenames(const char *name, char **text, char **gra
 	assert(name && text && graphics && hints_);
 
 	/* Take a destroyable copy of the input filename. */
-	base = (char *)gms_malloc(strlen(name) + 1);
-	strcpy(base, name);
+	size_t ln = strlen(name) + 1;
+	base = (char *)gms_malloc(ln);
+	Common::strcpy_s(base, ln, name);
 
 	/* If base has an extension .MAG, .GFX, or .HNT, remove it. */
 	if (strlen(base) > strlen(".XXX")) {
@@ -3737,16 +3739,17 @@ void Magnetic::gms_establish_filenames(const char *name, char **text, char **gra
 	}
 
 	/* Allocate space for the return text file. */
-	text_file = (char *)gms_malloc(strlen(base) + strlen(".MAG") + 1);
+	ln = strlen(base) + 4/*strlen(".MAG")*/ + 1;
+	text_file = (char *)gms_malloc(ln);
 
 	/* Form a candidate text file, by adding a .MAG extension. */
-	strcpy(text_file, base);
-	strcat(text_file, ".MAG");
+	Common::strcpy_s(text_file, ln, base);
+	Common::strcat_s(text_file, ln, ".MAG");
 
 	if (!stream.open(text_file)) {
 		/* Retry, using a .mag extension instead. */
-		strcpy(text_file, base);
-		strcat(text_file, ".mag");
+		Common::strcpy_s(text_file, ln, base);
+		Common::strcat_s(text_file, ln, ".mag");
 
 		if (!stream.open(text_file)) {
 			/*
@@ -3765,16 +3768,17 @@ void Magnetic::gms_establish_filenames(const char *name, char **text, char **gra
 	stream.close();
 
 	/* Now allocate space for the return graphics file. */
-	graphics_file = (char *)gms_malloc(strlen(base) + strlen(".GFX") + 1);
+	ln = strlen(base) + 4/*strlen(".GFX")*/ + 1;
+	graphics_file = (char *)gms_malloc(ln);
 
 	/* As above, form a candidate graphics file, using a .GFX extension. */
-	strcpy(graphics_file, base);
-	strcat(graphics_file, ".GFX");
+	Common::strcpy_s(graphics_file, ln, base);
+	Common::strcat_s(graphics_file, ln, ".GFX");
 
 	if (!stream.open(graphics_file)) {
 		/* Retry, using a .gfx extension instead. */
-		strcpy(graphics_file, base);
-		strcat(graphics_file, ".gfx");
+		Common::strcpy_s(graphics_file, ln, base);
+		Common::strcat_s(graphics_file, ln, ".gfx");
 
 		if (!stream.open(graphics_file)) {
 			/*
@@ -3788,16 +3792,17 @@ void Magnetic::gms_establish_filenames(const char *name, char **text, char **gra
 	stream.close();
 
 	/* Now allocate space for the return hints_ file. */
-	hints_file = (char *)gms_malloc(strlen(base) + strlen(".HNT") + 1);
+	ln = strlen(base) + 4/*strlen(".HNT")*/ + 1;
+	hints_file = (char *)gms_malloc(ln);
 
 	/* As above, form a candidate graphics file, using a .HNT extension. */
-	strcpy(hints_file, base);
-	strcat(hints_file, ".HNT");
+	Common::strcpy_s(hints_file, ln, base);
+	Common::strcat_s(hints_file, ln, ".HNT");
 
 	if (!stream.open(hints_file)) {
 		/* Retry, using a .hnt extension instead. */
-		strcpy(hints_file, base);
-		strcat(hints_file, ".hnt");
+		Common::strcpy_s(hints_file, ln, base);
+		Common::strcat_s(hints_file, ln, ".hnt");
 
 		if (!stream.open(hints_file)) {
 			/*
diff --git a/engines/glk/scott/c64_checksums.cpp b/engines/glk/scott/c64_checksums.cpp
index b241023fee6..eb415bce510 100644
--- a/engines/glk/scott/c64_checksums.cpp
+++ b/engines/glk/scott/c64_checksums.cpp
@@ -476,7 +476,7 @@ int decrunchC64(uint8_t **sf, size_t *extent, C64Rec record) {
 
 	if (record._switches != nullptr) {
 		char string[100];
-		strcpy(string, record._switches);
+		Common::strcpy_s(string, record._switches);
 		switches[numSwitches] = strtok(string, " ");
 
 		while (switches[numSwitches] != nullptr)
diff --git a/engines/glk/scott/scott.cpp b/engines/glk/scott/scott.cpp
index 0930648e291..b3b9fd1222a 100644
--- a/engines/glk/scott/scott.cpp
+++ b/engines/glk/scott/scott.cpp
@@ -375,7 +375,7 @@ const char *Scott::mapSynonym(int noun) {
 		if (*tp == '*')
 			tp++;
 		else
-			strcpy(lastword, tp);
+			Common::strcpy_s(lastword, tp);
 		if (n == noun)
 			return lastword;
 		n++;
diff --git a/engines/glk/scott/unp64/unp64.cpp b/engines/glk/scott/unp64/unp64.cpp
index 76effc8cab2..7da8e279a33 100644
--- a/engines/glk/scott/unp64/unp64.cpp
+++ b/engines/glk/scott/unp64/unp64.cpp
@@ -587,7 +587,7 @@ int unp64(uint8_t *compressed, size_t length, uint8_t *destinationBuffer, size_t
 	}
 
 	if (*forcedname) {
-		strcpy(name, forcedname);
+		Common::strcpy_s(name, forcedname);
 	} else {
 		if (strlen(name) > 248) /* dirty hack in case name is REALLY long */
 			name[248] = 0;
diff --git a/engines/glk/tads/os_frob_tads.cpp b/engines/glk/tads/os_frob_tads.cpp
index 6cf1abb30b1..af753f912aa 100644
--- a/engines/glk/tads/os_frob_tads.cpp
+++ b/engines/glk/tads/os_frob_tads.cpp
@@ -187,7 +187,7 @@ bool os_locate(const char *fname, int flen, const char *arg0, char *buf, size_t
 }
 
 osfildef *os_create_tempfile(const char *fname, char *buf) {
-	strcpy(buf, "tmpfile");
+	Common::strcpy_s(buf, OSFNMAX, "tmpfile");
 	return new Common::MemoryReadWriteStream(DisposeAfterUse::YES);
 }
 
@@ -197,7 +197,7 @@ int osfdel_temp(const char *fname) {
 }
 
 void os_get_tmp_path(char *buf) {
-	strcpy(buf, "");
+	buf[0] = '\0';
 }
 
 int os_gen_temp_filename(char *buf, size_t buflen) {
@@ -228,11 +228,11 @@ bool os_rmdir(const char *dir) {
 
 void os_defext(char *fname, const char *ext) {
 	if (!strchr(fname, '.'))
-		strcat(fname, ext);
+		Common::strcat_s(fname, OSFNMAX, ext);
 }
 
 void os_addext(char *fname, const char *ext) {
-	strcat(fname, ext);
+	Common::strcat_s(fname, OSFNMAX, ext);
 }
 
 void os_remext(char *fname) {
@@ -254,28 +254,28 @@ bool os_is_file_absolute(const char *fname) {
 }
 
 void os_get_path_name(char *pathbuf, size_t pathbuflen, const char *fname) {
-	strcpy(pathbuf, "");
+	pathbuf[0] = '\0';
 }
 
 void os_build_full_path(char *fullpathbuf, size_t fullpathbuflen,
 	const char *path, const char *filename) {
-	strcpy(fullpathbuf, filename);
+	Common::strcpy_s(fullpathbuf, fullpathbuflen, filename);
 }
 
 void os_combine_paths(char *fullpathbuf, size_t pathbuflen,
 	const char *path, const char *filename) {
-	strcpy(fullpathbuf, filename);
+	Common::strcpy_s(fullpathbuf, pathbuflen, filename);
 }
 
 bool os_get_abs_filename(char *result_buf, size_t result_buf_size,
 	const char *filename) {
-	strcpy(result_buf, filename);
+	Common::strcpy_s(result_buf, result_buf_size, filename);
 	return true;
 }
 
 bool os_get_rel_path(char *result_buf, size_t result_buf_size,
 	const char *basepath, const char *filename) {
-	strcpy(result_buf, filename);
+	Common::strcpy_s(result_buf, result_buf_size, filename);
 	return true;
 }
 
diff --git a/engines/glk/tads/os_glk.cpp b/engines/glk/tads/os_glk.cpp
index 1b9ce1dafa9..7306814e9fd 100644
--- a/engines/glk/tads/os_glk.cpp
+++ b/engines/glk/tads/os_glk.cpp
@@ -95,7 +95,7 @@ int os_init(int *argc, char *argv[], const char *prompt,
 
 	g_vm->glk_set_window(mainwin);
 
-	strcpy(rbuf, "");
+	rbuf[0] = '\0';
 
 	return 0;
 }
@@ -324,7 +324,7 @@ void os_status(int stat)
 										winmethod_Above | winmethod_Fixed, 1,
 										wintype_TextGrid, 0);
 		}
-		strcpy(lbuf, "");
+		lbuf[0] = '\0';
 	}
 }
 
@@ -534,7 +534,7 @@ int os_askfile(const char *prompt, char *fname_buf, int fname_buf_len,
 	if (fileref == nullptr)
 		return OS_AFE_CANCEL;
 
-	strcpy(fname_buf, g_vm->garglk_fileref_get_name(fileref));
+	Common::strcpy_s(fname_buf, fname_buf_len, g_vm->garglk_fileref_get_name(fileref));
 
 	g_vm->glk_fileref_destroy(fileref);
 
@@ -967,7 +967,7 @@ osfildef *os_exeseek(const char *argv0, const char *typ) {
 }
 
 int os_get_str_rsc(int id, char *buf, size_t buflen) {
-	strcpy(buf, "");
+	buf[0] = '\0';
 	return 0;
 }
 
@@ -982,8 +982,9 @@ void os_dbg_vprintf(const char *fmt, va_list args) {
 int os_vasprintf(char **bufptr, const char *fmt, va_list ap) {
 	Common::String s = Common::String::vformat(fmt, ap);
 
-	*bufptr = (char *)malloc(s.size() + 1);
-	strcpy(*bufptr, s.c_str());
+	size_t ln = s.size() + 1;
+	*bufptr = (char *)malloc(ln);
+	Common::strcpy_s(*bufptr, ln, s.c_str());
 	return s.size();
 }
 
@@ -1010,12 +1011,12 @@ void os_xlat_html4(unsigned int html4_char, char *result, size_t result_len) {
 		case 132:                                      /* double back quote */
 			result[0] = '\"'; break;
 		case 153:                                             /* trade mark */
-			strcpy(result, "(tm)"); return;
+			Common::strcpy_s(result, result_len, "(tm)"); return;
 		case 140:                                            /* OE ligature */
 		case 338:                                            /* OE ligature */
-			strcpy(result, "OE"); return;
+			Common::strcpy_s(result, result_len, "OE"); return;
 		case 339:                                            /* oe ligature */
-			strcpy(result, "oe"); return;
+			Common::strcpy_s(result, result_len, "oe"); return;
 		case 159:                                                   /* Yuml */
 			result[0] = (char)255; return;
 		case 376:                                        /* Y with diaresis */
@@ -1029,7 +1030,7 @@ void os_xlat_html4(unsigned int html4_char, char *result, size_t result_len) {
 			result[0] = '-'; break;
 		case 151:                                                /* em dash */
 		case 8212:                                               /* em dash */
-			strcpy(result, "--"); return;
+			Common::strcpy_s(result, result_len, "--"); return;
 		case 145:                                      /* left single quote */
 		case 8216:                                     /* left single quote */
 			result[0] = '`'; break;
diff --git a/engines/glk/tads/tads2/built_in.cpp b/engines/glk/tads/tads2/built_in.cpp
index 4e432ecf6fc..27247af298f 100644
--- a/engines/glk/tads/tads2/built_in.cpp
+++ b/engines/glk/tads/tads2/built_in.cpp
@@ -52,9 +52,9 @@ void bifyon(bifcxdef *ctx, int argc)
 
 	/* load the "yes" and "no" reply patterns */
 	if (os_get_str_rsc(RESID_YORN_YES, yesbuf, sizeof(yesbuf)))
-		strcpy(yesbuf, "[Yy].*");
+		Common::strcpy_s(yesbuf, "[Yy].*");
 	if (os_get_str_rsc(RESID_YORN_NO, nobuf, sizeof(nobuf)))
-		strcpy(nobuf, "[Nn].*");
+		Common::strcpy_s(nobuf, "[Nn].*");
 
 	/* if we're in HTML mode, switch to input font */
 	if (tio_is_html_mode())
@@ -2047,27 +2047,27 @@ static int get_ext_key_name(char *namebuf, int c, int extc)
 		case 10:
 		case 13:
 			/* return '\n' for LF and CR characters */
-			strcpy(namebuf, "\\n");
+			Common::strcpy_s(namebuf, 20, "\\n");
 			return TRUE;
 
 		case 9:
 			/* return '\t' for TAB characters */
-			strcpy(namebuf, "\\t");
+			Common::strcpy_s(namebuf, 20, "\\t");
 			return TRUE;
 
 		case 8:
 			/* return '[bksp]' for backspace characters */
-			strcpy(namebuf, "[bksp]");
+			Common::strcpy_s(namebuf, 20, "[bksp]");
 			return TRUE;
 
 		case 27:
 			/* return '[esc]' for the escape key */
-			strcpy(namebuf, "[esc]");
+			Common::strcpy_s(namebuf, 20, "[esc]");
 			return TRUE;
 
 		default:
 			/* return '[ctrl-X]' for other control characters */
-			strcpy(namebuf, "[ctrl-X]");
+			Common::strcpy_s(namebuf, 20, "[ctrl-X]");
 			namebuf[6] = (char)(c + 'a' - 1);
 			return TRUE;
 		}
@@ -2086,7 +2086,7 @@ static int get_ext_key_name(char *namebuf, int c, int extc)
 		&& extc <= (int)(sizeof(ext_key_names)/sizeof(ext_key_names[0])))
 	{
 		/* use the array name */
-		strcpy(namebuf, ext_key_names[extc - 1]);
+		Common::strcpy_s(namebuf, 20, ext_key_names[extc - 1]);
 		return TRUE;
 	}
 
@@ -2094,13 +2094,13 @@ static int get_ext_key_name(char *namebuf, int c, int extc)
 	if (extc >= CMD_ALT && extc <= CMD_ALT + 25)
 	{
 		/* generate an ALT key name */
-		strcpy(namebuf, "[alt-X]");
+		Common::strcpy_s(namebuf, 20, "[alt-X]");
 		namebuf[5] = (char)(extc - CMD_ALT + 'a');
 		return TRUE;
 	}
 
 	/* it's not a valid key - use '[?]' as the name */
-	strcpy(namebuf, "[?]");
+	Common::strcpy_s(namebuf, 20, "[?]");
 	return FALSE;
 }
 
@@ -2174,7 +2174,7 @@ void bifwrd(bifcxdef *ctx, int argc)
 			*dst++ = DAT_SSTRING;
 			len = strlen((const char *)src);
 			oswp2(dst, len + 2);
-			strcpy((char *)dst + 2, (const char *)src);
+			Common::strcpy_s((char *)dst + 2, sizeof(buf) - (dst + 2 - buf), (const char *)src);
 			dst += len + 2;
 		}
 	}
@@ -2507,7 +2507,7 @@ void biffopen(bifcxdef *ctx, int argc)
 						   ctx->bifcxrun->runcxgamepath, fname);
 
 		/* replace the original filename with the full path */
-		strcpy(fname, newname);
+		Common::strcpy_s(fname, newname);
 	}
 
 	/* get the mode string */
diff --git a/engines/glk/tads/tads2/character_map.cpp b/engines/glk/tads/tads2/character_map.cpp
index 5a59afc2de8..4a21cff6a04 100644
--- a/engines/glk/tads/tads2/character_map.cpp
+++ b/engines/glk/tads/tads2/character_map.cpp
@@ -74,7 +74,7 @@ void cmap_init_default(void)
 	memset(G_cmap_id, 0, sizeof(G_cmap_id));
 
 	/* indicate that it's the default */
-	strcpy(G_cmap_ldesc, "(native/no mapping)");
+	Common::strcpy_s(G_cmap_ldesc, "(native/no mapping)");
 
 	/* note that we have no character set loaded */
 	S_cmap_loaded = FALSE;
@@ -331,7 +331,7 @@ void cmap_set_game_charset(errcxdef *ec,
 	 *   provide here.  Save the game's character set ldesc for that
 	 *   eventuality, since it describes exactly what the *game* wanted.
 	 */
-	strcpy(G_cmap_ldesc, internal_ldesc);
+	Common::strcpy_s(G_cmap_ldesc, internal_ldesc);
 }
 
 } // End of namespace TADS2
diff --git a/engines/glk/tads/tads2/execute_command.cpp b/engines/glk/tads/tads2/execute_command.cpp
index 26ef04cb532..9ef451ce6a3 100644
--- a/engines/glk/tads/tads2/execute_command.cpp
+++ b/engines/glk/tads/tads2/execute_command.cpp
@@ -2444,8 +2444,8 @@ static void voc_askobj_indirect(voccxdef *ctx, vocoldef *dolist,
  */
 int execmd(voccxdef *ctx, objnum actor, objnum prep,
 		   char *vverb, char *vprep, vocoldef *dolist, vocoldef *iolist,
-		   char **cmd, int *typelist,
-		   char *cmdbuf, int wrdcnt, uchar **preparse_list, int *next_word)
+		   char **cmd, int *typelist, char *cmdbuf, size_t cmdlen,
+		   int wrdcnt, uchar **preparse_list, int *next_word)
 {
 	objnum    verb;
 	objnum    iobj;
@@ -2776,7 +2776,7 @@ int execmd(voccxdef *ctx, objnum actor, objnum prep,
 				/* disambiguate the direct object list, now that we can */
 				if (vocdisambig(ctx, dolist1, dolist, PRP_DODEFAULT,
 								PRP_VALIDDO, voctplvd(tpl), cmd, MCMONINV,
-								actor, verb, prep, cmdbuf, FALSE))
+								actor, verb, prep, cmdbuf, cmdlen, FALSE))
 				{
 					err = -1;
 					goto exit_error;
@@ -2880,7 +2880,7 @@ int execmd(voccxdef *ctx, objnum actor, objnum prep,
 											PRP_DODEFAULT, PRP_VALIDDO,
 											voctplvd(tpl), cmd, MCMONINV,
 											actor, verb, prep, cmdbuf,
-											FALSE))
+											cmdlen, FALSE))
 							{
 								err = -1;
 								goto exit_error;
@@ -3058,7 +3058,7 @@ int execmd(voccxdef *ctx, objnum actor, objnum prep,
 				/* disambiguate the direct object list */
 				if (vocdisambig(ctx, dolist1, dolist, PRP_DODEFAULT,
 								PRP_VALIDDO, voctplvd(tpl), cmd, otherobj,
-								actor, verb, prep, cmdbuf, FALSE))
+								actor, verb, prep, cmdbuf, cmdlen, FALSE))
 				{
 					err = -1;
 					goto exit_error;
@@ -3083,7 +3083,7 @@ int execmd(voccxdef *ctx, objnum actor, objnum prep,
 			/* disambiguate the indirect object list */
 			if (vocdisambig(ctx, iolist1, iolist, PRP_IODEFAULT,
 							PRP_VALIDIO, voctplvi(tpl), cmd, otherobj,
-							actor, verb, prep, cmdbuf, FALSE))
+							actor, verb, prep, cmdbuf, cmdlen, FALSE))
 			{
 				err = -1;
 				goto exit_error;
@@ -3107,7 +3107,7 @@ int execmd(voccxdef *ctx, objnum actor, objnum prep,
 			if (!(tplflags & VOCTPLFLG_DOBJ_FIRST)
 				&& vocdisambig(ctx, dolist1, dolist, PRP_DODEFAULT,
 							   PRP_VALIDDO, voctplvd(tpl), cmd, otherobj,
-							   actor, verb, prep, cmdbuf, FALSE))
+							   actor, verb, prep, cmdbuf, cmdlen, FALSE))
 			{
 				err = -1;
 				goto exit_error;
@@ -3582,7 +3582,7 @@ int execmd(voccxdef *ctx, objnum actor, objnum prep,
 				 *   new command line - copy the new text to the command
 				 *   buffer, set the 'redo' flag, and give up
 				 */
-				strcpy(cmdbuf, exenewcmd);
+				Common::strcpy_s(cmdbuf, cmdlen, exenewcmd);
 				ctx->voccxredo = TRUE;
 				VOC_RETVAL(ctx, save_sp, 1);
 			}
@@ -3613,7 +3613,7 @@ int execmd(voccxdef *ctx, objnum actor, objnum prep,
 
 			/* get the types */
 			exenewlist[cnt] = nullptr;
-			if (vocgtyp(ctx, exenewlist, exenewtype, cmdbuf))
+			if (vocgtyp(ctx, exenewlist, exenewtype, cmdbuf, cmdlen))
 			{
 				/*
 				 *   clear the unknown word count so that we fail with
@@ -3661,7 +3661,7 @@ int execmd(voccxdef *ctx, objnum actor, objnum prep,
 				|| (exenewlist[next] && !vocspec(exenewlist[next], VOCW_THEN)
 					&& *exenewlist[next] != '\0'))
 			{
-				strcpy(cmdbuf, exenewcmd);
+				Common::strcpy_s(cmdbuf, cmdlen, exenewcmd);
 				ctx->voccxredo = TRUE;
 				VOC_RETVAL(ctx, save_sp, 1);
 			}
diff --git a/engines/glk/tads/tads2/file_io.cpp b/engines/glk/tads/tads2/file_io.cpp
index 355aa483170..0165c4f4a3b 100644
--- a/engines/glk/tads/tads2/file_io.cpp
+++ b/engines/glk/tads/tads2/file_io.cpp
@@ -1077,7 +1077,7 @@ void fiord(mcmcxdef *mctx, voccxdef *vctx, tokcxdef *tctx, const char *fname,
 				 *   same directory that contains the .GAM file
 				 */
 				if (base_name != nullptr)
-					strcpy(resname, base_name);
+					Common::strcpy_s(resname, base_name);
 				else
 					resname[0] = '\0';
 			}
diff --git a/engines/glk/tads/tads2/line_source_file.cpp b/engines/glk/tads/tads2/line_source_file.cpp
index bb0530c20c6..d7714ac1526 100644
--- a/engines/glk/tads/tads2/line_source_file.cpp
+++ b/engines/glk/tads/tads2/line_source_file.cpp
@@ -1030,7 +1030,7 @@ void linfnam(lindef *lin, char *buf)
 {
 #   define  linf ((linfdef *)lin)
 
-	strcpy(buf, linf->linfnam);
+	Common::strcpy_s(buf, OSFNMAX, linf->linfnam);
 
 #   undef linf
 }
diff --git a/engines/glk/tads/tads2/memory_cache_swap.cpp b/engines/glk/tads/tads2/memory_cache_swap.cpp
index b36a6c8935b..3a314b91788 100644
--- a/engines/glk/tads/tads2/memory_cache_swap.cpp
+++ b/engines/glk/tads/tads2/memory_cache_swap.cpp
@@ -57,8 +57,9 @@ void mcsini(mcscxdef *ctx, mcmcx1def *gmemctx, ulong maxsiz,
 	 *   have to retain the original copy (in case it's on the stack)
 	 */
 	if (swapfilename != nullptr) {
-		ctx->mcscxfname = (char *)mchalo(errctx, (strlen(swapfilename) + 1), "mcsini");
-		strcpy(ctx->mcscxfname, swapfilename);
+		size_t ln = strlen(swapfilename) + 1;
+		ctx->mcscxfname = (char *)mchalo(errctx, ln, "mcsini");
+		Common::strcpy_s(ctx->mcscxfname, ln, swapfilename);
 	} else {
 		ctx->mcscxfname = nullptr;
 	}
diff --git a/engines/glk/tads/tads2/output.cpp b/engines/glk/tads/tads2/output.cpp
index 33c6a88c660..8dbb7d3084d 100644
--- a/engines/glk/tads/tads2/output.cpp
+++ b/engines/glk/tads/tads2/output.cpp
@@ -1895,7 +1895,7 @@ static int outformatlen_stream(out_stream_info *stream,
 				}
 
 				/* convert the entire string to lower case for searching */
-				strcpy(fmsbuf_srch, fmsbuf);
+				Common::strcpy_s(fmsbuf_srch, fmsbuf);
 				os_strlwr(fmsbuf_srch);
 
 				/* find the string in the format string table */
@@ -3144,7 +3144,7 @@ int tiologopn(tiocxdef *ctx, char *fn)
 		return 1;
 
 	/* save the filename for later */
-	strcpy(logfname, fn);
+	Common::strcpy_s(logfname, fn);
 
 	/* open the new file */
 	logfp = osfopwt(fn, OSFTLOG);
diff --git a/engines/glk/tads/tads2/play.cpp b/engines/glk/tads/tads2/play.cpp
index 6cff7dfb70a..4f7648a6829 100644
--- a/engines/glk/tads/tads2/play.cpp
+++ b/engines/glk/tads/tads2/play.cpp
@@ -273,7 +273,7 @@ startover:
 		if (voc->voccxredo && voc->voccxredobuf[0] != '\0')
 		{
 			/* copy the redo buffer into our internal buffer */
-			strcpy(buf, voc->voccxredobuf);
+			Common::strcpy_s(buf, voc->voccxredobuf);
 
 			/* we've consumed it now, so clear it out */
 			voc->voccxredobuf[0] = '\0';
diff --git a/engines/glk/tads/tads2/runtime_driver.cpp b/engines/glk/tads/tads2/runtime_driver.cpp
index 45974990109..814d72e4716 100644
--- a/engines/glk/tads/tads2/runtime_driver.cpp
+++ b/engines/glk/tads/tads2/runtime_driver.cpp
@@ -42,7 +42,7 @@ namespace TADS2 {
 /* dummy setup function */
 void supgnam(char *buf, tokthdef *tab, objnum sc)
 {
-	strcpy(buf, "???");
+	Common::strcpy_s(buf, TOKNAMMAX + 1, "???");
 }
 
 /* dummy file read functions */
@@ -571,7 +571,7 @@ static void trdmain1(errcxdef *ec, int argc, char *argv[],
 		 */
 		if (osfacc(infile))
 		{
-			strcpy(inbuf, infile);
+			Common::strcpy_s(inbuf, infile);
 			os_defext(inbuf, "gam");
 			infile = inbuf;
 		}
diff --git a/engines/glk/tads/tads2/tads2.cpp b/engines/glk/tads/tads2/tads2.cpp
index fb4ee41e0f3..dc99dfe2388 100644
--- a/engines/glk/tads/tads2/tads2.cpp
+++ b/engines/glk/tads/tads2/tads2.cpp
@@ -37,7 +37,7 @@ void TADS2::runGame() {
 	os_instbrk(true);
 
 	char name[255];
-	strcpy(name, getFilename().c_str());
+	Common::strcpy_s(name, getFilename().c_str());
 	char *argv[2] = { nullptr, name };
 
 	trdmain(2, argv, nullptr, ".sav");
diff --git a/engines/glk/tads/tads2/vocabulary.h b/engines/glk/tads/tads2/vocabulary.h
index 5247d842d85..f3760a1c07f 100644
--- a/engines/glk/tads/tads2/vocabulary.h
+++ b/engines/glk/tads/tads2/vocabulary.h
@@ -372,7 +372,7 @@ int voctok(voccxdef *ctx, char *cmd, char *outbuf,
 		   char **wrd, int lower, int cvt_ones, int show_errors);
 
 /* get types for a word list */
-int vocgtyp(voccxdef *ctx, char **cmd, int *types, char *orgbuf);
+int vocgtyp(voccxdef *ctx, char **cmd, int *types, char *orgbuf, size_t orgbuflen);
 
 /* execute a player command */
 int voccmd(voccxdef *ctx, char *cmd, uint cmdlen);
@@ -382,7 +382,7 @@ int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
 				prpnum defprop, prpnum accprop, prpnum verprop,
 				char *cmd[], objnum otherobj, objnum cmdActor,
 				objnum cmdVerb, objnum cmdPrep, char *cmdbuf,
-				int silent);
+				size_t cmdlen, int silent);
 
 /* display a multiple-object prefix */
 void voc_multi_prefix(voccxdef *ctx, objnum objn,
@@ -392,8 +392,8 @@ void voc_multi_prefix(voccxdef *ctx, objnum objn,
 /* low-level executor */
 int execmd(voccxdef *ctx, objnum actor, objnum prep,
 		   char *vverb, char *vprep, vocoldef *dolist, vocoldef *iolist,
-		   char **cmd, int *typelist,
-		   char *cmdbuf, int wrdcnt, uchar **preparse_list, int *next_start);
+		   char **cmd, int *typelist, char *cmdbuf, size_t cmdlen,
+		   int wrdcnt, uchar **preparse_list, int *next_start);
 
 /* recursive command execution */
 int execmd_recurs(voccxdef *ctx, objnum actor, objnum verb,
diff --git a/engines/glk/tads/tads2/vocabulary_parser.cpp b/engines/glk/tads/tads2/vocabulary_parser.cpp
index fdfda30e0ca..32cadea85f9 100644
--- a/engines/glk/tads/tads2/vocabulary_parser.cpp
+++ b/engines/glk/tads/tads2/vocabulary_parser.cpp
@@ -1613,7 +1613,7 @@ static char *voc_read_oops(voccxdef *ctx, char *oopsbuf, size_t oopsbuflen,
  *   figure out what parts of speech are associated with each
  *   word in a tokenized command list
  */
-int vocgtyp(voccxdef *ctx, char *cmd[], int types[], char *orgbuf)
+int vocgtyp(voccxdef *ctx, char *cmd[], int types[], char *orgbuf, size_t orgbuflen)
 {
 	int      cur;
 	int      t;
@@ -1800,7 +1800,7 @@ startover:
 					 *   this must be a brand new command.  Replace the
 					 *   original command with the new command.
 					 */
-					strcpy(orgbuf, oopsbuf);
+					Common::strcpy_s(orgbuf, orgbuflen, oopsbuf);
 
 					/*
 					 *   forget we had an unknown word so that we're sure
@@ -1852,7 +1852,7 @@ startover:
 				if (t & (1 << i))
 				{
 					if (cnt) *p++ = ',';
-					strcpy(p, type_names[i]);
+					Common::strcpy_s(p, sizeof(buf) - (p - buf), type_names[i]);
 					p += strlen(p);
 					++cnt;
 				}
@@ -2202,7 +2202,7 @@ static void vocaddof(voccxdef *ctx, char *buf)
 		buf[len + oldlen] = '\0';
 	}
 	else
-		strcat(buf, "of");
+		Common::strcat_s(buf, VOCBUFSIZ, "of");
 }
 
 /* ------------------------------------------------------------------------ */
@@ -2421,13 +2421,13 @@ void voc_make_obj_name(voccxdef *ctx, char *namebuf, char *cmd[],
 		if (voc_check_special(ctx, cmd[i], VOCW_OF))
 			vocaddof(ctx, namebuf);
 		else
-			strcat(namebuf, cmd[i]);
+			Common::strcat_s(namebuf, VOCBUFSIZ, cmd[i]);
 
 		if (cmd[i][strlen(cmd[i])-1] == '.' && i + 1 < lastwrd)
-			strcat(namebuf, "\\");
+			Common::strcat_s(namebuf, VOCBUFSIZ, "\\");
 
 		if (i + 1 < lastwrd)
-			strcat(namebuf, " ");
+			Common::strcat_s(namebuf, VOCBUFSIZ, " ");
 	}
 }
 
@@ -4137,7 +4137,7 @@ void voc_parse_disambig(voccxdef *ctx)
 	/* disambiguate the noun list */
 	err = vocdisambig(&ctx_copy, outlist, inlist,
 					  defprop, accprop, verprop, cmd,
-					  otherobj, actor, verb, prep, cmdbuf, silent);
+					  otherobj, actor, verb, prep, cmdbuf, VOCBUFSIZ, silent);
 
 	/*
 	 *   If the error was VOCERR(2) - unknown word - check the input list
@@ -4212,7 +4212,7 @@ void voc_parse_disambig(voccxdef *ctx)
 			ctx_copy.voccxredo = TRUE;
 
 			/* copy the response into the command buffer */
-			strcpy(cmdbuf, oopsbuf);
+			Common::strcpy_s(cmdbuf, VOCBUFSIZ, oopsbuf);
 		}
 		else
 		{
@@ -4262,7 +4262,7 @@ void voc_parse_disambig(voccxdef *ctx)
 				if (i == unk_idx)
 				{
 					/* insert the replacement text */
-					strcpy(p, rpl_text);
+					Common::strcpy_s(p, VOCBUFSIZ - (p - cmdbuf), rpl_text);
 				}
 				else if (*cmd[i] == '"')
 				{
@@ -4314,7 +4314,7 @@ void voc_parse_disambig(voccxdef *ctx)
 				else
 				{
 					/* copy this word */
-					strcpy(p, cmd[i]);
+					Common::strcpy_s(p, VOCBUFSIZ - (p - cmdbuf), cmd[i]);
 				}
 
 				/* move past this token */
@@ -4456,7 +4456,7 @@ void voc_parse_replace_cmd(voccxdef *ctx)
  *   value is nonzero, then that object is the actor.
  */
 static objnum vocgetactor(voccxdef *ctx, char *cmd[], int typelist[],
-						  int cur, int *next, char *cmdbuf)
+						  int cur, int *next, char *cmdbuf, size_t cmdlen)
 {
 	int       l;
 	vocoldef *nounlist;
@@ -4501,7 +4501,7 @@ static objnum vocgetactor(voccxdef *ctx, char *cmd[], int typelist[],
 		/* disambiguate it using the selected properties */
 		if (vocdisambig(ctx, actlist, nounlist, PRP_DODEFAULT, valprop,
 						verprop, cmd, MCMONINV, ctx->voccxme,
-						ctx->voccxvtk, MCMONINV, cmdbuf, FALSE))
+						ctx->voccxvtk, MCMONINV, cmdbuf, cmdlen, FALSE))
 		{
 			/*
 			 *   if we have an unknown word in the list, assume for the
@@ -5246,7 +5246,7 @@ int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
 				prpnum defprop, prpnum accprop, prpnum verprop,
 				char *cmd[], objnum otherobj, objnum cmdActor,
 				objnum cmdVerb, objnum cmdPrep, char *cmdbuf,
-				int silent)
+				size_t cmdlen, int silent)
 {
 	int       inpos;
 	int       outpos;
@@ -5436,7 +5436,7 @@ int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
 			{
 				err = vocdisambig(ctx, exclist2, exclist, defprop, accprop,
 								  verprop, cmd, otherobj, cmdActor,
-								  cmdVerb, cmdPrep, cmdbuf, silent);
+								  cmdVerb, cmdPrep, cmdbuf, cmdlen, silent);
 				if (err != 0)
 					goto done;
 
@@ -5985,17 +5985,17 @@ int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
 					{
 						/* quote the space if the last word ended with '.' */
 						if (p[strlen(p)-1] == '.')
-							strcat(usrobj, "\\");
+							Common::strcat_s(usrobj, VOCBUFSIZ, "\\");
 
 						/* add the space */
-						strcat(usrobj, " ");
+						Common::strcat_s(usrobj, VOCBUFSIZ, " ");
 					}
 
 					/* add the current word, or "of" if it's "of" */
 					if (voc_check_special(ctx, p, VOCW_OF))
 						vocaddof(ctx, usrobj);
 					else
-						strcat(usrobj, p);
+						Common::strcat_s(usrobj, VOCBUFSIZ, p);
 				}
 			}
 
@@ -6676,7 +6676,7 @@ int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
 							   (int)VOCBUFSIZ, 2) == VOCREAD_REDO)
 				{
 					/* they want to treat the input as a new command */
-					strcpy(cmdbuf, disnewbuf);
+					Common::strcpy_s(cmdbuf, cmdlen, disnewbuf);
 					ctx->voccxunknown = 0;
 					ctx->voccxredo = TRUE;
 					err = VOCERR(43);
@@ -6722,14 +6722,14 @@ int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
 
 				/* tokenize the sentence */
 				diswordlist[wrdcnt] = nullptr;
-				if (vocgtyp(ctx, diswordlist, distypelist, cmdbuf)
+				if (vocgtyp(ctx, diswordlist, distypelist, cmdbuf, cmdlen)
 					|| ctx->voccxunknown != 0)
 				{
 					/*
 					 *   there's an unknown word or other problem - retry
 					 *   the input as an entirely new command
 					 */
-					strcpy(cmdbuf, disnewbuf);
+					Common::strcpy_s(cmdbuf, cmdlen, disnewbuf);
 					ctx->voccxunknown = 0;
 					ctx->voccxredo = TRUE;
 					err = VOCERR(2);
@@ -7005,7 +7005,7 @@ int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
 										 *   replace the entire adjective
 										 *   phrase with "such"
 										 */
-										strcpy(newobj, "such");
+										Common::strcpy_s(newobj, VOCBUFSIZ, "such");
 
 										/*
 										 *   stop here - don't add any
@@ -7017,16 +7017,16 @@ int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
 
 									/* add a space if we have a prior word */
 									if (newobj[0] != '\0')
-										strcat(newobj, " ");
+										Common::strcat_s(newobj, VOCBUFSIZ, " ");
 
 									/* add this word */
-									strcat(newobj, p);
+									Common::strcat_s(newobj, VOCBUFSIZ, p);
 								}
 							}
 							else
 							{
 								/* no noun phrase found */
-								strcpy(newobj, "such");
+								Common::strcpy_s(newobj, VOCBUFSIZ, "such");
 							}
 
 							/* didn't find anything - complain and give up */
@@ -7067,7 +7067,7 @@ int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
 						}
 
 						/* retry as an entire new command */
-						strcpy(cmdbuf, disnewbuf);
+						Common::strcpy_s(cmdbuf, cmdlen, disnewbuf);
 						ctx->voccxunknown = 0;
 						ctx->voccxredo = TRUE;
 						err = VOCERR(43);
@@ -7112,7 +7112,7 @@ done:
 static int vocready(voccxdef *ctx, char *cmd[], int *typelist, int cur,
 					objnum cmdActor, objnum cmdPrep, char *vverb, char *vprep,
 					vocoldef *dolist, vocoldef *iolist, int *errp,
-					char *cmdbuf, int first_word, uchar **preparse_list,
+					char *cmdbuf, size_t cmdlen, int first_word, uchar **preparse_list,
 					int *next_start)
 {
 	if (cur != -1
@@ -7130,14 +7130,14 @@ static int vocready(voccxdef *ctx, char *cmd[], int *typelist, int cur,
 
 		*errp = execmd(ctx, cmdActor, cmdPrep, vverb, vprep, dolist, iolist,
 					   &cmd[first_word], &typelist[first_word],cmdbuf,
-					   cur - first_word, preparse_list, next_start);
+					   cmdlen, cur - first_word, preparse_list, next_start);
 		return(TRUE);
 	}
 	return(FALSE);
 }
 
 /* execute a single command */
-static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
+static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf, size_t cmdlen,
 				   objnum *cmdActorp, int first)
 {
 	int       cur;
@@ -7192,7 +7192,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 	memset(typelist, 0, VOCBUFSIZ*sizeof(typelist[0]));
 
 	/* get the types of the words in the command */
-	if (vocgtyp(ctx, cmd, typelist, cmdbuf))
+	if (vocgtyp(ctx, cmd, typelist, cmdbuf, cmdlen))
 	{
 		retval = 1;
 		goto done;
@@ -7291,7 +7291,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 			cmd[cnt] = nullptr;
 
 			/* generate the type list for the new list */
-			if (vocgtyp(ctx, cmd, typelist, cmdbuf))
+			if (vocgtyp(ctx, cmd, typelist, cmdbuf, cmdlen))
 			{
 				/* return an error */
 				retval = 1;
@@ -7354,7 +7354,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 				preparseCmd_stat.active = FALSE;
 
 				/* get the type list for the original list again */
-				if (vocgtyp(ctx, cmd, typelist, cmdbuf))
+				if (vocgtyp(ctx, cmd, typelist, cmdbuf, cmdlen))
 				{
 					/* return the error */
 					retval = 1;
@@ -7382,7 +7382,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 
 		{
 			/* look for an explicit actor in the command */
-			if ((o = vocgetactor(ctx, cmd, typelist, cur, &next, cmdbuf))
+			if ((o = vocgetactor(ctx, cmd, typelist, cur, &next, cmdbuf, cmdlen))
 				!= MCMONINV)
 			{
 				/* skip the actor noun phrase in the input */
@@ -7432,7 +7432,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 		/* execute if the command is just a verb */
 		if (vocready(ctx, cmd, typelist, cur, cmdActor, cmdPrep,
 					 vverb, vprep, dolist, iolist, &err, cmdbuf,
-					 first_word, &preparse_list, &next_start))
+					 cmdlen, first_word, &preparse_list, &next_start))
 			continue;
 
 		/*
@@ -7447,7 +7447,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 				vprep = cmd[cur++];
 				if (vocready(ctx, cmd, typelist, cur, cmdActor, cmdPrep,
 							 vverb, vprep, dolist, iolist, &err, cmdbuf,
-							 first_word, &preparse_list, &next_start))
+							 cmdlen, first_word, &preparse_list, &next_start))
 					continue;
 			}
 			else
@@ -7584,7 +7584,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 					 vverb, vprep,
 					 swapObj ? iolist : dolist,
 					 swapObj ? dolist : iolist,
-					 &err, cmdbuf, first_word, &preparse_list,
+					 &err, cmdbuf, cmdlen, first_word, &preparse_list,
 					 &next_start))
 			continue;
 
@@ -7630,7 +7630,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 				if ((err = execmd(ctx, cmdActor, cmdPrep, vverb, vprep,
 								  dolist, iolist,
 								  &cmd[first_word], &typelist[first_word],
-								  cmdbuf, cur - first_word,
+								  cmdbuf, cmdlen, cur - first_word,
 								  &preparse_list, &next_start)) != 0)
 				{
 					retval = 1;
@@ -7701,7 +7701,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 
 				if (vocready(ctx, cmd, typelist, cur, cmdActor, cmdPrep,
 							 vverb, vprep, dolist, iolist, &err, cmdbuf,
-							 first_word, &preparse_list, &next_start))
+							 cmdlen, first_word, &preparse_list, &next_start))
 					continue;
 				else if ((typelist[cur] & VOCT_PREP) &&
 						 vocffw(ctx, vverb, vvlen, cmd[cur],
@@ -7711,7 +7711,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 					vprep = cmd[cur++];
 					if (vocready(ctx, cmd, typelist, cur, cmdActor,
 								 cmdPrep, vverb, vprep, dolist, iolist,
-								 &err, cmdbuf, first_word, &preparse_list,
+								 &err, cmdbuf, cmdlen, first_word, &preparse_list,
 								 &next_start))
 						continue;
 					else
@@ -7874,7 +7874,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 			err = execmd(ctx, cmdActor, cmdPrep, vverb, vprep,
 						 iolist, dolist,
 						 &cmd[first_word], &typelist[first_word], cmdbuf,
-						 cur - first_word, &preparse_list, &next_start);
+						 cmdlen, cur - first_word, &preparse_list, &next_start);
 			continue;
 		}
 		else if (cnt < 0)
@@ -7891,7 +7891,7 @@ static int voc1cmd(voccxdef *ctx, char *cmd[], char *cmdbuf,
 done:
 	/* copy back the command if we need to redo */
 	if (ctx->voccxredo && cmdbuf != origcmdbuf)
-		strcpy(origcmdbuf, cmdbuf);
+		Common::strcpy_s(origcmdbuf, cmdlen, cmdbuf);
 
 	/* return the status */
 	VOC_RETVAL(ctx, save_sp, retval);
@@ -8055,7 +8055,7 @@ int voccmd(voccxdef *ctx, char *cmd, uint cmdlen)
 		for (;;)
 		{
 			/* try processing the command */
-			if (voc1cmd(ctx, &wordlist[next], cmd, &cmdActor, first))
+			if (voc1cmd(ctx, &wordlist[next], cmd, cmdlen, &cmdActor, first))
 			{
 				/*
 				 *   If the unknown word flag is set, try the command
diff --git a/engines/glk/zcode/detection.cpp b/engines/glk/zcode/detection.cpp
index 3fedcf3c988..feb920f3d08 100644
--- a/engines/glk/zcode/detection.cpp
+++ b/engines/glk/zcode/detection.cpp
@@ -94,9 +94,9 @@ bool ZCodeMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 				continue;
 			}
 			gameFile.seek(18);
-			strcpy(&serial[0], "\"");
+			Common::strcpy_s(&serial[0], sizeof(serial), "\"");
 			gameFile.read(&serial[1], 6);
-			strcpy(&serial[7], "\"");
+			Common::strcpy_s(&serial[7], sizeof(serial)-7, "\"");
 		} else {
 			Blorb b(*file, INTERPRETER_ZCODE);
 			Common::SeekableReadStream *f = b.createReadStreamForMember("game");
@@ -104,9 +104,9 @@ bool ZCodeMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 
 			if (!emptyBlorb) {
 				f->seek(18);
-				strcpy(&serial[0], "\"");
+				Common::strcpy_s(&serial[0], sizeof(serial), "\"");
 				f->read(&serial[1], 6);
-				strcpy(&serial[7], "\"");
+				Common::strcpy_s(&serial[7], sizeof(serial) - 7, "\"");
 				delete f;
 			}
 		}


Commit: f26ce1e4ffba89d6e23e3957d0dc4aa8907bfa73
    https://github.com/scummvm/scummvm/commit/f26ce1e4ffba89d6e23e3957d0dc4aa8907bfa73
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GOB: Don't use unsafe strcat and strcpy

Changed paths:
    engines/gob/draw.cpp
    engines/gob/hotspots.cpp
    engines/gob/inter.cpp
    engines/gob/inter_v2.cpp
    engines/gob/map_v1.cpp
    engines/gob/util.cpp
    engines/gob/util.h
    engines/gob/variables.cpp


diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index 360edbe13b1..2ae69dc6ac9 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -514,7 +514,7 @@ void Draw::oPlaytoons_sub_F_1B(uint16 id, int16 left, int16 top, int16 right, in
 		_vm->_game->_script->pop();
 	}
 
-	strcpy(paramStr, tmpStr);
+	Common::strcpy_s(paramStr, 200, tmpStr);
 
 	if (fontIndex >= kFontCount) {
 		warning("Draw::oPlaytoons_sub_F_1B(): Font %d > Count %d", fontIndex, kFontCount);
diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp
index 03a27247d81..a960112264c 100644
--- a/engines/gob/hotspots.cpp
+++ b/engines/gob/hotspots.cpp
@@ -917,7 +917,7 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig
 	while (1) {
 		// If we the edit field has enough space, add a space for the new character
 		Common::strlcpy(tempStr, str, 255);
-		strcat(tempStr, " ");
+		Common::strcat_s(tempStr, " ");
 		if ((editSize != 0) && strlen(tempStr) > editSize)
 			Common::strlcpy(tempStr, str, 256);
 
diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp
index f81fb13e07f..c0145500a7a 100644
--- a/engines/gob/inter.cpp
+++ b/engines/gob/inter.cpp
@@ -404,7 +404,7 @@ void Inter::storeString(uint16 index, uint16 type, const char *value) {
 
 	case TYPE_IMM_INT8:
 	case TYPE_VAR_INT8:
-		strcpy(str, value);
+		Common::strcpy_s(str, maxLength, value);
 		break;
 
 	case TYPE_ARRAY_INT8:
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index caa0e6f6f63..c9c109540d6 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -1565,7 +1565,7 @@ void Inter_v2::o2_loadInfogramesIns(OpGobParams &params) {
 	varName = _vm->_game->_script->readInt16();
 
 	Common::strlcpy(fileName, GET_VAR_STR(varName), 16);
-	strcat(fileName, ".INS");
+	Common::strcat_s(fileName, ".INS");
 
 	_vm->_sound->infogramesLoadInstruments(fileName);
 }
@@ -1577,7 +1577,7 @@ void Inter_v2::o2_playInfogrames(OpGobParams &params) {
 	varName = _vm->_game->_script->readInt16();
 
 	Common::strlcpy(fileName, GET_VAR_STR(varName), 16);
-	strcat(fileName, ".DUM");
+	Common::strcat_s(fileName, ".DUM");
 
 	_vm->_sound->infogramesLoadSong(fileName);
 	_vm->_sound->infogramesPlay();
@@ -1662,9 +1662,9 @@ int16 Inter_v2::loadSound(int16 search) {
 		Common::strlcpy(sndfile, _vm->_game->_script->readString(9), 10);
 
 		if (type == SOUND_ADL)
-			strcat(sndfile, ".ADL");
+			Common::strcat_s(sndfile, ".ADL");
 		else
-			strcat(sndfile, ".SND");
+			Common::strcat_s(sndfile, ".SND");
 
 		int32 dataSize;
 		byte *dataPtr = _vm->_dataIO->getFile(sndfile, dataSize);
diff --git a/engines/gob/map_v1.cpp b/engines/gob/map_v1.cpp
index 76276470d2f..dc0e93866c1 100644
--- a/engines/gob/map_v1.cpp
+++ b/engines/gob/map_v1.cpp
@@ -65,8 +65,8 @@ void Map_v1::loadMapObjects(const char *avjFile) {
 	uint32 gobsPos;
 	uint32 objsPos;
 
-	strcpy(avoName, _sourceFile);
-	strcat(avoName, ".avo");
+	Common::strcpy_s(avoName, sizeof(avoName) - 4, _sourceFile);
+	Common::strcat_s(avoName, ".avo");
 
 	int32 size;
 	dataBuf = _vm->_dataIO->getFile(avoName, size);
@@ -151,8 +151,8 @@ void Map_v1::loadSounds(Common::SeekableReadStream &data) {
 	for (int i = 0; i < count; i++) {
 		data.read(buf, 14);
 		buf[14] = 0;
-		strcat(buf, ".SND");
-		strcpy(sndNames[i], buf);
+		Common::strcat_s(buf, ".SND");
+		Common::strcpy_s(sndNames[i], buf);
 	}
 
 	_vm->_sound->sampleLoad(&_vm->_goblin->_soundData[14], SOUND_SND, "diamant1.snd");
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index c9f315c30c2..65e305affb6 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -534,9 +534,9 @@ void Util::cleanupStr(char *str) {
 	char *start, *end;
 	char buf[300];
 
-	strcpy(buf, trStr1);
-	strcat(buf, trStr2);
-	strcat(buf, trStr3);
+	Common::strcpy_s(buf, trStr1);
+	Common::strcat_s(buf, trStr2);
+	Common::strcat_s(buf, trStr3);
 
 	// Translating "wrong" characters
 	for (size_t i = 0; i < strlen(str); i++)
@@ -620,6 +620,7 @@ void Util::deleteList(List *list) {
 	delete list;
 }
 
+#if 0
 char *Util::setExtension(char *str, const char *ext) {
 	assert(str && ext);
 
@@ -633,6 +634,7 @@ char *Util::setExtension(char *str, const char *ext) {
 	strcat(str, ext);
 	return str;
 }
+#endif
 
 Common::String Util::setExtension(const Common::String &str, const Common::String &ext) {
 	if (str.empty())
diff --git a/engines/gob/util.h b/engines/gob/util.h
index def95f612dc..c5938d93430 100644
--- a/engines/gob/util.h
+++ b/engines/gob/util.h
@@ -136,7 +136,7 @@ public:
 	static void listDropFront(List *list);
 	static void deleteList(List *list);
 
-	static char *setExtension(char *str, const char *ext);
+	//static char *setExtension(char *str, const char *ext);
 	static Common::String setExtension(const Common::String &str, const Common::String &ext);
 
 	/** Read a constant-length string out of a stream. */
diff --git a/engines/gob/variables.cpp b/engines/gob/variables.cpp
index 4d7dba4d427..725d5371093 100644
--- a/engines/gob/variables.cpp
+++ b/engines/gob/variables.cpp
@@ -85,7 +85,7 @@ void Variables::writeOffString(uint32 offset, const char *value) {
 	uint32 length = strlen(value);
 	assert((offset + length + 1) < _size);
 
-	strcpy((char *)(_vars + offset), value);
+	Common::strcpy_s((char *)(_vars + offset), _size - offset, value);
 }
 
 uint8 Variables::readVar8(uint32 var) const {


Commit: 0a0d21b904984a4a8b9a7c5fa1ba8dd29866f11a
    https://github.com/scummvm/scummvm/commit/0a0d21b904984a4a8b9a7c5fa1ba8dd29866f11a
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GRIFFON: Don't use unsafe strcat and strcpy

Changed paths:
    engines/griffon/combat.cpp
    engines/griffon/dialogs.cpp
    engines/griffon/draw.cpp
    engines/griffon/gfx.cpp
    engines/griffon/logic.cpp


diff --git a/engines/griffon/combat.cpp b/engines/griffon/combat.cpp
index 1673db81af8..5a3d86c4807 100644
--- a/engines/griffon/combat.cpp
+++ b/engines/griffon/combat.cpp
@@ -553,7 +553,7 @@ void GriffonEngine::damageNPC(int npcnum, int damage, int spell) {
 	int fcol;
 
 	if (damage == 0) {
-		strcpy(line, "miss!");
+		Common::strcpy_s(line, "miss!");
 		fcol = 2;
 	} else {
 		int ratio = 0;
@@ -1021,7 +1021,7 @@ void GriffonEngine::damagePlayer(int damage) {
 
 	sprintf(line, "-%i", damage);
 	if (damage == 0)
-		strcpy(line, "miss!");
+		Common::strcpy_s(line, "miss!");
 
 	addFloatText(line, _player.px + 12 - 4 * strlen(line), _player.py + 16, 4);
 
diff --git a/engines/griffon/dialogs.cpp b/engines/griffon/dialogs.cpp
index 9e9de9dc7ef..128d6d64bd4 100644
--- a/engines/griffon/dialogs.cpp
+++ b/engines/griffon/dialogs.cpp
@@ -349,7 +349,7 @@ void GriffonEngine::configMenu() {
 				int vol = (i ==18 ? config.musicVol : config.effectsVol) * 9 / 255;
 				vol = CLIP(vol, 0, 9);
 
-				strcpy(line, "[----------]");
+				Common::strcpy_s(line, "[----------]");
 				line[vol + 1] = 'X';
 				optionValues[i] = line;
 			} else if (i > 21)
@@ -579,7 +579,7 @@ void GriffonEngine::renderSaveStates() {
 			drawString(_videoBuffer2, line, sx, sy, cc);
 
 			if (_playera.level == 22)
-				strcpy(line, "Level: MAX");
+				Common::strcpy_s(line, "Level: MAX");
 			else
 				sprintf(line, "Level: %i", _playera.level);
 
diff --git a/engines/griffon/draw.cpp b/engines/griffon/draw.cpp
index 818c3fb34d6..71a9aeccbae 100644
--- a/engines/griffon/draw.cpp
+++ b/engines/griffon/draw.cpp
@@ -310,7 +310,7 @@ void GriffonEngine::drawHud() {
 
 		sprintf(line, "Level : %i", _player.level);
 		if (_player.level == _player.maxLevel)
-			strcpy(line, "Level : MAX");
+			Common::strcpy_s(line, "Level : MAX");
 		drawString(_videoBuffer, line, sx, sy + 8, 0);
 
 		// experience
diff --git a/engines/griffon/gfx.cpp b/engines/griffon/gfx.cpp
index 96825886792..7fc5567754f 100644
--- a/engines/griffon/gfx.cpp
+++ b/engines/griffon/gfx.cpp
@@ -58,7 +58,7 @@ void GriffonEngine::addFloatText(const char *stri, float xloc, float yloc, int c
 			_floatText[i].x = xloc;
 			_floatText[i].y = yloc;
 			_floatText[i].col = col;
-			strcpy(_floatText[i].text, stri);
+			Common::strcpy_s(_floatText[i].text, 64, stri);
 			return;
 		}
 	}
diff --git a/engines/griffon/logic.cpp b/engines/griffon/logic.cpp
index 1e44c873c48..265ecf945b8 100644
--- a/engines/griffon/logic.cpp
+++ b/engines/griffon/logic.cpp
@@ -1637,20 +1637,20 @@ void GriffonEngine::updateSpells() {
 					}
 
 					char line[256];
-					strcpy(line, "Found... nothing...");
+					Common::strcpy_s(line, "Found... nothing...");
 
 					for (int f1 = 0; f1 < 5; f1++) {
 						if (foundel[f1] && !_player.foundSpell[f1]) {
 							_player.foundSpell[f1] = 1;
 							_player.spellCharge[f1] = 0;
 							if (f1 == 1)
-								strcpy(line, "Found... Water Essence");
+								Common::strcpy_s(line, "Found... Water Essence");
 							if (f1 == 2)
-								strcpy(line, "Found... Metal Essence");
+								Common::strcpy_s(line, "Found... Metal Essence");
 							if (f1 == 3)
-								strcpy(line, "Found... Earth Essence");
+								Common::strcpy_s(line, "Found... Earth Essence");
 							if (f1 == 4)
-								strcpy(line, "Found... Fire Essence");
+								Common::strcpy_s(line, "Found... Fire Essence");
 							break;
 						}
 					}


Commit: e15aa921183bf9055760102c45c6f5688a6de522
    https://github.com/scummvm/scummvm/commit/e15aa921183bf9055760102c45c6f5688a6de522
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GRIM: Don't use unsafe strcat and strcpy

Changed paths:
    engines/grim/imuse/imuse_sndmgr.cpp
    engines/grim/imuse/imuse_track.cpp
    engines/grim/lua/ldo.cpp
    engines/grim/lua/lstring.cpp
    engines/grim/lua/lvm.cpp
    engines/grim/model.cpp
    engines/grim/resource.cpp
    engines/grim/sector.cpp
    engines/grim/set.cpp


diff --git a/engines/grim/imuse/imuse_sndmgr.cpp b/engines/grim/imuse/imuse_sndmgr.cpp
index 6b2cf3fdeca..74e1b2aa7ae 100644
--- a/engines/grim/imuse/imuse_sndmgr.cpp
+++ b/engines/grim/imuse/imuse_sndmgr.cpp
@@ -181,7 +181,7 @@ ImuseSndMgr::SoundDesc *ImuseSndMgr::openSound(const char *soundName, int volGro
 		error("ImuseSndMgr::openSound() Can't alloc free sound slot");
 	}
 
-	strcpy(sound->name, soundName);
+	Common::strcpy_s(sound->name, soundName);
 	sound->volGroupId = volGroupId;
 	sound->inStream = nullptr;
 
diff --git a/engines/grim/imuse/imuse_track.cpp b/engines/grim/imuse/imuse_track.cpp
index f9d6de1949f..069fea83011 100644
--- a/engines/grim/imuse/imuse_track.cpp
+++ b/engines/grim/imuse/imuse_track.cpp
@@ -135,7 +135,7 @@ bool Imuse::startSound(const char *soundName, int volGroupId, int hookId, int vo
 
 	int bits = 0, freq = 0, channels = 0;
 
-	strcpy(track->soundName, soundName);
+	Common::strcpy_s(track->soundName, soundName);
 	track->soundDesc = _sound->openSound(soundName, volGroupId);
 
 	if (!track->soundDesc)
diff --git a/engines/grim/lua/ldo.cpp b/engines/grim/lua/ldo.cpp
index 5ef1483819d..3b05144c2d3 100644
--- a/engines/grim/lua/ldo.cpp
+++ b/engines/grim/lua/ldo.cpp
@@ -8,6 +8,7 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
 #define FORBIDDEN_SYMBOL_EXCEPTION_stderr
 #define FORBIDDEN_SYMBOL_EXCEPTION_exit
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
 
 #ifdef _MSC_VER
 #pragma warning(disable:4611)
diff --git a/engines/grim/lua/lstring.cpp b/engines/grim/lua/lstring.cpp
index 632945a4da0..f226f6d8ab8 100644
--- a/engines/grim/lua/lstring.cpp
+++ b/engines/grim/lua/lstring.cpp
@@ -5,6 +5,7 @@
 
 #define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
 #define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
 
 #include "common/util.h"
 
diff --git a/engines/grim/lua/lvm.cpp b/engines/grim/lua/lvm.cpp
index d0888fd0084..c7279ac44da 100644
--- a/engines/grim/lua/lvm.cpp
+++ b/engines/grim/lua/lvm.cpp
@@ -5,6 +5,7 @@
 
 #define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
 #define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
 
 #include "engines/grim/lua/lauxlib.h"
 #include "engines/grim/lua/ldo.h"
diff --git a/engines/grim/model.cpp b/engines/grim/model.cpp
index c643fc2fe80..6b23607d260 100644
--- a/engines/grim/model.cpp
+++ b/engines/grim/model.cpp
@@ -142,7 +142,7 @@ void Model::loadText(TextSplitter *ts) {
 		_materials[i] = nullptr;
 
 		ts->scanString("%d: %32s", 2, &num, materialName);
-		strcpy(_materialNames[num], materialName);
+		Common::strcpy_s(_materialNames[num], materialName);
 		loadMaterial(num, _cmap);
 	}
 
diff --git a/engines/grim/resource.cpp b/engines/grim/resource.cpp
index ebfd6ed7858..b6a170458ca 100644
--- a/engines/grim/resource.cpp
+++ b/engines/grim/resource.cpp
@@ -309,7 +309,7 @@ void ResourceLoader::putIntoCache(const Common::String &fname, byte *res, uint32
 	entry.resPtr = res;
 	entry.len = len;
 	entry.fname = new char[fname.size() + 1];
-	strcpy(entry.fname, fname.c_str());
+	Common::strcpy_s(entry.fname, fname.size() + 1, fname.c_str());
 	_cacheMemorySize += len;
 	_cache.push_back(entry);
 	_cacheDirty = true;
diff --git a/engines/grim/sector.cpp b/engines/grim/sector.cpp
index dda177ffbbd..c37c408850a 100644
--- a/engines/grim/sector.cpp
+++ b/engines/grim/sector.cpp
@@ -125,7 +125,7 @@ void Sector::load(TextSplitter &ts) {
 		ts.scanString(" sector %256s", 1, buf);
 	else {
 		ts.nextLine();
-		strcpy(buf, "");
+		buf[0] = '\0';
 	}
 
 	ts.scanString(" id %d", 1, &ident);
diff --git a/engines/grim/set.cpp b/engines/grim/set.cpp
index 7af6cdebc61..ecdc433041b 100644
--- a/engines/grim/set.cpp
+++ b/engines/grim/set.cpp
@@ -564,7 +564,7 @@ void Light::load(TextSplitter &ts) {
 		ts.scanString(" light %256s", 1, buf);
 	else {
 		ts.nextLine();
-		strcpy(buf, "");
+		buf[0] = '\0';
 	}
 	_name = buf;
 


Commit: 6a391ff462535d03fcfdac2d5bfb9f9016d5eb75
    https://github.com/scummvm/scummvm/commit/6a391ff462535d03fcfdac2d5bfb9f9016d5eb75
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
HOPKINS: Don't use unsafe strcat and strcpy

Changed paths:
    engines/hopkins/hopkins.cpp


diff --git a/engines/hopkins/hopkins.cpp b/engines/hopkins/hopkins.cpp
index 5d40a543b58..e6127879c20 100644
--- a/engines/hopkins/hopkins.cpp
+++ b/engines/hopkins/hopkins.cpp
@@ -2419,7 +2419,7 @@ void HopkinsEngine::loadCredits() {
 		_globals->_creditsItem[0]._color = '1';
 		_globals->_creditsItem[0]._actvFl = true;
 		_globals->_creditsItem[0]._linePosY = _globals->_creditsPosY;
-		strcpy((char *)_globals->_creditsItem[0]._line, "The End");
+		Common::strcpy_s(_globals->_creditsItem[0]._line, "The End");
 		_globals->_creditsItem[0]._lineSize = 7;
 		return;
 	}


Commit: 5fbf81f4983575ca93a7b0f2047f204b2c16b115
    https://github.com/scummvm/scummvm/commit/5fbf81f4983575ca93a7b0f2047f204b2c16b115
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
HUGO: Don't use unsafe strcat and strcpy

Changed paths:
    engines/hugo/intro.cpp
    engines/hugo/parser.cpp
    engines/hugo/parser_v1d.cpp
    engines/hugo/parser_v3d.cpp


diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp
index 5d1ec14614e..3185443af82 100644
--- a/engines/hugo/intro.cpp
+++ b/engines/hugo/intro.cpp
@@ -121,11 +121,11 @@ bool intro_v1d::introPlay() {
 
 			char buffer[80];
 			if (_vm->_boot._registered == kRegRegistered)
-				strcpy(buffer, "Registered Version");
+				Common::strcpy_s(buffer, "Registered Version");
 			else if (_vm->_boot._registered == kRegShareware)
-				strcpy(buffer, "Shareware Version");
+				Common::strcpy_s(buffer, "Shareware Version");
 			else if (_vm->_boot._registered == kRegFreeware)
-				strcpy(buffer, "Freeware Version");
+				Common::strcpy_s(buffer, "Freeware Version");
 			else
 				error("Unknown registration flag in hugo.bsf: %d", _vm->_boot._registered);
 
@@ -138,7 +138,7 @@ bool intro_v1d::introPlay() {
 			}
 
 			// SCRIPT, size 24-16
-			strcpy(buffer, "Hugo's");
+			Common::strcpy_s(buffer, "Hugo's");
 
 			if (_font.loadFromFON("SCRIPT.FON")) {
 				_font.drawString(&_surf, buffer, 0, 20, 320, _TMAGENTA, Graphics::kTextAlignCenter);
@@ -152,7 +152,7 @@ bool intro_v1d::introPlay() {
 			if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 24)))
 				error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 24");
 
-			strcpy(buffer, "House of Horrors !");
+			Common::strcpy_s(buffer, "House of Horrors !");
 			_font.drawString(&_surf, buffer, 0, 50, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
 			break;
 		case 2:
@@ -162,7 +162,7 @@ bool intro_v1d::introPlay() {
 			if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 14)))
 				error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 14");
 
-			strcpy(buffer, "S t a r r i n g :");
+			Common::strcpy_s(buffer, "S t a r r i n g :");
 			_font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
 			break;
 		case 3:
@@ -170,7 +170,7 @@ bool intro_v1d::introPlay() {
 			if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 18)))
 				error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 18");
 
-			strcpy(buffer, "Hugo !");
+			Common::strcpy_s(buffer, "Hugo !");
 			_font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
 			break;
 		case 4:
@@ -180,36 +180,36 @@ bool intro_v1d::introPlay() {
 			if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 14)))
 				error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 14");
 
-			strcpy(buffer, "P r o d u c e d  b y :");
+			Common::strcpy_s(buffer, "P r o d u c e d  b y :");
 			_font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
 			break;
 		case 5:
 			// TROMAN size 16-9
-			strcpy(buffer, "David P Gray !");
+			Common::strcpy_s(buffer, "David P Gray !");
 			_font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
 			break;
 		case 6:
 			_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
 
 			// TROMAN, size 16-9
-			strcpy(buffer, "D i r e c t e d   b y :");
+			Common::strcpy_s(buffer, "D i r e c t e d   b y :");
 			_font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
 			break;
 		case 7:
 			// TROMAN, size 16-9
-			strcpy(buffer, "David P Gray !");
+			Common::strcpy_s(buffer, "David P Gray !");
 			_font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
 			break;
 		case 8:
 			_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
 
 			// TROMAN, size 16-9
-			strcpy(buffer, "M u s i c   b y :");
+			Common::strcpy_s(buffer, "M u s i c   b y :");
 			_font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
 			break;
 		case 9:
 			// TROMAN, size 16-9
-			strcpy(buffer, "David P Gray !");
+			Common::strcpy_s(buffer, "David P Gray !");
 			_font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
 			break;
 		case 10:
@@ -219,7 +219,7 @@ bool intro_v1d::introPlay() {
 			if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 18)))
 				error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 18");
 
-			strcpy(buffer, "E n j o y !");
+			Common::strcpy_s(buffer, "E n j o y !");
 			_font.drawString(&_surf, buffer, 0, 100, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
 			break;
 		default:
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index 5c500562f48..780137f37be 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -260,7 +260,7 @@ void Parser::charHandler() {
 	if (gameStatus._recallFl) {
 		// Copy previous line to current cmdline
 		gameStatus._recallFl = false;
-		strcpy(_cmdLine, _vm->_line);
+		Common::strcpy_s(_cmdLine, _vm->_line);
 		_cmdLineIndex = strlen(_cmdLine);
 	}
 
diff --git a/engines/hugo/parser_v1d.cpp b/engines/hugo/parser_v1d.cpp
index e31eb8b65ed..ccaf0be771d 100644
--- a/engines/hugo/parser_v1d.cpp
+++ b/engines/hugo/parser_v1d.cpp
@@ -88,13 +88,13 @@ bool Parser_v1d::isNear_v1(const char *verb, const char *noun, Object *obj, char
 		return true;
 	} else if (obj->_screenIndex != *_vm->_screenPtr) { // Not in same screen
 		if (obj->_objValue)
-			strcpy (comment, _vm->_text->getTextParser(kCmtAny4));
+			Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtAny4));
 		return false;
 	}
 
 	if (obj->_cycling == kCycleInvisible) {
 		if (obj->_seqNumb) {                         // There is an image
-			strcpy(comment, _vm->_text->getTextParser(kCmtAny5));
+			Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtAny5));
 			return false;
 		} else {                                    // No image, assume visible
 			if ((obj->_radius < 0) ||
@@ -106,9 +106,9 @@ bool Parser_v1d::isNear_v1(const char *verb, const char *noun, Object *obj, char
 				// or is not carrying it (small, portable objects of value)
 				if (noun) {                         // Don't say unless object specified
 					if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
-						strcpy(comment, _vm->_text->getTextParser(kCmtAny4));
+						Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtAny4));
 					else
-						strcpy(comment, _vm->_text->getTextParser(kCmtClose));
+						Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtClose));
 					}
 				return false;
 			}
@@ -124,9 +124,9 @@ bool Parser_v1d::isNear_v1(const char *verb, const char *noun, Object *obj, char
 		// or is not carrying it (small, portable objects of value)
 		if (noun) {                                 // Don't say unless object specified
 			if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
-				strcpy(comment, _vm->_text->getTextParser(kCmtAny4));
+				Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtAny4));
 			else
-				strcpy(comment, _vm->_text->getTextParser(kCmtClose));
+				Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtClose));
 		}
 		return false;
 	}
diff --git a/engines/hugo/parser_v3d.cpp b/engines/hugo/parser_v3d.cpp
index ba6f2af5831..36a36d67a27 100644
--- a/engines/hugo/parser_v3d.cpp
+++ b/engines/hugo/parser_v3d.cpp
@@ -321,16 +321,16 @@ bool Parser_v3d::isNear_v3(Object *obj, const char *verb, char *comment) const {
 	if (obj->_screenIndex != *_vm->_screenPtr) {
 		// Not in same screen
 		if (obj->_objValue)
-			strcpy(comment, _vm->_text->getTextParser(kCmtAny1));
+			Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtAny1));
 		else
-			strcpy(comment, _vm->_text->getTextParser(kCmtAny2));
+			Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtAny2));
 		return false;
 	}
 
 	if (obj->_cycling == kCycleInvisible) {
 		if (obj->_seqNumb) {
 			// There is an image
-			strcpy(comment, _vm->_text->getTextParser(kCmtAny3));
+			Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtAny3));
 			return false;
 		} else {
 			// No image, assume visible
@@ -341,9 +341,9 @@ bool Parser_v3d::isNear_v3(Object *obj, const char *verb, char *comment) const {
 			} else {
 				// User is not close enough
 				if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
-					strcpy(comment, _vm->_text->getTextParser(kCmtAny1));
+					Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtAny1));
 				else
-					strcpy(comment, _vm->_text->getTextParser(kCmtClose));
+					Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtClose));
 				return false;
 			}
 		}
@@ -356,9 +356,9 @@ bool Parser_v3d::isNear_v3(Object *obj, const char *verb, char *comment) const {
 	} else {
 		// User is not close enough
 		if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
-			strcpy(comment, _vm->_text->getTextParser(kCmtAny1));
+			Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtAny1));
 		else
-			strcpy(comment, _vm->_text->getTextParser(kCmtClose));
+			Common::strcpy_s(comment, kCompLineSize * 5, _vm->_text->getTextParser(kCmtClose));
 		return false;
 	}
 	return true;


Commit: f24d1435652cf5f36dc1976aa1afcc742722cba2
    https://github.com/scummvm/scummvm/commit/f24d1435652cf5f36dc1976aa1afcc742722cba2
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
ICB: Don't use unsafe strcat and strcpy

Changed paths:
    engines/icb/animation_mega_set.cpp
    engines/icb/cluster_manager_pc.cpp
    engines/icb/event_timer.h
    engines/icb/fn_sound.cpp
    engines/icb/function.cpp
    engines/icb/icon_list.cpp
    engines/icb/icon_menu.cpp
    engines/icb/icon_menu_pc.cpp
    engines/icb/line_of_sight.cpp
    engines/icb/mission.cpp
    engines/icb/options_manager_pc.cpp
    engines/icb/remora.cpp
    engines/icb/remora.h
    engines/icb/remora_pc.h
    engines/icb/remora_sprite.cpp
    engines/icb/session.cpp
    engines/icb/set_pc.cpp
    engines/icb/sound/fx_manager.cpp
    engines/icb/string_vest.cpp


diff --git a/engines/icb/animation_mega_set.cpp b/engines/icb/animation_mega_set.cpp
index ba1b80044c9..baead831ac0 100644
--- a/engines/icb/animation_mega_set.cpp
+++ b/engines/icb/animation_mega_set.cpp
@@ -150,8 +150,8 @@ void _vox_image::___init(const char *chr, const char *set, __weapon weapon) {
 	Cancel_override_pose();
 
 	// store these things temporarily so we can recall this function when swapping voxel -> polygon and vice verse...
-	strcpy(temp_chr, chr);
-	strcpy(temp_set, set);
+	Common::strcpy_s(temp_chr, chr);
+	Common::strcpy_s(temp_set, set);
 	temp_weapon = weapon;
 
 	// constructor for mega-set-caps class
@@ -238,7 +238,7 @@ void _vox_image::MakeAnimEntry(int32 i) {
 	if (strName.size() > ANIM_NAME_STR_LEN) {
 		Fatal_error("_vox_image::___init [%s] string too long", strName.c_str());
 	}
-	strcpy(anim_name[i], strName.c_str());
+	Common::strcpy_s(anim_name[i], strName.c_str());
 
 	anim_name_hash[i] = HashString(anim_name[i]);
 
@@ -247,7 +247,7 @@ void _vox_image::MakeAnimEntry(int32 i) {
 	if (strName.size() > ANIM_NAME_STR_LEN) {
 		Fatal_error("_vox_image::___init [%s] string too long", strName.c_str());
 	}
-	strcpy(info_name[i], strName.c_str());
+	Common::strcpy_s(info_name[i], strName.c_str());
 
 	info_name_hash[i] = HashString(info_name[i]);
 
@@ -415,7 +415,7 @@ bool8 _vox_image::Set_texture(const char *tex_name) {
 
 	// set palette to be same as texture
 
-	strcpy(palette_name, texture_name);
+	Common::strcpy_s(palette_name, texture_name);
 	palette_hash = texture_hash;
 
 	// okay preload the texture/palette combo
@@ -428,8 +428,8 @@ bool8 _vox_image::Set_mesh(const char *m_name) {
 	char name[32];
 	int32 len;
 
-	strcpy(name, m_name);
-	strcat(name, ".rap");
+	Common::strcpy_s(name, m_name);
+	Common::strcat_s(name, ".rap");
 
 	len = sprintf(mesh_name, "%s", name);
 	if (len > IMAGE_PATH_STR_LEN)
diff --git a/engines/icb/cluster_manager_pc.cpp b/engines/icb/cluster_manager_pc.cpp
index 24f93d8bf36..155ffb05285 100644
--- a/engines/icb/cluster_manager_pc.cpp
+++ b/engines/icb/cluster_manager_pc.cpp
@@ -193,8 +193,8 @@ int32 ClusterManager::WhichCD(MISSION_ID mission) {
 }
 
 bool8 ClusterManager::CheckForCD(int32 /*number*/) {
-	strcpy(m_cdroot1, "");
-	strcpy(m_cdroot2, "");
+	m_cdroot1[0] = '\0';
+	m_cdroot2[0] = '\0';
 	return TRUE8;
 }
 
diff --git a/engines/icb/event_timer.h b/engines/icb/event_timer.h
index f51bd63fdc4..b7b4a720899 100644
--- a/engines/icb/event_timer.h
+++ b/engines/icb/event_timer.h
@@ -106,7 +106,7 @@ inline _event_timer::_event_timer(const _event_timer &oX) {
 	m_nEnd = oX.m_nEnd;
 	m_nInterval = oX.m_nInterval;
 	m_nCurrentTime = oX.m_nCurrentTime;
-	strcpy(m_pcEventName, oX.m_pcEventName);
+	Common::strcpy_s(m_pcEventName, oX.m_pcEventName);
 }
 
 inline const _event_timer &_event_timer::operator=(const _event_timer &oOpB) {
@@ -115,7 +115,7 @@ inline const _event_timer &_event_timer::operator=(const _event_timer &oOpB) {
 	m_nEnd = oOpB.m_nEnd;
 	m_nInterval = oOpB.m_nInterval;
 	m_nCurrentTime = oOpB.m_nCurrentTime;
-	strcpy(m_pcEventName, oOpB.m_pcEventName);
+	Common::strcpy_s(m_pcEventName, oOpB.m_pcEventName);
 
 	return (*this);
 }
@@ -124,7 +124,7 @@ inline void _event_timer::SetEventName(const char *pcEventName) {
 	if (strlen(pcEventName) >= MAXLEN_EVENT_NAME)
 		Fatal_error("Event name [%s] too long (max %d) in _event_timer::SetEventName()", pcEventName, MAXLEN_EVENT_NAME - 1);
 
-	strcpy(m_pcEventName, pcEventName);
+	Common::strcpy_s(m_pcEventName, pcEventName);
 }
 
 } // End of namespace ICB
diff --git a/engines/icb/fn_sound.cpp b/engines/icb/fn_sound.cpp
index add04fb179d..981be9c713b 100644
--- a/engines/icb/fn_sound.cpp
+++ b/engines/icb/fn_sound.cpp
@@ -169,7 +169,7 @@ mcodeFunctionReturnCodes _game_session::fn_stop_sfx(int32 &, int32 *params) {
 		strncpy(tempObj, const_cast<char *>(snd), sub - snd);
 		tempObj[sub - snd] = 0; // null terminate
 
-		strcpy(tempSnd, sub + strlen("::"));
+		Common::strcpy_s(tempSnd, sub + 2/*strlen("::")*/);
 
 		int32 obj = LinkedDataObject::Fetch_item_number_by_name(MS->objects, tempObj);
 
diff --git a/engines/icb/function.cpp b/engines/icb/function.cpp
index 70c8b7f3e26..ca50c136e60 100644
--- a/engines/icb/function.cpp
+++ b/engines/icb/function.cpp
@@ -3472,8 +3472,8 @@ mcodeFunctionReturnCodes _game_session::fn_hard_load_mesh(int32 &, int32 *params
 	const char *base_name = (const char *)MemoryUtil::resolvePtr(params[0]);
 
 	char mesh[32];
-	strcpy(mesh, base_name);
-	strcat(mesh, ".rap");
+	Common::strcpy_s(mesh, base_name);
+	Common::strcat_s(mesh, ".rap");
 
 	uint32 fileHash = NULL_HASH;
 	rs_anims->Res_open(mesh, fileHash, L->voxel_info->base_path, L->voxel_info->base_path_hash);
@@ -3485,8 +3485,8 @@ mcodeFunctionReturnCodes _game_session::fn_preload_mesh(int32 &, int32 *params)
 	const char *base_name = (const char *)MemoryUtil::resolvePtr(params[0]);
 
 	char filename[32];
-	strcpy(filename, base_name);
-	strcat(filename, ".rap");
+	Common::strcpy_s(filename, base_name);
+	Common::strcat_s(filename, ".rap");
 
 	if (L->voxel_info->Preload_file(filename) == 0)
 		return IR_REPEAT;
@@ -3498,8 +3498,8 @@ mcodeFunctionReturnCodes _game_session::fn_preload_texture(int32 &, int32 *param
 	const char *base_name = (const char *)MemoryUtil::resolvePtr(params[0]);
 
 	char filename[32];
-	strcpy(filename, base_name);
-	strcat(filename, ".revtex");
+	Common::strcpy_s(filename, base_name);
+	Common::strcat_s(filename, ".revtex");
 
 	if (L->voxel_info->Preload_file(filename) == 0)
 		return IR_REPEAT;
@@ -3511,8 +3511,8 @@ mcodeFunctionReturnCodes _game_session::fn_preload_palette(int32 &, int32 *param
 	const char *base_name = (const char *)MemoryUtil::resolvePtr(params[0]);
 
 	char filename[32];
-	strcpy(filename, base_name);
-	strcat(filename, ".revtex");
+	Common::strcpy_s(filename, base_name);
+	Common::strcat_s(filename, ".revtex");
 
 	if (L->voxel_info->Preload_file(filename) == 0)
 		return IR_REPEAT;
@@ -3528,23 +3528,23 @@ mcodeFunctionReturnCodes _game_session::fn_preload_animation(int32 &param1, int3
 	char file[128];
 
 	// The set name
-	strcpy(stub, set_name);
+	Common::strcpy_s(stub, set_name);
 
 	// The actual animation name
-	strcat(stub, "\\");
-	strcat(stub, anim_name);
+	Common::strcat_s(stub, "\\");
+	Common::strcat_s(stub, anim_name);
 
 	// Preload the marker file into memory
-	strcpy(file, stub);
-	strcat(file, ".raj");
+	Common::strcpy_s(file, stub);
+	Common::strcat_s(file, ".raj");
 
 	if (L->voxel_info->Preload_file(file) == 0) {
 		return IR_REPEAT;
 	}
 
 	// Preload the animation file into memory
-	strcpy(file, stub);
-	strcat(file, ".rab");
+	Common::strcpy_s(file, stub);
+	Common::strcat_s(file, ".rab");
 
 	 if (L->voxel_info->Preload_file(file) == 0) {
 		return IR_REPEAT;
diff --git a/engines/icb/icon_list.cpp b/engines/icb/icon_list.cpp
index 4c4a08d0b43..ba11343a5b0 100644
--- a/engines/icb/icon_list.cpp
+++ b/engines/icb/icon_list.cpp
@@ -183,7 +183,7 @@ void _icon_list::RemoveIcon(const char *pcIconName, bool8 bForceRemove) {
 			// swings and roundabouts: other code ends up less efficient if I don't remove holes, and it's not like
 			// we're dealing with thousands of array elements.
 			for (j = i + 1; j < m_nItemCount; ++j) {
-				strcpy(m_ppcIconList[j - 1], m_ppcIconList[j]);
+				Common::strcpy_s(m_ppcIconList[j - 1], m_ppcIconList[j]);
 				m_pnIconListHash[j - 1] = m_pnIconListHash[j];
 				m_pnDuplicateCount[j - 1] = m_pnDuplicateCount[j];
 			}
diff --git a/engines/icb/icon_menu.cpp b/engines/icb/icon_menu.cpp
index f022b0fbff1..35d48f509e5 100644
--- a/engines/icb/icon_menu.cpp
+++ b/engines/icb/icon_menu.cpp
@@ -50,8 +50,8 @@ _icon_menu::_icon_menu() {
 	m_nAddedSymbol = 0;
 	m_nAddedFlashCount = 0;
 
-	strcpy(m_pcGlobalClusterFile, GLOBAL_CLUSTER_PATH);
-	strcpy(m_pcIconCluster, ICON_CLUSTER_PATH);
+	Common::strcpy_s(m_pcGlobalClusterFile, GLOBAL_CLUSTER_PATH);
+	Common::strcpy_s(m_pcIconCluster, ICON_CLUSTER_PATH);
 
 	m_nGlobalClusterHash = NULL_HASH;
 	m_nIconClusterHash = NULL_HASH;
diff --git a/engines/icb/icon_menu_pc.cpp b/engines/icb/icon_menu_pc.cpp
index d4ed9d709c2..8e639d95de8 100644
--- a/engines/icb/icon_menu_pc.cpp
+++ b/engines/icb/icon_menu_pc.cpp
@@ -365,7 +365,7 @@ void _icon_menu::DrawIconMenu() {
 		}
 
 		// Get the icon name and hash for it.
-		strcpy(pcIconName, m_pIconList->GetIcon(nIconIndex));
+		Common::strcpy_s(pcIconName, m_pIconList->GetIcon(nIconIndex));
 		uint32 nHashRef = HashString(pcIconName);
 
 		// Now blit the icon itself.
diff --git a/engines/icb/line_of_sight.cpp b/engines/icb/line_of_sight.cpp
index 5a3e370ca8f..d3932ff02b0 100644
--- a/engines/icb/line_of_sight.cpp
+++ b/engines/icb/line_of_sight.cpp
@@ -61,7 +61,7 @@ void _line_of_sight::Initialise() {
 	char oFileName[ENGINE_STRING_LEN];
 
 	// When clustered the session files have the base stripped
-	strcpy(oFileName, PX_FILENAME_LINEOFSIGHT);
+	Common::strcpy_s(oFileName, PX_FILENAME_LINEOFSIGHT);
 #endif
 
 	uint32 cluster_hash = MS->Fetch_session_cluster_hash();
diff --git a/engines/icb/mission.cpp b/engines/icb/mission.cpp
index d74affe56b7..0b257955dc1 100644
--- a/engines/icb/mission.cpp
+++ b/engines/icb/mission.cpp
@@ -205,7 +205,7 @@ void _mission::___init_mission(const char *new_mission_name, const char *session
 
 	// When using clusters keep items withouth the root so the correct hashing
 	// start point can be maintained
-	strcpy(mission_name, new_mission_name);
+	Common::strcpy_s(mission_name, new_mission_name);
 
 	Set_string(new_mission_name, tiny_mission_name, TINY_NAME_LEN);
 	Set_string(session_name, tiny_session_name, TINY_NAME_LEN);
diff --git a/engines/icb/options_manager_pc.cpp b/engines/icb/options_manager_pc.cpp
index 9f2b8b77e2d..bc8ba341542 100644
--- a/engines/icb/options_manager_pc.cpp
+++ b/engines/icb/options_manager_pc.cpp
@@ -167,67 +167,67 @@ void InitialiseMovieLibrary() {
 	}
 
 	// Setup filename mappings (only done here)
-	strcpy(g_movieLibrary[0].filename, "m01int2");
-	strcpy(g_movieLibrary[1].filename, "m01intro");
-	strcpy(g_movieLibrary[2].filename, "m01accel");
-	strcpy(g_movieLibrary[3].filename, "m01cable");
-	strcpy(g_movieLibrary[4].filename, "m01chasm");
-	strcpy(g_movieLibrary[5].filename, "m01cut");
-	strcpy(g_movieLibrary[6].filename, "m01robot");
-	strcpy(g_movieLibrary[7].filename, "m01robt2");
-	strcpy(g_movieLibrary[8].filename, "m01robt3");
-	strcpy(g_movieLibrary[9].filename, "m01outro");
-
-	strcpy(g_movieLibrary[10].filename, "m02tortu");
-	strcpy(g_movieLibrary[11].filename, "m02intro");
-	strcpy(g_movieLibrary[12].filename, "m02outro");
-
-	strcpy(g_movieLibrary[13].filename, "m03tortu");
-	strcpy(g_movieLibrary[14].filename, "m03intro");
-	strcpy(g_movieLibrary[15].filename, "m03bomb");
-	strcpy(g_movieLibrary[16].filename, "m03cord");
-	strcpy(g_movieLibrary[17].filename, "m03shoot");
-	strcpy(g_movieLibrary[18].filename, "m03c1sep");
-	strcpy(g_movieLibrary[19].filename, "m03outro");
-
-	strcpy(g_movieLibrary[20].filename, "m04tortu");
-	strcpy(g_movieLibrary[21].filename, "m04intro");
-	strcpy(g_movieLibrary[22].filename, "m04lift1");
-	strcpy(g_movieLibrary[23].filename, "m04lift2");
-	strcpy(g_movieLibrary[24].filename, "m04spec");
-	strcpy(g_movieLibrary[25].filename, "m04zapp");
-	strcpy(g_movieLibrary[26].filename, "m04tube");
-	strcpy(g_movieLibrary[27].filename, "m04nag");
-	strcpy(g_movieLibrary[28].filename, "m04outro");
-
-	strcpy(g_movieLibrary[29].filename, "m05tortu");
-	strcpy(g_movieLibrary[30].filename, "m05intro");
-	strcpy(g_movieLibrary[31].filename, "m05outro");
-
-	strcpy(g_movieLibrary[32].filename, "m07tortu");
-	strcpy(g_movieLibrary[33].filename, "m07intro");
-	strcpy(g_movieLibrary[34].filename, "m07sam");
-	strcpy(g_movieLibrary[35].filename, "m07doors");
-	strcpy(g_movieLibrary[36].filename, "m07outro");
-
-	strcpy(g_movieLibrary[37].filename, "m08intro");
-	strcpy(g_movieLibrary[38].filename, "m08betr");
-	strcpy(g_movieLibrary[39].filename, "m08tortu");
-	strcpy(g_movieLibrary[40].filename, "m08outro");
-
-	strcpy(g_movieLibrary[41].filename, "m10intro");
-	strcpy(g_movieLibrary[42].filename, "m10luk");
-	strcpy(g_movieLibrary[43].filename, "m10exp");
-	strcpy(g_movieLibrary[44].filename, "m10miss");
-	strcpy(g_movieLibrary[45].filename, "m10coptr");
-	strcpy(g_movieLibrary[46].filename, "m10outro");
+	Common::strcpy_s(g_movieLibrary[0].filename, "m01int2");
+	Common::strcpy_s(g_movieLibrary[1].filename, "m01intro");
+	Common::strcpy_s(g_movieLibrary[2].filename, "m01accel");
+	Common::strcpy_s(g_movieLibrary[3].filename, "m01cable");
+	Common::strcpy_s(g_movieLibrary[4].filename, "m01chasm");
+	Common::strcpy_s(g_movieLibrary[5].filename, "m01cut");
+	Common::strcpy_s(g_movieLibrary[6].filename, "m01robot");
+	Common::strcpy_s(g_movieLibrary[7].filename, "m01robt2");
+	Common::strcpy_s(g_movieLibrary[8].filename, "m01robt3");
+	Common::strcpy_s(g_movieLibrary[9].filename, "m01outro");
+
+	Common::strcpy_s(g_movieLibrary[10].filename, "m02tortu");
+	Common::strcpy_s(g_movieLibrary[11].filename, "m02intro");
+	Common::strcpy_s(g_movieLibrary[12].filename, "m02outro");
+
+	Common::strcpy_s(g_movieLibrary[13].filename, "m03tortu");
+	Common::strcpy_s(g_movieLibrary[14].filename, "m03intro");
+	Common::strcpy_s(g_movieLibrary[15].filename, "m03bomb");
+	Common::strcpy_s(g_movieLibrary[16].filename, "m03cord");
+	Common::strcpy_s(g_movieLibrary[17].filename, "m03shoot");
+	Common::strcpy_s(g_movieLibrary[18].filename, "m03c1sep");
+	Common::strcpy_s(g_movieLibrary[19].filename, "m03outro");
+
+	Common::strcpy_s(g_movieLibrary[20].filename, "m04tortu");
+	Common::strcpy_s(g_movieLibrary[21].filename, "m04intro");
+	Common::strcpy_s(g_movieLibrary[22].filename, "m04lift1");
+	Common::strcpy_s(g_movieLibrary[23].filename, "m04lift2");
+	Common::strcpy_s(g_movieLibrary[24].filename, "m04spec");
+	Common::strcpy_s(g_movieLibrary[25].filename, "m04zapp");
+	Common::strcpy_s(g_movieLibrary[26].filename, "m04tube");
+	Common::strcpy_s(g_movieLibrary[27].filename, "m04nag");
+	Common::strcpy_s(g_movieLibrary[28].filename, "m04outro");
+
+	Common::strcpy_s(g_movieLibrary[29].filename, "m05tortu");
+	Common::strcpy_s(g_movieLibrary[30].filename, "m05intro");
+	Common::strcpy_s(g_movieLibrary[31].filename, "m05outro");
+
+	Common::strcpy_s(g_movieLibrary[32].filename, "m07tortu");
+	Common::strcpy_s(g_movieLibrary[33].filename, "m07intro");
+	Common::strcpy_s(g_movieLibrary[34].filename, "m07sam");
+	Common::strcpy_s(g_movieLibrary[35].filename, "m07doors");
+	Common::strcpy_s(g_movieLibrary[36].filename, "m07outro");
+
+	Common::strcpy_s(g_movieLibrary[37].filename, "m08intro");
+	Common::strcpy_s(g_movieLibrary[38].filename, "m08betr");
+	Common::strcpy_s(g_movieLibrary[39].filename, "m08tortu");
+	Common::strcpy_s(g_movieLibrary[40].filename, "m08outro");
+
+	Common::strcpy_s(g_movieLibrary[41].filename, "m10intro");
+	Common::strcpy_s(g_movieLibrary[42].filename, "m10luk");
+	Common::strcpy_s(g_movieLibrary[43].filename, "m10exp");
+	Common::strcpy_s(g_movieLibrary[44].filename, "m10miss");
+	Common::strcpy_s(g_movieLibrary[45].filename, "m10coptr");
+	Common::strcpy_s(g_movieLibrary[46].filename, "m10outro");
 }
 
 void Movie_ID_to_name(uint32 id, char *buff) {
 	if (id >= TOTAL_NUMBER_OF_MOVIES)
 		Fatal_error("Movies information out-of-date!");
 
-	strcpy(buff, g_movieLibrary[id].filename);
+	Common::strcpy_s(buff, 32, g_movieLibrary[id].filename);
 }
 
 int32 Movie_name_to_ID(char *name) {
@@ -3132,7 +3132,7 @@ void OptionsManager::DoChoice() {
 			// If the slot contains data, copy the label into our editing buffer else use default name
 			if (m_slots[m_slotOffset + m_GAMESLOT_selected] != nullptr) {
 				// Wish to edit an existing slot label
-				strcpy(m_editBuffer, m_slots[m_slotOffset + m_GAMESLOT_selected]->label);
+				Common::strcpy_s(m_editBuffer, m_slots[m_slotOffset + m_GAMESLOT_selected]->label);
 				// Record this ex-time played so we restore if if the action is cancelled
 				m_emptySlotFlag = m_slots[m_slotOffset + m_GAMESLOT_selected]->secondsPlayed;
 				// Overwrite with current timeplayed
@@ -3143,7 +3143,7 @@ void OptionsManager::DoChoice() {
 				m_slots[m_slotOffset + m_GAMESLOT_selected] = new _SLOT;
 				m_slots[m_slotOffset + m_GAMESLOT_selected]->secondsPlayed = m_timePlayed;
 				memset(m_slots[m_slotOffset + m_GAMESLOT_selected]->label, 0, MAX_LABEL_LENGTH);
-				strcpy(m_editBuffer, m_defaultSlotName);
+				Common::strcpy_s(m_editBuffer, m_defaultSlotName);
 				m_defaultWiper = TRUE8;
 				// By setting this to zero it can be used to identify this newly created slot on cencel (ie need a delete)
 				m_emptySlotFlag = 0;
@@ -3196,7 +3196,7 @@ void OptionsManager::DoChoice() {
 			m_editBuffer[m_cursorPos] = '\0';
 
 			// Then set the label to equal the buffer
-			strcpy(m_slots[m_slotOffset + m_GAMESLOT_selected]->label, m_editBuffer);
+			Common::strcpy_s(m_slots[m_slotOffset + m_GAMESLOT_selected]->label, m_editBuffer);
 
 			// Now actually save the game
 			MakeFullSaveFilename(m_slotOffset + m_GAMESLOT_selected, buff);
@@ -3418,7 +3418,7 @@ void OptionsManager::EditSlotLabel() {
 			m_editBuffer[m_cursorPos] = '\0';
 
 			// Then set the label to equal the buffer
-			strcpy(m_slots[id]->label, m_editBuffer);
+			Common::strcpy_s(m_slots[id]->label, m_editBuffer);
 
 			// Now actually save the game
 			g_mission->Save_game_position(buff, m_slots[id]->label, m_slots[id]->secondsPlayed);
diff --git a/engines/icb/remora.cpp b/engines/icb/remora.cpp
index 7134a4cdc79..f47d1861538 100644
--- a/engines/icb/remora.cpp
+++ b/engines/icb/remora.cpp
@@ -61,7 +61,7 @@ _remora::_remora() {
 	m_nCurrentZoom = REMORA_SCAN_START_ZOOM;
 
 	// Name of the cluster which holds remora graphics.
-	strcpy(m_pcRemoraCluster, REMORA_CLUSTER_PATH);
+	Common::strcpy_s(m_pcRemoraCluster, REMORA_CLUSTER_PATH);
 	m_nScanPan = 0;
 
 	// Make the hash name of the remora graphics cluster.
diff --git a/engines/icb/remora.h b/engines/icb/remora.h
index 4f526755608..d53aaa15fcc 100644
--- a/engines/icb/remora.h
+++ b/engines/icb/remora.h
@@ -501,7 +501,7 @@ inline void _remora::SetMinimumZoom(uint32 nZoom) {
 	m_nMinZoom = nZoom;
 }
 
-inline void _remora::NewEmail(const char *pcEmailID) { strcpy(m_pcEmailID, pcEmailID); }
+inline void _remora::NewEmail(const char *pcEmailID) { Common::strcpy_s(m_pcEmailID, pcEmailID); }
 
 inline void _remora::ResetFloorRanges() {
 	m_nNumFloorRangesSet = 0;
diff --git a/engines/icb/remora_pc.h b/engines/icb/remora_pc.h
index 09cbe42b34a..12d37104d3d 100644
--- a/engines/icb/remora_pc.h
+++ b/engines/icb/remora_pc.h
@@ -147,9 +147,9 @@ inline const char *_remora::MakeRemoraGraphicsPath(const char *pcBitmapName) con
 	static char pcRemoraGraphicsPath[MAXLEN_URL];
 
 	sprintf(pcRemoraGraphicsPath, REMORA_GRAPHICS_PATH);
-	strcat(pcRemoraGraphicsPath, pcBitmapName);
-	strcat(pcRemoraGraphicsPath, ".");
-	strcat(pcRemoraGraphicsPath, PX_BITMAP_EXT);
+	Common::strcat_s(pcRemoraGraphicsPath, pcBitmapName);
+	Common::strcat_s(pcRemoraGraphicsPath, ".");
+	Common::strcat_s(pcRemoraGraphicsPath, PX_BITMAP_EXT);
 
 	return (pcRemoraGraphicsPath);
 }
diff --git a/engines/icb/remora_sprite.cpp b/engines/icb/remora_sprite.cpp
index e60ae73c74c..026a5244280 100644
--- a/engines/icb/remora_sprite.cpp
+++ b/engines/icb/remora_sprite.cpp
@@ -41,9 +41,9 @@ void _remora_sprite::InitialiseFromBitmapName(const char *pcBitmapName, const ch
 	_pxSprite *psSprite;
 
 	// Set name.
-	strcpy(m_pcName, pcBitmapName);
+	Common::strcpy_s(m_pcName, pcBitmapName);
 	m_nNameHash = NULL_HASH;
-	strcpy(m_pcClusterName, pcClusterName);
+	Common::strcpy_s(m_pcClusterName, pcClusterName);
 	m_nClusterHash = nClusterHash;
 
 	// Get the number of frames (don't forget to check schema number is correct).
@@ -85,9 +85,9 @@ _remora_sprite::_remora_sprite(const _remora_sprite &oX) {
 	m_nFramePC = oX.m_nFramePC;
 	m_nNumFrames = oX.m_nNumFrames;
 
-	strcpy(m_pcName, oX.m_pcName);
+	Common::strcpy_s(m_pcName, oX.m_pcName);
 	m_nNameHash = oX.m_nNameHash;
-	strcpy(m_pcClusterName, oX.m_pcClusterName);
+	Common::strcpy_s(m_pcClusterName, oX.m_pcClusterName);
 	m_nClusterHash = oX.m_nClusterHash;
 }
 
@@ -95,9 +95,9 @@ const _remora_sprite &_remora_sprite::operator=(const _remora_sprite &oOpB) {
 	m_nFramePC = oOpB.m_nFramePC;
 	m_nNumFrames = oOpB.m_nNumFrames;
 
-	strcpy(m_pcName, oOpB.m_pcName);
+	Common::strcpy_s(m_pcName, oOpB.m_pcName);
 	m_nNameHash = oOpB.m_nNameHash;
-	strcpy(m_pcClusterName, oOpB.m_pcClusterName);
+	Common::strcpy_s(m_pcClusterName, oOpB.m_pcClusterName);
 	m_nClusterHash = oOpB.m_nClusterHash;
 
 	return (*this);
diff --git a/engines/icb/session.cpp b/engines/icb/session.cpp
index 839add1b079..c9ab4688b13 100644
--- a/engines/icb/session.cpp
+++ b/engines/icb/session.cpp
@@ -154,7 +154,7 @@ void _game_session::___init(const char *mission, const char *new_session_name) {
 	// we can assume all of these in here will be of the game object class!
 
 	// When clustered the session files have the base stripped
-	strcpy(temp_buf, "objects");
+	Common::strcpy_s(temp_buf, "objects");
 
 	// so PSX can have nice session loading screen and details (for timing and to stop player getting bored)
 	LoadMsg("Session Objects");
@@ -181,7 +181,7 @@ void _game_session::___init(const char *mission, const char *new_session_name) {
 	// inititialise the session scripts
 
 	// When clustered the session files have the base stripped
-	strcpy(temp_buf, "scripts");
+	Common::strcpy_s(temp_buf, "scripts");
 
 	// so PSX can have nice session loading screen and details (for timing and to stop player getting bored)
 	LoadMsg("Session Scripts");
@@ -195,7 +195,7 @@ void _game_session::___init(const char *mission, const char *new_session_name) {
 	// initialise prop animation file
 
 	// When clustered the session files have the base stripped
-	strcpy(temp_buf, PX_FILENAME_PROPANIMS);
+	Common::strcpy_s(temp_buf, PX_FILENAME_PROPANIMS);
 
 	// so PSX can have nice session loading screen and details (for timing and to stop player getting bored)
 	LoadMsg("Session PropAnims");
@@ -210,7 +210,7 @@ void _game_session::___init(const char *mission, const char *new_session_name) {
 	// we stick this in the private cache so it hangs around and later in-game references wont cause a main pool reload
 
 	// When clustered the session files have the base stripped
-	strcpy(temp_buf, "pxwgfeatures");
+	Common::strcpy_s(temp_buf, "pxwgfeatures");
 
 	// so PSX can have nice session loading screen and details (for timing and to stop player getting bored)
 	LoadMsg("Session Features");
@@ -237,7 +237,7 @@ void _game_session::___init(const char *mission, const char *new_session_name) {
 	char textFileName[100];
 
 	// When clustered the session files have the base stripped
-	strcpy(temp_buf, "text");
+	Common::strcpy_s(temp_buf, "text");
 
 	buf_hash = HashString(temp_buf);
 	if (private_session_resman->Test_file(temp_buf, buf_hash, session_cluster, session_cluster_hash)) {
@@ -262,7 +262,7 @@ void _game_session::___init(const char *mission, const char *new_session_name) {
 
 	char global_cluster[ENGINE_STRING_LEN];
 
-	strcpy(global_cluster, GLOBAL_CLUSTER_PATH);
+	Common::strcpy_s(global_cluster, GLOBAL_CLUSTER_PATH);
 
 	uint32 global_cluster_hash = HashString(global_cluster);
 
@@ -311,7 +311,7 @@ void _game_session::___init(const char *mission, const char *new_session_name) {
 	total_was = 0;
 
 	// When clustered the session files have the base stripped
-	strcpy(temp_buf, "walkarea");
+	Common::strcpy_s(temp_buf, "walkarea");
 
 	buf_hash = HashString(temp_buf);
 
@@ -542,8 +542,8 @@ void _game_session::Init_objects() {
 		if (pc) {
 			RunScript(pc, object);
 
-			strcpy(buf, CGameObject::GetName(object));
-			strcat(buf, "::local_init");
+			Common::strcpy_s(buf, CGameObject::GetName(object));
+			Common::strcat_s(buf, "::local_init");
 
 			uint32 script_hash;
 
diff --git a/engines/icb/set_pc.cpp b/engines/icb/set_pc.cpp
index 130b61370c9..c973ff732e4 100644
--- a/engines/icb/set_pc.cpp
+++ b/engines/icb/set_pc.cpp
@@ -609,7 +609,7 @@ bool8 _set::Init(const char *camera_name, const char *clustered_camera_name) {
 	uint32 p_rcvf_hash = HashString(p_rcvf);
 
 	// Keep the non clustered name of the camera ( not really needed but nicer for error messages)
-	strcpy(set_name, camera_name);
+	Common::strcpy_s(set_name, camera_name);
 
 	// Load this camera
 	m_currentCamera = (_pcSetHeader *)rs_bg->Res_open(p_rcvf, p_rcvf_hash, set_cluster, set_cluster_hash);
@@ -628,7 +628,7 @@ bool8 _set::Init(const char *camera_name, const char *clustered_camera_name) {
 void _set::Reset() {
 	// Free all the prop surface that have been created.
 	if (m_setOk) {
-		strcpy(set_name, "None");
+		Common::strcpy_s(set_name, "None");
 
 		// Remove all the old surface
 		for (int32 s = 0; s < m_TotalPropSurfaces; s++) {
diff --git a/engines/icb/sound/fx_manager.cpp b/engines/icb/sound/fx_manager.cpp
index cfb835137d3..b4ab8ebd1e1 100644
--- a/engines/icb/sound/fx_manager.cpp
+++ b/engines/icb/sound/fx_manager.cpp
@@ -133,7 +133,7 @@ int32 FxManager::Register(const int32 id, const char *name, const int32 delay, u
 	}
 
 	// Record the samples name so we know it is currently loaded in memory
-	strcpy(m_effects[id].name, name);
+	Common::strcpy_s(m_effects[id].name, name);
 
 	// Setup the delay if there is one
 	m_effects[id].delay = delay;
diff --git a/engines/icb/string_vest.cpp b/engines/icb/string_vest.cpp
index e2f65843855..0b9d72143d9 100644
--- a/engines/icb/string_vest.cpp
+++ b/engines/icb/string_vest.cpp
@@ -38,7 +38,7 @@ void Set_string_and_len(const char *from, char *to, uint32 *length) {
 	if (strlen(from) >= ENGINE_STRING_LEN)
 		Fatal_error("Set_string_and_len length violation [%s]", from);
 
-	strcpy(to, from);
+	Common::strcpy_s(to, ENGINE_STRING_LEN, from);
 
 	*length = strlen(to);
 }
@@ -49,7 +49,7 @@ void Set_string(const char *from, char *to) {
 	if (strlen(from) >= ENGINE_STRING_LEN)
 		Fatal_error("Set_string length violation [%s]", from);
 
-	strcpy(to, from);
+	Common::strcpy_s(to, ENGINE_STRING_LEN, from);
 }
 
 void Set_string(const char *from, char *to, uint32 length) {
@@ -58,7 +58,7 @@ void Set_string(const char *from, char *to, uint32 length) {
 	if (strlen(from) >= length)
 		Fatal_error("Set_string length violation [%s] - max length = %d", from, length);
 
-	strcpy(to, from);
+	Common::strcpy_s(to, length, from);
 }
 
 } // End of namespace ICB


Commit: abb4c3cd6cd02c6afb1056c45682b22e6f315edf
    https://github.com/scummvm/scummvm/commit/abb4c3cd6cd02c6afb1056c45682b22e6f315edf
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
LASTEXPRESS: Don't use unsafe strcat and strcpy

Changed paths:
    engines/lastexpress/debug.cpp
    engines/lastexpress/entities/august.cpp
    engines/lastexpress/entities/coudert.cpp
    engines/lastexpress/entities/entity.cpp
    engines/lastexpress/entities/francois.cpp
    engines/lastexpress/entities/gendarmes.cpp
    engines/lastexpress/entities/tatiana.cpp
    engines/lastexpress/entities/train.cpp
    engines/lastexpress/entities/vesna.cpp
    engines/lastexpress/game/entities.cpp
    engines/lastexpress/sound/entry.cpp
    engines/lastexpress/sound/sound.cpp


diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp
index 9724ff1cebf..9e94d03ff37 100644
--- a/engines/lastexpress/debug.cpp
+++ b/engines/lastexpress/debug.cpp
@@ -134,12 +134,13 @@ void Debugger::copyCommand(int argc, const char **argv) {
 	_numParams = argc;
 
 	for (int i = 0; i < _numParams; i++) {
-		_commandParams[i] = (char *)malloc(strlen(argv[i]) + 1);
+		size_t ln = strlen(argv[i]) + 1;
+		_commandParams[i] = (char *)malloc(ln);
 		if (_commandParams[i] == nullptr)
 			error("[Debugger::copyCommand] Cannot allocate memory for command parameters");
 
 		memset(_commandParams[i], 0, strlen(argv[i]) + 1);
-		strcpy(_commandParams[i], argv[i]);
+		Common::strcpy_s(_commandParams[i], ln, argv[i]);
 	}
 
 	// Exit the debugger!
diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp
index 59a1275e845..792ecffdc4d 100644
--- a/engines/lastexpress/entities/august.cpp
+++ b/engines/lastexpress/entities/august.cpp
@@ -172,14 +172,14 @@ IMPLEMENT_FUNCTION_IIS(10, August, callSavepointNoDrawing, EntityIndex, ActionIn
 
 	case kActionExitCompartment:
 		if (!params->param6)
-			getSavePoints()->call(kEntityAugust, (EntityIndex)params->param1, (ActionIndex)params->param2, (char *)&params->seq);
+			getSavePoints()->call(kEntityAugust, (EntityIndex)params->param1, (ActionIndex)params->param2, params->seq);
 
 		callbackAction();
 		break;
 
 	case kAction10:
 		if (!params->param6) {
-			getSavePoints()->call(kEntityAugust, (EntityIndex)params->param1, (ActionIndex)params->param2, (char *)&params->seq);
+			getSavePoints()->call(kEntityAugust, (EntityIndex)params->param1, (ActionIndex)params->param2, params->seq);
 			params->param6 = 1;
 		}
 		break;
@@ -348,29 +348,29 @@ IMPLEMENT_FUNCTION_II(19, August, function19, bool, bool)
 			break;
 
 		case kChapter1:
-			strcpy((char *)&parameters->seq1, "626");
+			Common::strcpy_s(parameters->seq1, "626");
 			break;
 
 		case kChapter2:
 		case kChapter3:
 			if (getData()->clothes != kClothes2) {
-				strcpy((char *)&parameters->seq1, "666");
+				Common::strcpy_s(parameters->seq1, "666");
 				break;
 			}
 			// fall through
 
 		case kChapter4:
 		case kChapter5:
-			strcpy((char *)&parameters->seq1, "696");
+			Common::strcpy_s(parameters->seq1, "696");
 			break;
 		}
 
 		getSavePoints()->push(kEntityAugust, kEntityMertens, kAction303343617);
 
-		strcpy((char *)&parameters->seq2, (char *)&parameters->seq1);
-		strcat((char *)&parameters->seq2, "Pc");
+		Common::strcpy_s(parameters->seq2, parameters->seq1);
+		Common::strcat_s(parameters->seq2, "Pc");
 
-		getEntities()->drawSequenceLeft(kEntityAugust, (char *)&parameters->seq2);
+		getEntities()->drawSequenceLeft(kEntityAugust, parameters->seq2);
 		getEntities()->enterCompartment(kEntityAugust, kObjectCompartment3, true);
 
 		setCallback(1);
@@ -383,20 +383,20 @@ IMPLEMENT_FUNCTION_II(19, August, function19, bool, bool)
 			break;
 
 		case 1:
-			strcpy((char *)&parameters->seq2, (char *)&parameters->seq1);
-			strcat((char *)&parameters->seq2, "Qc");
+			Common::strcpy_s(parameters->seq2, parameters->seq1);
+			Common::strcat_s(parameters->seq2, "Qc");
 
-			getEntities()->drawSequenceLeft(kEntityAugust, (char *)&parameters->seq2);
+			getEntities()->drawSequenceLeft(kEntityAugust, parameters->seq2);
 			if (parameters->param2)
 				getData()->inventoryItem = kItem147;
 			break;
 
 		case 2:
-			strcpy((char *)&parameters->seq2, (char *)&parameters->seq1);
-			strcat((char *)&parameters->seq2, parameters->param1 ? "Fc" : "Dc");
+			Common::strcpy_s(parameters->seq2, parameters->seq1);
+			Common::strcat_s(parameters->seq2, parameters->param1 ? "Fc" : "Dc");
 
 			setCallback(3);
-			setup_enterExitCompartment2((char *)&parameters->seq2, kObjectCompartment3);
+			setup_enterExitCompartment2(parameters->seq2, kObjectCompartment3);
 			break;
 
 		case 3:
@@ -433,39 +433,39 @@ IMPLEMENT_FUNCTION_I(20, August, function20, bool)
 			break;
 
 		case kChapter1:
-			strcpy((char *)&parameters->seq1, "626");
+			Common::strcpy_s(parameters->seq1, "626");
 			break;
 
 		case kChapter2:
 		case kChapter3:
 			if (getData()->clothes != kClothes2) {
-				strcpy((char *)&parameters->seq1, "666");
+				Common::strcpy_s(parameters->seq1, "666");
 				break;
 			}
 			// fall through
 
 		case kChapter4:
 		case kChapter5:
-			strcpy((char *)&parameters->seq1, "696");
+			Common::strcpy_s(parameters->seq1, "696");
 			break;
 		}
 
 		if (parameters->param1) {
-			Common::String sequence = Common::String::format("%s%s", (char *)&parameters->seq1, "Gc");
+			Common::String sequence = Common::String::format("%s%s", parameters->seq1, "Gc");
 			assert(sequence.size() <= 12); // .size() does not count terminating zero
 
-			strcpy((char *)&parameters->seq2, sequence.c_str());
+			Common::strcpy_s(parameters->seq2, sequence.c_str());
 
 			getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
 		} else {
-			Common::String sequence = Common::String::format("%s%s", (char *)&parameters->seq1, "Ec");
+			Common::String sequence = Common::String::format("%s%s", parameters->seq1, "Ec");
 			assert(sequence.size() <= 12);
 
-			strcpy((char *)&parameters->seq2, sequence.c_str());
+			Common::strcpy_s(parameters->seq2, sequence.c_str());
 		}
 
 		setCallback(1);
-		setup_enterExitCompartment((char *)&parameters->seq2, kObjectCompartment3);
+		setup_enterExitCompartment(parameters->seq2, kObjectCompartment3);
 		break;
 
 	case kActionCallback:
@@ -476,12 +476,12 @@ IMPLEMENT_FUNCTION_I(20, August, function20, bool)
 		case 1: {
 			getData()->location = kLocationOutsideCompartment;
 
-			Common::String sequence2 = Common::String::format("%s%s", (char *)&parameters->seq1, "Pc");
+			Common::String sequence2 = Common::String::format("%s%s", parameters->seq1, "Pc");
 			assert(sequence2.size() <= 12);
 
-			strcpy((char *)&parameters->seq2, sequence2.c_str());
+			Common::strcpy_s(parameters->seq2, sequence2.c_str());
 
-			getEntities()->drawSequenceLeft(kEntityAugust, (char *)&parameters->seq2);
+			getEntities()->drawSequenceLeft(kEntityAugust, parameters->seq2);
 			getEntities()->enterCompartment(kEntityAugust, kObjectCompartment3, true);
 
 			if (getProgress().chapter != kChapter3 || getState()->time >= kTime1998000) {
@@ -499,12 +499,12 @@ IMPLEMENT_FUNCTION_I(20, August, function20, bool)
 		case 3: {
 			getSavePoints()->push(kEntityAugust, kEntityMertens, kAction269436673);
 
-			Common::String sequence = Common::String::format("%s%s", (char *)&parameters->seq1, "Qc");
+			Common::String sequence = Common::String::format("%s%s", parameters->seq1, "Qc");
 			assert(sequence.size() <= 13);
 
-			strcpy((char *)&parameters->seq2, sequence.c_str());
+			Common::strcpy_s(parameters->seq2, sequence.c_str());
 
-			getEntities()->drawSequenceLeft(kEntityAugust, (char *)&parameters->seq2);
+			getEntities()->drawSequenceLeft(kEntityAugust, parameters->seq2);
 
 			}
 			break;
diff --git a/engines/lastexpress/entities/coudert.cpp b/engines/lastexpress/entities/coudert.cpp
index c4e81c13c2b..bc476c7b73f 100644
--- a/engines/lastexpress/entities/coudert.cpp
+++ b/engines/lastexpress/entities/coudert.cpp
@@ -122,7 +122,7 @@ IMPLEMENT_FUNCTION_S(2, Coudert, bloodJacket)
 		break;
 
 	case kActionDefault:
-		getEntities()->drawSequenceRight(kEntityCoudert, (char *)&params->seq1);
+		getEntities()->drawSequenceRight(kEntityCoudert, params->seq1);
 		break;
 
 	case kActionCallback:
@@ -219,7 +219,7 @@ IMPLEMENT_FUNCTION_S(6, Coudert, playSound)
 		break;
 
 	case kActionDefault:
-		getSound()->playSound(kEntityCoudert, (char *)&params->seq1);
+		getSound()->playSound(kEntityCoudert, params->seq1);
 		break;
 
 	case kActionCallback:
@@ -248,7 +248,7 @@ IMPLEMENT_FUNCTION_NOSETUP(7, Coudert, playSound16)
 		break;
 
 	case kActionDefault:
-		getSound()->playSound(kEntityCoudert, (char *)&params->seq1, kVolumeFull);
+		getSound()->playSound(kEntityCoudert, params->seq1, kVolumeFull);
 		break;
 
 	case kActionCallback:
@@ -1522,47 +1522,47 @@ IMPLEMENT_FUNCTION_I(30, Coudert, function30, ObjectIndex)
 		case kObjectCompartmentA:
 			parameters->param2 = kPosition_8200;
 			parameters->param3 = kPosition_7850;
-			strcpy((char *)&parameters->seq, "627Ma");
-			strcpy((char *)&parameters1->seq1, "627Na");
+			Common::strcpy_s(parameters->seq, "627Ma");
+			Common::strcpy_s(parameters1->seq1, "627Na");
 			break;
 
 		case kObjectCompartmentB:
 			parameters->param2 = kPosition_7500;
 			parameters->param3 = kPosition_7850;
 			parameters->param4 = true;
-			strcpy((char *)&parameters->seq, "627Vb");
-			strcpy((char *)&parameters1->seq1, "627Wb");
+			Common::strcpy_s(parameters->seq, "627Vb");
+			Common::strcpy_s(parameters1->seq1, "627Wb");
 			break;
 
 		case kObjectCompartmentC:
 			parameters->param2 = kPosition_6470;
 			parameters->param3 = kPosition_6130;
-			strcpy((char *)&parameters->seq, "627Mc");
-			strcpy((char *)&parameters1->seq1, "627Nc");
+			Common::strcpy_s(parameters->seq, "627Mc");
+			Common::strcpy_s(parameters1->seq1, "627Nc");
 			break;
 
 		case kObjectCompartmentD:
 			parameters->param2 = kPosition_5790;
 			parameters->param3 = kPosition_6130;
 			parameters->param4 = true;
-			strcpy((char *)&parameters->seq, "627Vd");
-			strcpy((char *)&parameters1->seq1, "627Wd");
+			Common::strcpy_s(parameters->seq, "627Vd");
+			Common::strcpy_s(parameters1->seq1, "627Wd");
 			break;
 
 		case kObjectCompartmentE:
 			parameters->param2 = kPosition_4840;
 			parameters->param3 = kPosition_4455;
 			parameters->param4 = true;
-			strcpy((char *)&parameters->seq, "627Me");
-			strcpy((char *)&parameters1->seq1, "627Ne");
+			Common::strcpy_s(parameters->seq, "627Me");
+			Common::strcpy_s(parameters1->seq1, "627Ne");
 			break;
 
 		case kObjectCompartmentF:
 			parameters->param2 = kPosition_4070;
 			parameters->param3 = kPosition_4455;
 			parameters->param4 = true;
-			strcpy((char *)&parameters->seq, "627Vf");
-			strcpy((char *)&parameters1->seq1, "627Wf");
+			Common::strcpy_s(parameters->seq, "627Vf");
+			Common::strcpy_s(parameters1->seq1, "627Wf");
 			break;
 		}
 
@@ -1588,11 +1588,11 @@ IMPLEMENT_FUNCTION_I(30, Coudert, function30, ObjectIndex)
 			}
 
 			setCallback(3);
-			setup_enterExitCompartment((char *)&parameters->seq, (ObjectIndex)parameters->param1);
+			setup_enterExitCompartment(parameters->seq, (ObjectIndex)parameters->param1);
 			break;
 
 		case 3:
-			getEntities()->drawSequenceLeft(kEntityCoudert, (char *)&parameters1->seq1);
+			getEntities()->drawSequenceLeft(kEntityCoudert, parameters1->seq1);
 			getEntities()->enterCompartment(kEntityCoudert, (ObjectIndex)parameters->param1, true);
 
 			setCallback(4);
diff --git a/engines/lastexpress/entities/entity.cpp b/engines/lastexpress/entities/entity.cpp
index fa21d19b2cd..3b56d00d124 100644
--- a/engines/lastexpress/entities/entity.cpp
+++ b/engines/lastexpress/entities/entity.cpp
@@ -54,12 +54,12 @@ void EntityData::EntityCallData::syncString(Common::Serializer &s, Common::Strin
 	assert(string.size() <= 13);
 
 	char seqName[13];
-	memset(&seqName, 0, length);
+	memset(seqName, 0, length);
 
 	if (s.isSaving())
-		strcpy((char *)&seqName, string.c_str());
+		Common::strcpy_s(seqName, string.c_str());
 
-	s.syncBytes((byte *)&seqName, length);
+	s.syncBytes((byte *)seqName, length);
 
 	if (s.isLoading())
 		string = seqName;
diff --git a/engines/lastexpress/entities/francois.cpp b/engines/lastexpress/entities/francois.cpp
index d348f3546c9..9363c897a16 100644
--- a/engines/lastexpress/entities/francois.cpp
+++ b/engines/lastexpress/entities/francois.cpp
@@ -635,8 +635,8 @@ IMPLEMENT_FUNCTION_IIS(14, Francois, chaseBeetle, ObjectIndex, EntityPosition)
 		break;
 
 	case kActionDefault:
-		strcpy((char *)&parameters->seq2, "605H");
-		strcat((char *)&parameters->seq2, (char *)&parameters->seq1);
+		Common::strcpy_s(parameters->seq2, "605H");
+		Common::strcat_s(parameters->seq2, parameters->seq1);
 
 		setCallback(1);
 		setup_exitCompartment();
@@ -654,7 +654,7 @@ IMPLEMENT_FUNCTION_IIS(14, Francois, chaseBeetle, ObjectIndex, EntityPosition)
 
 		case 2:
 			if (getInventory()->get(kItemBeetle)->location == kObjectLocation3) {
-				getEntities()->drawSequenceLeft(kEntityFrancois, (char *)&parameters->seq2);
+				getEntities()->drawSequenceLeft(kEntityFrancois, parameters->seq2);
 				getEntities()->enterCompartment(kEntityFrancois, (ObjectIndex)parameters->param1, true);
 
 				setCallback(3);
diff --git a/engines/lastexpress/entities/gendarmes.cpp b/engines/lastexpress/entities/gendarmes.cpp
index b9445b31886..a0c5be42fc1 100644
--- a/engines/lastexpress/entities/gendarmes.cpp
+++ b/engines/lastexpress/entities/gendarmes.cpp
@@ -159,20 +159,20 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
 			parameters2->param5 += 31; // Switch to next compartment car
 
 		if (parameters2->param6) {
-			strcpy((char *)&parameters1->seq1, "632A");
-			strcpy((char *)&parameters1->seq2, "632B");
-			strcpy((char *)&parameters1->seq3, "632C");
+			Common::strcpy_s(parameters1->seq1, "632A");
+			Common::strcpy_s(parameters1->seq2, "632B");
+			Common::strcpy_s(parameters1->seq3, "632C");
 		} else {
-			strcpy((char *)&parameters1->seq1, "632D");
-			strcpy((char *)&parameters1->seq2, "632E");
-			strcpy((char *)&parameters1->seq3, "632F");
+			Common::strcpy_s(parameters1->seq1, "632D");
+			Common::strcpy_s(parameters1->seq2, "632E");
+			Common::strcpy_s(parameters1->seq3, "632F");
 		}
 
 		// The sequence 3 string needs to be a maximum of 9 characters, leaving 5 characters after the initial setup
 		assert(Common::String(params->seq1).size() <= 5);
 
-		strcat((char *)&parameters1->seq1, (char *)&params->seq1);
-		strcat((char *)&parameters1->seq2, (char *)&params->seq1);
+		Common::strcat_s(parameters1->seq1, params->seq1);
+		Common::strcat_s(parameters1->seq2, params->seq1);
 		Common::strlcat((char *)&parameters1->seq3, (char *)&params->seq1, 9); // Beware, seq3 is smaller than seq1
 
 		if ((getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params->param1, (EntityPosition)params->param2)
@@ -182,7 +182,7 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
 			setCallback(1);
 			setup_trappedCath((CarIndex)params->param1, (EntityPosition)params->param2, (ObjectIndex)parameters2->param5);
 		} else {
-			getEntities()->drawSequenceLeft(kEntityGendarmes, (char *)&parameters1->seq1);
+			getEntities()->drawSequenceLeft(kEntityGendarmes, parameters1->seq1);
 			getEntities()->enterCompartment(kEntityGendarmes, (ObjectIndex)CURRENT_PARAM(2, 5), true);
 
 			setCallback(parameters2->param6 ? 2 : 3);
@@ -201,14 +201,14 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
 
 		case 2:
 		case 3:
-			getEntities()->drawSequenceLeft(kEntityGendarmes, (char *)&parameters1->seq2);
+			getEntities()->drawSequenceLeft(kEntityGendarmes, parameters1->seq2);
 			if (getEntities()->isNobodyInCompartment((CarIndex)params->param1, (EntityPosition)params->param2) || !strcmp(params->seq2, "NODIALOG")) {
 				setCallback(4);
 				setup_doWait(150);
 			} else {
-				char *arrestSound = (char *)&parameters2->seq;
-				strcpy(arrestSound, "POL1045");
-				strcat(arrestSound, (char *)&params->seq2);
+				char *arrestSound = parameters2->seq;
+				Common::strcpy_s(arrestSound, sizeof(parameters2->seq), "POL1045");
+				Common::strcat_s(arrestSound, sizeof(parameters2->seq), params->seq2);
 
 				setCallback(5);
 				setup_doDialog(arrestSound);
@@ -218,9 +218,9 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
 		case 4:
 		case 5:
 			if (!getEntities()->isNobodyInCompartment((CarIndex)params->param1, (EntityPosition)params->param2) && strcmp(params->seq2, "NODIALOG")) {
-				char *arrestSound = (char *)&parameters2->seq;
-				strcpy(arrestSound, "POL1043");
-				strcat(arrestSound, (char *)&params->seq2);
+				char *arrestSound = parameters2->seq;
+				Common::strcpy_s(arrestSound, sizeof(parameters2->seq), "POL1043");
+				Common::strcat_s(arrestSound, sizeof(parameters2->seq), params->seq2);
 
 				getSound()->playSound(kEntityGendarmes, arrestSound, kSoundVolumeEntityDefault, 30);
 			}
@@ -228,7 +228,7 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
 			getData()->location = kLocationInsideCompartment;
 
 			setCallback(6);
-			setup_doDraw((char *)&parameters1->seq3);
+			setup_doDraw(parameters1->seq3);
 			break;
 
 		case 6:
@@ -603,9 +603,9 @@ void Gendarmes::handleAction(const SavePoint &savepoint, bool shouldPlaySound, S
 			EXPOSE_PARAMS(EntityData::EntityParametersSIIS);
 
 			if (!shouldPlaySound)
-				getEntities()->drawSequenceRight(kEntityGendarmes, (char *)&params->seq1);
+				getEntities()->drawSequenceRight(kEntityGendarmes, params->seq1);
 			else
-				getSound()->playSound(kEntityGendarmes, (char *)&params->seq1, flag);
+				getSound()->playSound(kEntityGendarmes, params->seq1, flag);
 		}
 
 		if (shouldUpdateEntity) {
diff --git a/engines/lastexpress/entities/tatiana.cpp b/engines/lastexpress/entities/tatiana.cpp
index d5f96086d17..3255ef71d87 100644
--- a/engines/lastexpress/entities/tatiana.cpp
+++ b/engines/lastexpress/entities/tatiana.cpp
@@ -1011,8 +1011,8 @@ IMPLEMENT_FUNCTION(32, Tatiana, playChess)
 
 			if (getState()->timeDelta > parameters->param1) {
 
-				getEntities()->drawSequenceLeft(kEntityTatiana, (char *)&parameters1->seq);
-				getSound()->playSound(kEntityTatiana, (char *)&parameters->seq);
+				getEntities()->drawSequenceLeft(kEntityTatiana, parameters1->seq);
+				getSound()->playSound(kEntityTatiana, parameters->seq);
 
 				if (parameters->param3 == 4 && getEntities()->isInSalon(kEntityPlayer))
 					getProgress().field_90 = 1;
@@ -1045,41 +1045,41 @@ IMPLEMENT_FUNCTION(32, Tatiana, playChess)
 		case 1:
 			parameters->param1 = 900;
 			getEntities()->drawSequenceLeft(kEntityTatiana, "110A");
-			strcpy((char *)&parameters->seq, "Tat3160B");
-			strcpy((char *)&parameters1->seq, "110A");
+			Common::strcpy_s(parameters->seq, "Tat3160B");
+			Common::strcpy_s(parameters1->seq, "110A");
 			break;
 
 		case 2:
 			parameters->param1 = 9000;
-			strcpy((char *)&parameters->seq, "Tat3160C");
-			strcpy((char *)&parameters1->seq, "110C");
+			Common::strcpy_s(parameters->seq, "Tat3160C");
+			Common::strcpy_s(parameters1->seq, "110C");
 			break;
 
 		case 3:
 			parameters->param1 = 13500;
 			getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
-			strcpy((char *)&parameters->seq, "Tat3160D");
-			strcpy((char *)&parameters1->seq, "110D");
+			Common::strcpy_s(parameters->seq, "Tat3160D");
+			Common::strcpy_s(parameters1->seq, "110D");
 			break;
 
 		case 4:
 			parameters->param1 = 9000;
 			getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
-			strcpy((char *)&parameters->seq, "Tat3160E");
-			strcpy((char *)&parameters1->seq, "110D");
+			Common::strcpy_s(parameters->seq, "Tat3160E");
+			Common::strcpy_s(parameters1->seq, "110D");
 			break;
 
 		case 5:
 			parameters->param1 = 4500;
 			getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
-			strcpy((char *)&parameters->seq, "Tat3160G");
-			strcpy((char *)&parameters1->seq, "110D");
+			Common::strcpy_s(parameters->seq, "Tat3160G");
+			Common::strcpy_s(parameters1->seq, "110D");
 			break;
 
 		case 6:
 			parameters->param1 = 4500;
 			getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
-			strcpy((char *)&parameters->seq, "Tat3160F");
+			Common::strcpy_s(parameters->seq, "Tat3160F");
 			break;
 		}
 		break;
@@ -1767,7 +1767,7 @@ IMPLEMENT_FUNCTION(46, Tatiana, withAlexei)
 			parameters->param1 -= getState()->timeDelta;
 
 			if (parameters->param1 < getState()->timeDelta) {
-				getSound()->playSound(kEntityTatiana, (char *)&parameters->seq);
+				getSound()->playSound(kEntityTatiana, parameters->seq);
 
 				if (getEntities()->isDistanceBetweenEntities(kEntityTatiana, kEntityPlayer, 2000)) {
 					if (parameters->param4 == 4)
@@ -1818,37 +1818,37 @@ IMPLEMENT_FUNCTION(46, Tatiana, withAlexei)
 
 		case 1:
 			parameters->param1 = 900;
-			strcpy((char *)&parameters->seq, "Tat4165F");
+			Common::strcpy_s(parameters->seq, "Tat4165F");
 			break;
 
 		case 2:
 			parameters->param1 = 900;
-			strcpy((char *)&parameters->seq, "Tat4165B");
+			Common::strcpy_s(parameters->seq, "Tat4165B");
 			break;
 
 		case 3:
 			parameters->param1 = 1800;
-			strcpy((char *)&parameters->seq, "Tat4165G");
+			Common::strcpy_s(parameters->seq, "Tat4165G");
 			break;
 
 		case 4:
 			parameters->param1 = 900;
-			strcpy((char *)&parameters->seq, "Tat4165H");
+			Common::strcpy_s(parameters->seq, "Tat4165H");
 			break;
 
 		case 5:
 			parameters->param1 = 2700;
-			strcpy((char *)&parameters->seq, "Tat4165C");
+			Common::strcpy_s(parameters->seq, "Tat4165C");
 			break;
 
 		case 6:
 			parameters->param1 = 900;
-			strcpy((char *)&parameters->seq, "Tat4165D");
+			Common::strcpy_s(parameters->seq, "Tat4165D");
 			break;
 
 		case 7:
 			parameters->param1 = 900;
-			strcpy((char *)&parameters->seq, "Tat4165E");
+			Common::strcpy_s(parameters->seq, "Tat4165E");
 			break;
 		}
 		break;
@@ -1856,7 +1856,7 @@ IMPLEMENT_FUNCTION(46, Tatiana, withAlexei)
 	case kActionDefault:
 		getEntities()->drawSequenceLeft(kEntityTatiana, "306E");
 		parameters->param1 = 450;
-		strcpy((char *)&parameters->seq, "Tat4165A");
+		Common::strcpy_s(parameters->seq, "Tat4165A");
 		break;
 
 	case kActionDrawScene:
diff --git a/engines/lastexpress/entities/train.cpp b/engines/lastexpress/entities/train.cpp
index f457e9e7db9..7905227160c 100644
--- a/engines/lastexpress/entities/train.cpp
+++ b/engines/lastexpress/entities/train.cpp
@@ -482,7 +482,7 @@ label_process:
 	case kAction203863200:
 		if (strcmp(savepoint.param.charValue, "")) {
 			params->param8 = 1;
-			strcpy((char *)&params1->seq, savepoint.param.charValue);	// this is the sound file name
+			Common::strcpy_s(params1->seq, savepoint.param.charValue);	// this is the sound file name
 		}
 		break;
 
diff --git a/engines/lastexpress/entities/vesna.cpp b/engines/lastexpress/entities/vesna.cpp
index 9b568467620..d73b6c38784 100644
--- a/engines/lastexpress/entities/vesna.cpp
+++ b/engines/lastexpress/entities/vesna.cpp
@@ -185,16 +185,16 @@ IMPLEMENT_FUNCTION(11, Vesna, homeAlone)
 		parameters->param1++;
 		switch (parameters->param1) {
 		default:
-			strcpy((char *)&parameters->seq, "VES1015C");
+			Common::strcpy_s(parameters->seq, "VES1015C");
 			parameters->param1 = 0;
 			break;
 
 		case 1:
-			strcpy((char *)&parameters->seq, "VES1015A");
+			Common::strcpy_s(parameters->seq, "VES1015A");
 			break;
 
 		case 2:
-			strcpy((char *)&parameters->seq, "VES1015B");
+			Common::strcpy_s(parameters->seq, "VES1015B");
 			break;
 		}
 
@@ -225,7 +225,7 @@ IMPLEMENT_FUNCTION(11, Vesna, homeAlone)
 		case 1:
 		case 2:
 			setCallback(3);
-			setup_playSound((char *)&parameters->seq);
+			setup_playSound(parameters->seq);
 			break;
 
 		case 3:
@@ -538,16 +538,16 @@ IMPLEMENT_FUNCTION(20, Vesna, inCompartment)
 
 		switch (parameters->param3) {
 		default:
-			strcpy((char *)&parameters->seq, "VES1015C");
+			Common::strcpy_s(parameters->seq, "VES1015C");
 			parameters->param3 = 0;
 			break;
 
 		case 1:
-			strcpy((char *)&parameters->seq, "VES1015A");
+			Common::strcpy_s(parameters->seq, "VES1015A");
 			break;
 
 		case 2:
-			strcpy((char *)&parameters->seq, "VES1015B");
+			Common::strcpy_s(parameters->seq, "VES1015B");
 			break;
 		}
 
@@ -583,7 +583,7 @@ IMPLEMENT_FUNCTION(20, Vesna, inCompartment)
 		case 1:
 		case 2:
 			setCallback(3);
-			setup_playSound((char *)&parameters->seq);
+			setup_playSound(parameters->seq);
 			break;
 
 		case 3:
diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp
index 753cbcd0731..ca35efec2d4 100644
--- a/engines/lastexpress/game/entities.cpp
+++ b/engines/lastexpress/game/entities.cpp
@@ -609,9 +609,9 @@ void Entities::resetSequences(EntityIndex entityIndex) const {
 	getData(entityIndex)->field_4A9 = false;
 	getData(entityIndex)->field_4AA = false;
 
-	strcpy((char *)&getData(entityIndex)->sequenceNameCopy, "");
-	strcpy((char *)&getData(entityIndex)->sequenceName, "");
-	strcpy((char *)&getData(entityIndex)->sequenceName2, "");
+	getData(entityIndex)->sequenceNameCopy.clear();
+	getData(entityIndex)->sequenceName.clear();
+	getData(entityIndex)->sequenceName2.clear();
 
 	getScenes()->resetQueue();
 }
diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
index f348d99d197..78dfec52517 100644
--- a/engines/lastexpress/sound/entry.cpp
+++ b/engines/lastexpress/sound/entry.cpp
@@ -422,7 +422,7 @@ void SoundEntry::saveLoadWithSerializer(Common::Serializer &s) {
 		char name[16] = {0};
 		s.syncBytes((byte *)name, 16);
 
-		strcpy((char *)name, _name.c_str());
+		Common::strcpy_s(name, _name.c_str());
 		s.syncBytes((byte *)name, 16);
 	}
 }
diff --git a/engines/lastexpress/sound/sound.cpp b/engines/lastexpress/sound/sound.cpp
index e2244e97507..cd010cc9725 100644
--- a/engines/lastexpress/sound/sound.cpp
+++ b/engines/lastexpress/sound/sound.cpp
@@ -1314,7 +1314,7 @@ void SoundManager::playAmbientSound(int param) {
 
 	if (_queue->getAmbientState() & kAmbientSoundEnabled && param >= 0x45 && param <= 0x46) {
 		if (_queue->getAmbientState() & kAmbientSoundSteam) {
-			strcpy(tmp, "STEAM.SND");
+			Common::strcpy_s(tmp, "STEAM.SND");
 
 			_ambientSoundDuration = 32767;
 		} else {


Commit: 700a965361e8b1e63501efb85360b1d2c191323e
    https://github.com/scummvm/scummvm/commit/700a965361e8b1e63501efb85360b1d2c191323e
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
LURE: Don't use unsafe strcat and strcpy

Changed paths:
    engines/lure/debugger.cpp
    engines/lure/disk.cpp
    engines/lure/game.cpp
    engines/lure/hotspots.cpp
    engines/lure/menu.cpp
    engines/lure/scripts.cpp
    engines/lure/strings.cpp
    engines/lure/surface.cpp


diff --git a/engines/lure/debugger.cpp b/engines/lure/debugger.cpp
index f9950da4f98..6c28f9901f1 100644
--- a/engines/lure/debugger.cpp
+++ b/engines/lure/debugger.cpp
@@ -122,7 +122,7 @@ bool Debugger::cmd_listRooms(int argc, const char **argv) {
 		// Explictly note the second drawbridge room as "Alt"
 		if (room.roomNumber == 49) {
 			strings.getString(47, buffer);
-			strcat(buffer, " (alt)");
+			Common::strcat_s(buffer, " (alt)");
 		} else {
 			strings.getString(room.roomNumber, buffer);
 		}
@@ -244,7 +244,7 @@ bool Debugger::cmd_hotspots(int argc, const char **argv) {
 			for (i = res.activeHotspots().begin(); i != res.activeHotspots().end(); ++i) {
 				Hotspot const &hotspot = **i;
 
-				if (hotspot.nameId() == 0) strcpy(buffer, "none");
+				if (hotspot.nameId() == 0) Common::strcpy_s(buffer, "none");
 				else strings.getString(hotspot.nameId(), buffer);
 
 				debugPrintf("%4xh - %s pos=(%d,%d,%d)\n", hotspot.hotspotId(), buffer,
@@ -259,7 +259,7 @@ bool Debugger::cmd_hotspots(int argc, const char **argv) {
 				HotspotData const &hotspot = **i;
 
 				if (hotspot.roomNumber == roomNumber) {
-					if (hotspot.nameId == 0) strcpy(buffer, "none");
+					if (hotspot.nameId == 0) Common::strcpy_s(buffer, "none");
 					else strings.getString(hotspot.nameId, buffer);
 
 					debugPrintf("%4xh - %s pos=(%d,%d,%d)\n", hotspot.hotspotId, buffer,
diff --git a/engines/lure/disk.cpp b/engines/lure/disk.cpp
index d5cdd0ab74a..daeecc3ffda 100644
--- a/engines/lure/disk.cpp
+++ b/engines/lure/disk.cpp
@@ -88,7 +88,7 @@ void Disk::openFile(uint8 fileNum) {
 
 	char sFilename[10];
 	if (_fileNum == 0)
-		strcpy(sFilename, SUPPORT_FILENAME);
+		Common::strcpy_s(sFilename, SUPPORT_FILENAME);
 	else
 		sprintf(sFilename, "disk%d.%s", _fileNum, isEGA ? "ega" : "vga");
 
diff --git a/engines/lure/game.cpp b/engines/lure/game.cpp
index c06fedd4427..68162e5147d 100644
--- a/engines/lure/game.cpp
+++ b/engines/lure/game.cpp
@@ -254,7 +254,7 @@ void Game::execute() {
 			destRoom = fields.getField(NEW_ROOM_NUMBER);
 			if (destRoom != 0) {
 				// Need to change the current room
-				strcpy(room.statusLine(), "");
+				room.statusLine()[0] = '\0';
 				bool remoteFlag = fields.getField(OLD_ROOM_NUMBER) != 0;
 				room.setRoomNumber(destRoom, remoteFlag);
 				fields.setField(NEW_ROOM_NUMBER, 0);
@@ -543,7 +543,7 @@ void Game::handleRightClickMenu() {
 	bool breakFlag = false;
 	while (!breakFlag) {
 		statusLine = room.statusLine();
-		strcpy(statusLine, "");
+		statusLine[0] = '\0';
 		room.update();
 		screen.update();
 
@@ -644,7 +644,7 @@ void Game::handleRightClickMenu() {
 		}
 	} else {
 		// Clear the status line
-		strcpy(room.statusLine(), "");
+		room.statusLine()[0] = '\0';
 	}
 }
 
@@ -660,7 +660,7 @@ void Game::handleLeftClick() {
 	player->stopWalking();
 	player->setDestHotspot(0);
 	player->setActionCtr(0);
-	strcpy(room.statusLine(), "");
+	room.statusLine()[0] = '\0';
 
 	if ((room.destRoomNumber() == 0) && (room.hotspotId() != 0)) {
 		// Handle look at hotspot
@@ -689,7 +689,8 @@ bool Game::GetTellActions() {
 	Room &room = Room::getReference();
 	StringData &strings = StringData::getReference();
 	StringList &stringList = res.stringList();
-	char *statusLine = room.statusLine();
+	char *origStatusLine = room.statusLine();
+	char *statusLine = origStatusLine;
 	uint16 *commands = &_tellCommands[1];
 	char *statusLinePos[MAX_TELL_COMMANDS][4];
 	int paramIndex = 0;
@@ -778,7 +779,7 @@ bool Game::GetTellActions() {
 
 					// Store selected entry
 					commands[_numTellCommands * 3 + 1] = selectionId;
-					strcat(statusLine, selectionName);
+					Common::strcat_s(statusLine, MAX_DESC_SIZE - (statusLine - origStatusLine), selectionName);
 				}
 
 				++paramIndex;
@@ -810,7 +811,7 @@ bool Game::GetTellActions() {
 					hotspot = res.getHotspot(selectionId);
 					assert(hotspot);
 					strings.getString(hotspot->nameId, selectionName);
-					strcat(statusLine, selectionName);
+					Common::strcat_s(statusLine, MAX_DESC_SIZE - (statusLine - origStatusLine), selectionName);
 
 					commands[_numTellCommands * 3 + 2] = selectionId;
 					++paramIndex;
@@ -872,7 +873,7 @@ bool Game::GetTellActions() {
 	if (result) {
 		_numTellCommands &= 0xff;
 		assert((_numTellCommands > 0) && (_numTellCommands <= MAX_TELL_COMMANDS));
-		strcpy(statusLinePos[0][0], "..");
+		Common::strcpy_s(statusLinePos[0][0], MAX_DESC_SIZE - (statusLinePos[0][0] - origStatusLine), "..");
 		room.update();
 		screen.update();
 	}
diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
index 4cba4c87cdd..fee62c636f9 100644
--- a/engines/lure/hotspots.cpp
+++ b/engines/lure/hotspots.cpp
@@ -3024,7 +3024,7 @@ void HotspotTickHandlers::playerAnimHandler(Hotspot &h) {
 		h.setDestHotspot(0);
 		h.updateMovement2(CHARMODE_IDLE);
 		h.doNothing(nullptr);
-		strcpy(room.statusLine(), "");
+		room.statusLine()[0] = '\0';
 		break;
 
 	case DISPATCH_ACTION:
diff --git a/engines/lure/menu.cpp b/engines/lure/menu.cpp
index b19194cf7d3..37d0770241e 100644
--- a/engines/lure/menu.cpp
+++ b/engines/lure/menu.cpp
@@ -385,9 +385,9 @@ uint16 PopupMenu::ShowItems(Action contextAction, uint16 roomNumber) {
 	if (numItems == 0) {
 		// No items, so add a 'nothing' to the statusLine
 		if (LureEngine::getReference().getLanguage() == Common::RU_RUS)
-			strcat(room.statusLine(), "(ybxtuj ytn)");
+			Common::strcat_s(room.statusLine(), MAX_DESC_SIZE, "(ybxtuj ytn)");
 		else
-			strcat(room.statusLine(), "(nothing)");
+			Common::strcat_s(room.statusLine(), MAX_DESC_SIZE, "(nothing)");
 	}
 
 	room.update();
diff --git a/engines/lure/scripts.cpp b/engines/lure/scripts.cpp
index c62cc4f5d48..f02d645492f 100644
--- a/engines/lure/scripts.cpp
+++ b/engines/lure/scripts.cpp
@@ -930,7 +930,7 @@ uint16 Script::execute(uint16 startOffset) {
 	fields.setField(SEQUENCE_RESULT, 0);
 
 	debugC(ERROR_BASIC, kLureDebugScripts, "Executing script %xh", startOffset);
-	strcpy(debugInfo, "");
+	debugInfo[0] = '\0';
 
 	while (!breakFlag) {
 		if (offset >= scriptData->size())
@@ -1102,10 +1102,10 @@ uint16 Script::execute(uint16 startOffset) {
 
 			if (gDebugLevel >= ERROR_DETAILED) {
 				// Set up the debug string for the method call
-				if (rec->methodIndex == 0xff) strcat(debugInfo, " INVALID INDEX");
-				else if (scriptMethodNames[param] == nullptr) strcat(debugInfo, " UNKNOWN METHOD");
+				if (rec->methodIndex == 0xff) Common::strcat_s(debugInfo, " INVALID INDEX");
+				else if (scriptMethodNames[param] == nullptr) Common::strcat_s(debugInfo, " UNKNOWN METHOD");
 				else {
-					strcat(debugInfo, " ");
+					Common::strcat_s(debugInfo, " ");
 					Common::strlcat(debugInfo, scriptMethodNames[param], MAX_DESC_SIZE);
 				}
 
@@ -1118,7 +1118,7 @@ uint16 Script::execute(uint16 startOffset) {
 						stack[stack.size()-1], stack[stack.size()-2]);
 				else if (stack.size() == 1)
 					sprintf(debugInfo + strlen(debugInfo), " (%d)", stack[stack.size()-1]);
-				strcat(debugInfo, ")");
+				Common::strcat_s(debugInfo, ")");
 
 				debugC(ERROR_DETAILED, kLureDebugScripts, "%s", debugInfo);
 			}
@@ -1183,7 +1183,7 @@ uint16 Script::execute(uint16 startOffset) {
 				break;
 
 			case S_OPCODE_PUSH:
-				strcat(debugInfo, " => ST");
+				Common::strcat_s(debugInfo, " => ST");
 				break;
 
 			default:
diff --git a/engines/lure/strings.cpp b/engines/lure/strings.cpp
index 499e060f93e..fbca842848b 100644
--- a/engines/lure/strings.cpp
+++ b/engines/lure/strings.cpp
@@ -184,7 +184,7 @@ void StringData::getString(uint16 stringId, char *dest, const char *hotspotName,
 		stringId, hotspotArticle, hotspotName, characterArticle, characterName);
 	StringList &stringList = Resources::getReference().stringList();
 	char ch;
-	strcpy(dest, "");
+	dest[0] = '\0';
 	char *destPos = dest;
 	stringId &= 0x1fff;      // Strip off any article identifier
 	if (stringId == 0) return;
@@ -204,10 +204,10 @@ void StringData::getString(uint16 stringId, char *dest, const char *hotspotName,
 
 			if (p != nullptr) {
 				if (article > 0) {
-					strcpy(destPos, stringList.getString(S_ARTICLE_LIST + article - 1));
-					strcat(destPos, p);
+					Common::strcpy_s(destPos, MAX_DESC_SIZE - (destPos - dest), stringList.getString(S_ARTICLE_LIST + article - 1));
+					Common::strcat_s(destPos, MAX_DESC_SIZE - (destPos - dest), p);
 				} else {
-					strcpy(destPos, p);
+					Common::strcpy_s(destPos, MAX_DESC_SIZE - (destPos - dest), p);
 				}
 				destPos += strlen(destPos);
 
@@ -216,7 +216,7 @@ void StringData::getString(uint16 stringId, char *dest, const char *hotspotName,
 			}
 		} else if ((uint8) ch >= 0xa0) {
 			const char *p = getName((uint8) ch - 0xa0);
-			strcpy(destPos, p);
+			Common::strcpy_s(destPos, MAX_DESC_SIZE - (destPos - dest), p);
 			destPos += strlen(p);
 			debugC(ERROR_DETAILED, kLureDebugStrings, "String data %xh/%.2xh val=%.2xh sequence='%s'",
 				charOffset, charBitMask, (uint8)ch, p);
diff --git a/engines/lure/surface.cpp b/engines/lure/surface.cpp
index f2c415a0959..4e9b7979493 100644
--- a/engines/lure/surface.cpp
+++ b/engines/lure/surface.cpp
@@ -793,12 +793,12 @@ TalkDialog::TalkDialog(uint16 characterId, uint16 destCharacterId, uint16 active
 
 	strings.getString(talkingChar->nameId & 0x1fff, srcCharName);
 
-	strcpy(destCharName, "");
+	destCharName[0] = '\0';
 	if (destCharacter != nullptr) {
 		strings.getString(destCharacter->nameId, destCharName);
 		characterArticle = getArticle(descId, destCharacter->nameId);
 	}
-	strcpy(itemName, "");
+	itemName[0] = '\0';
 	if (itemHotspot != nullptr) {
 		strings.getString(itemHotspot->nameId & 0x1fff, itemName);
 		hotspotArticle = getArticle(descId, itemHotspot->nameId);


Commit: 295253abf3dbde0d44cd25b1858d724e5b9dd428
    https://github.com/scummvm/scummvm/commit/295253abf3dbde0d44cd25b1858d724e5b9dd428
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
MADS: Don't use unsafe strcat and strcpy

Changed paths:
    engines/mads/menu_views.cpp


diff --git a/engines/mads/menu_views.cpp b/engines/mads/menu_views.cpp
index ad1b30d1ac5..d2d0034bd73 100644
--- a/engines/mads/menu_views.cpp
+++ b/engines/mads/menu_views.cpp
@@ -310,7 +310,7 @@ void TextView::processText() {
 		// Delete the @ character and shift back the remainder of the string
 		char *p = centerP + 1;
 		if (*p == ' ') ++p;
-		strcpy(centerP, p);
+		Common::strcpy_s(centerP, 80 - (centerP - _currentLine), p);
 
 	} else {
 		int lineWidth = _font->getWidth(_currentLine);


Commit: e249dac38e86b524f150fd2586238967bfea6f81
    https://github.com/scummvm/scummvm/commit/e249dac38e86b524f150fd2586238967bfea6f81
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
NGI: Don't use unsafe strcat and strcpy

Changed paths:
    engines/ngi/statesaver.cpp


diff --git a/engines/ngi/statesaver.cpp b/engines/ngi/statesaver.cpp
index 574983839c7..c4278eb798d 100644
--- a/engines/ngi/statesaver.cpp
+++ b/engines/ngi/statesaver.cpp
@@ -50,7 +50,7 @@ bool GameLoader::writeSavegame(Scene *sc, const char *fname, const Common::Strin
 	memset(&header, 0, sizeof(header));
 
 	header.version = 48; // '0'
-	strcpy(header.magic, "FullPipe Savegame");
+	Common::strcpy_s(header.magic, "FullPipe Savegame");
 	header.updateCounter = _updateCounter;
 	header.unkField = 1;
 
@@ -128,7 +128,7 @@ bool GameLoader::writeSavegame(Scene *sc, const char *fname, const Common::Strin
 	uint headerPos = saveFile->pos();
 	FullpipeSavegameHeader header2;
 
-	strcpy(header2.id, "SVMCR");
+	Common::strcpy_s(header2.id, "SVMCR");
 	header2.version = NGI_SAVEGAME_VERSION;
 
 	TimeDate curTime;


Commit: a21b7eb75ab313344aea690a993860fa5272aaf0
    https://github.com/scummvm/scummvm/commit/a21b7eb75ab313344aea690a993860fa5272aaf0
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
PARALLACTION: Don't use unsafe strcat and strcpy

Changed paths:
    engines/parallaction/disk_ns.cpp
    engines/parallaction/objects.cpp
    engines/parallaction/parallaction.cpp
    engines/parallaction/parallaction_br.cpp
    engines/parallaction/parallaction_ns.cpp
    engines/parallaction/parser_br.cpp
    engines/parallaction/parser_ns.cpp
    engines/parallaction/saveload.cpp


diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp
index 342c221e931..3b7df307c0f 100644
--- a/engines/parallaction/disk_ns.cpp
+++ b/engines/parallaction/disk_ns.cpp
@@ -352,7 +352,7 @@ GfxObj* DosDisk_ns::loadHead(const char* name) {
 	char path[PATH_LEN];
 	sprintf(path, "%shead", name);
 	path[8] = '\0';
-	strcat(path, ".cnv");
+	Common::strcat_s(path, ".cnv");
 	return new GfxObj(0, loadCnv(path));
 }
 
diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp
index 4dfdd632a96..8f1e56fb628 100644
--- a/engines/parallaction/objects.cpp
+++ b/engines/parallaction/objects.cpp
@@ -396,8 +396,9 @@ void Table::addData(const char* s) {
 	if (!(_used < _size))
 		error("Table overflow");
 
-	char *data = (char *)malloc(strlen(s) + 1);
-	strcpy(data, s);
+	size_t ln = strlen(s) + 1;
+	char *data = (char *)malloc(ln);
+	Common::strcpy_s(data, ln, s);
 	_data[_used++] = data;
 }
 
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 041542f77fd..0e921facbaf 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -118,7 +118,7 @@ Common::Error Parallaction::init() {
 
 	_screenSize = _screenWidth * _screenHeight;
 
-	strcpy(_characterName1, "null");
+	Common::strcpy_s(_characterName1, "null");
 
 	memset(_localFlags, 0, sizeof(_localFlags));
 	memset(_locationNames, 0, NUM_LOCATIONS * 32);
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index f64842b88c3..e27c9f2dc4b 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -288,7 +288,7 @@ void Parallaction_br::changeLocation() {
 		// more cleanup needed for part changes (see also saveload)
 		g_globalFlags = 0;
 		cleanInventory(true);
-		strcpy(_characterName1, "null");
+		Common::strcpy_s(_characterName1, "null");
 
 		_part = _nextPart;
 
diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp
index 5daa23ccb96..6c2224df329 100644
--- a/engines/parallaction/parallaction_ns.cpp
+++ b/engines/parallaction/parallaction_ns.cpp
@@ -158,7 +158,7 @@ Common::Error Parallaction_ns::init() {
 		_disk = new DosDisk_ns(this);
 	} else {
 		if (getFeatures() & GF_DEMO) {
-			strcpy(_location._name, "fognedemo");
+			Common::strcpy_s(_location._name, "fognedemo");
 		}
 		_disk = new AmigaDisk_ns(this);
 	}
@@ -492,7 +492,7 @@ void Parallaction_ns::changeCharacter(const char *name) {
 			parseLocation("common");
 	}
 
-	strcpy(_characterName1, _char.getFullName());
+	Common::strcpy_s(_characterName1, _char.getFullName());
 
 	debugC(3, kDebugExec, "changeCharacter: switch completed");
 
diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp
index 2f892ff6995..ab0ebe31149 100644
--- a/engines/parallaction/parser_br.cpp
+++ b/engines/parallaction/parser_br.cpp
@@ -312,7 +312,7 @@ typedef Common::Functor0Mem<void, LocationParser_br> OpcodeV2;
 DECLARE_LOCATION_PARSER(location)  {
 	debugC(7, kDebugParser, "LOCATION_PARSER(location) ");
 
-	strcpy(_vm->_location._name, _tokens[1]);
+	Common::strcpy_s(_vm->_location._name, _tokens[1]);
 
 	bool flip = false;
 	int nextToken;
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index 6864d96972f..5c7c83098e8 100644
--- a/engines/parallaction/parser_ns.cpp
+++ b/engines/parallaction/parser_ns.cpp
@@ -244,10 +244,10 @@ DECLARE_ANIM_PARSER(file)  {
 	debugC(7, kDebugParser, "ANIM_PARSER(file) ");
 
 	char vC8[200];
-	strcpy(vC8, _tokens[1]);
+	Common::strcpy_s(vC8, _tokens[1]);
 	if (g_engineFlags & kEngineTransformedDonna) {
 		if (!scumm_stricmp(_tokens[1], "donnap") || !scumm_stricmp(_tokens[1], "donnapa")) {
-			strcat(vC8, "tras");
+			Common::strcat_s(vC8, "tras");
 		}
 	}
 	ctxt.a->gfxobj = _vm->_gfx->loadAnim(vC8);
@@ -915,7 +915,7 @@ DECLARE_LOCATION_PARSER(location)  {
 		mask++;
 	}
 
-	strcpy(_vm->_location._name, _tokens[1]);
+	Common::strcpy_s(_vm->_location._name, _tokens[1]);
 	_vm->changeBackground(_vm->_location._name, mask);
 
 	if (_tokens[2][0] != '\0') {
@@ -1020,7 +1020,7 @@ DECLARE_LOCATION_PARSER(sound)  {
 	debugC(7, kDebugParser, "LOCATION_PARSER(sound) ");
 
 	if (_vm->getPlatform() == Common::kPlatformAmiga) {
-		strcpy(_vm->_location._soundFile, _tokens[1]);
+		Common::strcpy_s(_vm->_location._soundFile, _tokens[1]);
 		_vm->_location._hasSound = true;
 	}
 }
diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp
index 829b3b8dc88..c98623206c5 100644
--- a/engines/parallaction/saveload.cpp
+++ b/engines/parallaction/saveload.cpp
@@ -116,7 +116,7 @@ void SaveLoad_ns::doLoadGame(uint16 slot) {
 
 	// force reload of character to solve inventory
 	// bugs, but it's a good maneuver anyway
-	strcpy(_vm->_characterName1, "null");
+	Common::strcpy_s(_vm->_characterName1, "null");
 
 	char tmp[PATH_LEN];
 	sprintf(tmp, "%s.%s" , location.c_str(), character.c_str());


Commit: e61f13b0aa9477b434f71286ae499730b066dd47
    https://github.com/scummvm/scummvm/commit/e61f13b0aa9477b434f71286ae499730b066dd47
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
QUEEN: Don't use unsafe strcat and strcpy

Changed paths:
    engines/queen/bankman.cpp
    engines/queen/command.cpp
    engines/queen/cutaway.cpp
    engines/queen/journal.cpp
    engines/queen/queen.cpp
    engines/queen/resource.cpp
    engines/queen/sound.cpp
    engines/queen/talk.cpp


diff --git a/engines/queen/bankman.cpp b/engines/queen/bankman.cpp
index 0e5e553e306..30ea16e0998 100644
--- a/engines/queen/bankman.cpp
+++ b/engines/queen/bankman.cpp
@@ -86,7 +86,7 @@ void BankManager::load(const char *bankname, uint32 bankslot) {
 	}
 
 	// mark this bank as loaded
-	strcpy(bank->name, bankname);
+	Common::strcpy_s(bank->name, bankname);
 }
 
 static void convertPlanarBitmap(uint8 *dst, int dstPitch, const uint8 *src, int w, int h, int plane) {
diff --git a/engines/queen/command.cpp b/engines/queen/command.cpp
index 0c6e4a0b950..cbfd0924a67 100644
--- a/engines/queen/command.cpp
+++ b/engines/queen/command.cpp
@@ -54,7 +54,7 @@ void CmdText::display(InkColor color, const char *command, bool outlined) {
 
 void CmdText::displayTemp(InkColor color, Verb v) {
 	char temp[MAX_COMMAND_LEN];
-	strcpy(temp, _vm->logic()->verbName(v));
+	Common::strcpy_s(temp, _vm->logic()->verbName(v));
 	display(color, temp, false);
 }
 
@@ -65,17 +65,17 @@ void CmdText::displayTemp(InkColor color, const char *name, bool outlined) {
 }
 
 void CmdText::setVerb(Verb v) {
-	strcpy(_command, _vm->logic()->verbName(v));
+	Common::strcpy_s(_command, _vm->logic()->verbName(v));
 }
 
 void CmdText::addLinkWord(Verb v) {
-	strcat(_command, " ");
-	strcat(_command, _vm->logic()->verbName(v));
+	Common::strcat_s(_command, " ");
+	Common::strcat_s(_command, _vm->logic()->verbName(v));
 }
 
 void CmdText::addObject(const char *objName) {
-	strcat(_command, " ");
-	strcat(_command, objName);
+	Common::strcat_s(_command, " ");
+	Common::strcat_s(_command, objName);
 }
 
 class CmdTextHebrew : public CmdText {
@@ -93,19 +93,19 @@ public:
 	void addLinkWord(Verb v) override {
 		char temp[MAX_COMMAND_LEN];
 
-		strcpy(temp, _command);
-		strcpy(_command, _vm->logic()->verbName(v));
-		strcat(_command, " ");
-		strcat(_command, temp);
+		Common::strcpy_s(temp, _command);
+		Common::strcpy_s(_command, _vm->logic()->verbName(v));
+		Common::strcat_s(_command, " ");
+		Common::strcat_s(_command, temp);
 	}
 
 	void addObject(const char *objName) override {
 		char temp[MAX_COMMAND_LEN];
 
-		strcpy(temp, _command);
-		strcpy(_command, objName);
-		strcat(_command, " ");
-		strcat(_command, temp);
+		Common::strcpy_s(temp, _command);
+		Common::strcpy_s(_command, objName);
+		Common::strcat_s(_command, " ");
+		Common::strcat_s(_command, temp);
 	}
 };
 
@@ -127,8 +127,8 @@ public:
 	void addObject(const char *objName) override {
 		// don't show a space after the goto and give commands in the Greek version
 		if (_command[1] != (char)-34 && !(_command[1] == (char)-2 && strlen(_command) > 5))
-			strcat(_command, " ");
-		strcat(_command, objName);
+			Common::strcat_s(_command, " ");
+		Common::strcat_s(_command, objName);
 	}
 };
 
@@ -778,7 +778,7 @@ bool Command::executeIfDialog(const char *description) {
 
 		while (cutaway[0] != '\0') {
 			char currentCutaway[20];
-			strcpy(currentCutaway, cutaway);
+			Common::strcpy_s(currentCutaway, cutaway);
 			_vm->logic()->playCutaway(currentCutaway, cutaway);
 		}
 		return true;
diff --git a/engines/queen/cutaway.cpp b/engines/queen/cutaway.cpp
index 5138f7f7ade..f25e649dd6f 100644
--- a/engines/queen/cutaway.cpp
+++ b/engines/queen/cutaway.cpp
@@ -69,7 +69,7 @@ void Cutaway::load(const char *filename) {
 	if (0 == scumm_stricmp(filename, "COMIC.CUT"))
 		_songBeforeComic = _vm->sound()->lastOverride();
 
-	strcpy(_basename, filename);
+	Common::strcpy_s(_basename, filename);
 	_basename[strlen(_basename)-4] = '\0';
 
 	_comPanel = READ_BE_UINT16(ptr);
@@ -711,7 +711,7 @@ const byte *Cutaway::handleAnimation(const byte *ptr, CutawayObject &object) {
 }
 
 static void findCdCut(const char *basename, int index, char *result) {
-	strcpy(result, basename);
+	Common::strcpy_s(result, Cutaway::MAX_STRING_SIZE, basename);
 	for (int i = strlen(basename); i < 5; i++)
 		result[i] = '_';
 	snprintf(result + 5, 3, "%02i", index);
@@ -1243,7 +1243,7 @@ void Cutaway::handleText(
 		if (_vm->sound()->speechOn()) {
 			char voiceFileName[MAX_STRING_SIZE];
 			findCdCut(_basename, index, voiceFileName);
-			strcat(voiceFileName, "1");
+			Common::strcat_s(voiceFileName, "1");
 			_vm->sound()->playSpeech(voiceFileName);
 		}
 
diff --git a/engines/queen/journal.cpp b/engines/queen/journal.cpp
index 20bb16c1fec..189c0df3446 100644
--- a/engines/queen/journal.cpp
+++ b/engines/queen/journal.cpp
@@ -547,7 +547,7 @@ void Journal::initTextField(const char *desc) {
 	_textField.posCursor = _vm->display()->textWidth(desc);
 	_textField.textCharsCount = strlen(desc);
 	memset(_textField.text, 0, sizeof(_textField.text));
-	strcpy(_textField.text, desc);
+	Common::strcpy_s(_textField.text, desc);
 }
 
 void Journal::updateTextField(uint16 ascii, int keycode) {
diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp
index a0861c40343..a0512e75bda 100644
--- a/engines/queen/queen.cpp
+++ b/engines/queen/queen.cpp
@@ -282,7 +282,7 @@ Common::String QueenEngine::getSaveStateName(int slot) const {
 
 void QueenEngine::makeGameStateName(int slot, char *buf) const {
 	Common::String name = getSaveStateName(slot);
-	strcpy(buf, name.c_str());
+	Common::strcpy_s(buf, 20, name.c_str());
 }
 
 int QueenEngine::getGameStateSlot(const char *filename) const {
@@ -303,7 +303,7 @@ void QueenEngine::findGameStateDescriptions(char descriptions[100][32]) {
 		if (i >= 0 && i < SAVESTATE_MAX_NUM) {
 			GameStateHeader header;
 			Common::InSaveFile *f = readGameStateHeader(i, &header);
-			strcpy(descriptions[i], header.description);
+			Common::strcpy_s(descriptions[i], header.description);
 			delete f;
 		}
 	}
diff --git a/engines/queen/resource.cpp b/engines/queen/resource.cpp
index 7c78f60f51c..7459161b01f 100644
--- a/engines/queen/resource.cpp
+++ b/engines/queen/resource.cpp
@@ -143,12 +143,11 @@ bool Resource::detectVersion(DetectedGameVersion *ver, Common::File *f) {
 			warning("Unknown/unsupported FOTAQ version");
 			return false;
 		}
-		strcpy(ver->str, gameVersion->str);
+		Common::strcpy_s(ver->str, gameVersion->str);
 		ver->compression = COMPRESSION_NONE;
 		ver->features = 0;
 		ver->queenTblVersion = gameVersion->queenTblVersion;
 		ver->queenTblOffset = gameVersion->queenTblOffset;
-		strcpy(ver->str, gameVersion->str);
 
 		// Handle game versions for which versionStr information is irrevelant
 		if (gameVersion == &_gameVersions[VER_AMI_DEMO]) { // CE101
diff --git a/engines/queen/sound.cpp b/engines/queen/sound.cpp
index 702fe0a76a8..a0874c34366 100644
--- a/engines/queen/sound.cpp
+++ b/engines/queen/sound.cpp
@@ -280,13 +280,13 @@ void PCSound::setVolume(int vol) {
 
 void PCSound::playSound(const char *base, bool isSpeech) {
 	char name[13];
-	strcpy(name, base);
+	Common::strcpy_s(name, base);
 	// alter filename to add zeros and append ".SB"
 	for (int i = 0; i < 8; i++) {
 		if (name[i] == ' ')
 			name[i] = '0';
 	}
-	strcat(name, ".SB");
+	Common::strcat_s(name, ".SB");
 	if (isSpeech) {
 		// Add _vm->shouldQuit() check here, otherwise game gets stuck
 		// in an infinite loop if we try to quit while a sound is playing...
diff --git a/engines/queen/talk.cpp b/engines/queen/talk.cpp
index 2e36f12395c..2c8148339d2 100644
--- a/engines/queen/talk.cpp
+++ b/engines/queen/talk.cpp
@@ -127,7 +127,7 @@ void Talk::talk(const char *filename, int personInRoom, char *cutawayFilename) {
 		_talkString[0][0] = '\0';
 
 		if (hasTalkedTo() && head == 1)
-			strcpy(_talkString[0], _person2String);
+			Common::strcpy_s(_talkString[0], _person2String);
 		else
 			findDialogueString(_person1PtrOff, head, _pMax, _talkString[0]);
 
@@ -1077,7 +1077,7 @@ TalkSelected *Talk::talkSelected() {
 
 int Talk::splitOption(const char *str, char optionText[5][MAX_STRING_SIZE]) {
 	char option[MAX_STRING_SIZE];
-	strcpy(option, str);
+	Common::strcpy_s(option, str);
 	// option text ends at '*' char
 	char *p = strchr(option, '*');
 	if (p) {
@@ -1086,7 +1086,7 @@ int Talk::splitOption(const char *str, char optionText[5][MAX_STRING_SIZE]) {
 	int lines;
 	memset(optionText, 0, 5 * MAX_STRING_SIZE);
 	if (_vm->resource()->getLanguage() == Common::EN_ANY || _vm->display()->textWidth(option) <= MAX_TEXT_WIDTH) {
-		strcpy(optionText[0], option);
+		Common::strcpy_s(optionText[0], option);
 		lines = 1;
 	} else if (_vm->resource()->getLanguage() == Common::HE_ISR) {
 		lines = splitOptionHebrew(option, optionText);
@@ -1119,10 +1119,10 @@ int Talk::splitOptionHebrew(const char *str, char optionText[5][MAX_STRING_SIZE]
 				width = wordWidth;
 				maxTextLen = MAX_TEXT_WIDTH - OPTION_TEXT_MARGIN;
 			} else {
-				strcpy(tmpString, optionText[optionLines]);
+				Common::strcpy_s(tmpString, optionText[optionLines]);
 				strncpy(optionText[optionLines], p, len);
 				optionText[optionLines][len] = '\0';
-				strcat(optionText[optionLines], tmpString);
+				Common::strcat_s(optionText[optionLines], tmpString);
 			}
 			--p;
 			len = 1;
@@ -1132,10 +1132,10 @@ int Talk::splitOptionHebrew(const char *str, char optionText[5][MAX_STRING_SIZE]
 				if (width + _vm->display()->textWidth(p + 1, len) > maxTextLen) {
 					++optionLines;
 				}
-				strcpy(tmpString, optionText[optionLines]);
+				Common::strcpy_s(tmpString, optionText[optionLines]);
 				strncpy(optionText[optionLines], p + 1, len);
 				optionText[optionLines][len] = '\0';
-				strcat(optionText[optionLines], tmpString);
+				Common::strcat_s(optionText[optionLines], tmpString);
 			}
 			++optionLines;
 		}
@@ -1171,7 +1171,7 @@ int Talk::splitOptionDefault(const char *str, char optionText[5][MAX_STRING_SIZE
 				if (width + _vm->display()->textWidth(str) > maxTextLen) {
 					++optionLines;
 				}
-				strcat(optionText[optionLines], str);
+				Common::strcat_s(optionText[optionLines], str);
 			}
 			++optionLines;
 		}


Commit: f564ffc12fd4a5bcbc3a100238cf01aa356f3847
    https://github.com/scummvm/scummvm/commit/f564ffc12fd4a5bcbc3a100238cf01aa356f3847
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SCUMM: Don't use unsafe strcat and strcpy

Changed paths:
    engines/scumm/he/intern_he.h
    engines/scumm/scumm.h
    engines/scumm/string.cpp


diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index 34452ecbd36..9925dc95fcf 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -326,7 +326,7 @@ protected:
 
 	bool handleNextCharsetCode(Actor *a, int *c) override;
 	int convertMessageToString(const byte *msg, byte *dst, int dstSize) override;
-	void fakeBidiString(byte *ltext, bool ignoreVerb) const override;
+	void fakeBidiString(byte *ltext, bool ignoreVerb, int ltextSize) const override;
 
 	void debugInput(byte *string);
 
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index c2789d28ef9..67342186932 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1480,7 +1480,7 @@ protected:
 	virtual void CHARSET_1();
 	bool newLine();
 	void drawString(int a, const byte *msg);
-	virtual void fakeBidiString(byte *ltext, bool ignoreVerb) const;
+	virtual void fakeBidiString(byte *ltext, bool ignoreVerb, int ltextSize) const;
 	void debugMessage(const byte *msg);
 	virtual void showMessageDialog(const byte *msg);
 
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index be80b1ac795..d868eb9ca9d 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -574,7 +574,7 @@ bool ScummEngine::newLine() {
 }
 
 #ifdef ENABLE_HE
-void ScummEngine_v72he::fakeBidiString(byte *ltext, bool ignoreVerb) const {
+void ScummEngine_v72he::fakeBidiString(byte *ltext, bool ignoreVerb, int ltextSize) const {
 	if (*ltext == 0x7F) {
 		ltext++;
 		while (*(ltext++) != 0x7F);
@@ -587,7 +587,7 @@ void ScummEngine_v72he::fakeBidiString(byte *ltext, bool ignoreVerb) const {
 		}
 		tmp = *loc;
 		*loc = 0;
-		strcpy((char *)ltext, Common::convertBiDiString((const char *)ltext, Common::kWindows1255).c_str());
+		Common::strcpy_s(reinterpret_cast<char *>(ltext), ltextSize, Common::convertBiDiString((const char *)ltext, Common::kWindows1255).c_str());
 		*loc = tmp;
 		loc++;
 		ltext = loc;
@@ -598,7 +598,7 @@ void ScummEngine_v72he::fakeBidiString(byte *ltext, bool ignoreVerb) const {
 }
 #endif
 
-void ScummEngine::fakeBidiString(byte *ltext, bool ignoreVerb) const {
+void ScummEngine::fakeBidiString(byte *ltext, bool ignoreVerb, int ltextSize) const {
 	// Provides custom made BiDi mechanism.
 	// Reverses texts on each line marked by control characters (considering different control characters used in verbs panel)
 	// While preserving original order of numbers (also negative numbers and comma separated)
@@ -850,7 +850,7 @@ void ScummEngine::CHARSET_1() {
 	int c = 0;
 
 	if (_isRTL)
-		fakeBidiString(_charsetBuffer + _charsetBufPos, true);
+		fakeBidiString(_charsetBuffer + _charsetBufPos, true, sizeof(_charsetBuffer) - _charsetBufPos);
 
 	bool createTextBox = (_macScreen && _game.id == GID_INDY3);
 	bool drawTextBox = false;
@@ -948,7 +948,7 @@ void ScummEngine::drawString(int a, const byte *msg) {
 	convertMessageToString(msg, buf, sizeof(buf));
 
 	if (_isRTL)
-		fakeBidiString(buf, false);
+		fakeBidiString(buf, false, sizeof(buf));
 
 	_charset->_top = _string[a].ypos + _screenTop;
 	_charset->_startLeft = _charset->_left = _string[a].xpos;
@@ -2036,7 +2036,7 @@ bool ScummEngine::reverseIfNeeded(const byte *text, byte *reverseBuf, int revers
 	if (_game.id != GID_LOOM && _game.id != GID_ZAK)
 		return false;
 	Common::strlcpy(reinterpret_cast<char *>(reverseBuf), reinterpret_cast<const char *>(text), reverseBufSize);
-	fakeBidiString(reverseBuf, true);
+	fakeBidiString(reverseBuf, true, reverseBufSize);
 	return true;
 }
 


Commit: 44870b1ad67285b8bade7237e3ebc88b0d849b54
    https://github.com/scummvm/scummvm/commit/44870b1ad67285b8bade7237e3ebc88b0d849b54
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SAGA: Don't use unsafe strcat and strcpy

Changed paths:
    engines/saga/interface.cpp
    engines/saga/resource.cpp


diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp
index 2fe58b97ff1..76d82415333 100644
--- a/engines/saga/interface.cpp
+++ b/engines/saga/interface.cpp
@@ -1208,7 +1208,7 @@ bool Interface::processTextInput(Common::KeyState keystate) {
 			if (_textInputPos != _textInputStringLength) {
 				strncat(tempString, &_textInputString[_textInputPos], _textInputStringLength - _textInputPos);
 			}
-			strcpy(_textInputString, tempString);
+			Common::strcpy_s(_textInputString, tempString);
 			_textInputStringLength = strlen(_textInputString);
 		}
 		break;
@@ -1244,16 +1244,16 @@ bool Interface::processTextInput(Common::KeyState keystate) {
 				}
 				if (_textInputPos != 1) {
 					strncpy(tempString, _textInputString, _textInputPos - 1);
-					strcat(tempString, ch);
+					Common::strcat_s(tempString, ch);
 				}
 				if ((_textInputStringLength == 0) || (_textInputPos == 1)) {
-					strcpy(tempString, ch);
+					Common::strcpy_s(tempString, ch);
 				}
 				if ((_textInputStringLength != 0) && (_textInputPos != _textInputStringLength)) {
 					strncat(tempString, &_textInputString[_textInputPos - 1], _textInputStringLength - _textInputPos + 1);
 				}
 
-				strcpy(_textInputString, tempString);
+				Common::strcpy_s(_textInputString, tempString);
 				_textInputStringLength = strlen(_textInputString);
 				_textInputPos++;
 			}
@@ -1633,7 +1633,7 @@ void Interface::setOption(PanelButton *panelButton) {
 		if (!_vm->isSaveListFull() && (_optionSaveFileTitleNumber == 0)) {
 			_textInputString[0] = 0;
 		} else {
-			strcpy(_textInputString, _vm->getSaveFile(_optionSaveFileTitleNumber)->name);
+			Common::strcpy_s(_textInputString, _vm->getSaveFile(_optionSaveFileTitleNumber)->name);
 		}
 		setMode(kPanelSave);
 		break;
diff --git a/engines/saga/resource.cpp b/engines/saga/resource.cpp
index b3fc59827cd..66459092ea9 100644
--- a/engines/saga/resource.cpp
+++ b/engines/saga/resource.cpp
@@ -193,7 +193,7 @@ bool Resource::createContexts() {
 		for (SoundFileInfo *curSoundFile = sfxFiles; (curSoundFile->gameId != -1); curSoundFile++) {
 			if (curSoundFile->gameId != _vm->getGameId()) continue;
 			if (!Common::File::exists(curSoundFile->fileName)) continue;
-			strcpy(_soundFileName, curSoundFile->fileName);
+			Common::strcpy_s(_soundFileName, curSoundFile->fileName);
 			uint32 flags = GAME_SOUNDFILE;
 
 			if (_vm->getFeatures() & GF_SOME_MAC_RESOURCES)
@@ -230,7 +230,7 @@ bool Resource::createContexts() {
 		if (curSoundFile->gameId != _vm->getGameId()) continue;
 		if (!Common::File::exists(curSoundFile->fileName)) continue;
 
-		strcpy(_voicesFileName[0], curSoundFile->fileName);
+		Common::strcpy_s(_voicesFileName[0], curSoundFile->fileName);
 		addContext(_voicesFileName[0], GAME_VOICEFILE | curSoundFile->voiceFileAddType, curSoundFile->isCompressed);
 
 		// Special cases
@@ -283,7 +283,7 @@ bool Resource::createContexts() {
 	for (SoundFileInfo *curSoundFile = musicFiles; (curSoundFile->gameId != -1); curSoundFile++) {
 		if (curSoundFile->gameId != _vm->getGameId()) continue;
 		if (!Common::File::exists(curSoundFile->fileName)) continue;
-		strcpy(_musicFileName, curSoundFile->fileName);
+		Common::strcpy_s(_musicFileName, curSoundFile->fileName);
 		uint32 flags = GAME_DIGITALMUSICFILE;
 
 		if (_vm->getFeatures() & GF_SOME_MAC_RESOURCES)


Commit: 80ee3dddd7aec1f4f591d8b99de167daf84d8e4d
    https://github.com/scummvm/scummvm/commit/80ee3dddd7aec1f4f591d8b99de167daf84d8e4d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SAGA2: Don't use unsafe strcat and strcpy

Changed paths:
    engines/saga2/document.cpp
    engines/saga2/intrface.cpp
    engines/saga2/mapfeatr.cpp
    engines/saga2/msgbox.cpp
    engines/saga2/uidialog.cpp


diff --git a/engines/saga2/document.cpp b/engines/saga2/document.cpp
index 103430509bc..febc26bdfce 100644
--- a/engines/saga2/document.cpp
+++ b/engines/saga2/document.cpp
@@ -354,8 +354,7 @@ void CDocument::pointerRelease(gPanelMessage &) {
 bool CDocument::checkForPageBreak(char *string, uint16 index, int32 &offset) {
 
 	// get the current index into the string
-	char    *strIndex       = string + index;
-	char *strAfter;
+	char *strIndex = string + index;
 
 	// page break detected
 	if (strIndex[1] == dPageBreak[0] &&
@@ -363,18 +362,16 @@ bool CDocument::checkForPageBreak(char *string, uint16 index, int32 &offset) {
 		// eat the page breaks chars
 		// tie off the end
 		strIndex[0] = 0;
-		strAfter = new char[_textSize];
-		Common::strlcpy(strAfter, &strIndex[3], _textSize);
+
+		size_t txtlen = strlen(&strIndex[3]);
 
 		// string them together
-		strcat(&strIndex[0], strAfter);
+		memmove(&strIndex[0], &strIndex[3], txtlen);
 
 		// take the offset to the end of this line
 		offset = index;
 
 		// and set the new page flag
-
-		delete[] strAfter;
 		return true;
 	}
 
@@ -441,7 +438,8 @@ bool CDocument::checkForImage(char      *string,
 			strIndex[0] = 0;
 
 			// and string them together
-			strcat(&strIndex[0], &strIndex[2 + 1 + numEat]);
+			// strIndex is inside text buffer
+			Common::strcat_s(&strIndex[0], _textSize + 1 - (&strIndex[0] - text), &strIndex[2 + 1 + numEat]);
 
 			// set new line length
 			offset = index;
diff --git a/engines/saga2/intrface.cpp b/engines/saga2/intrface.cpp
index 080db3a45e1..cf48710e187 100644
--- a/engines/saga2/intrface.cpp
+++ b/engines/saga2/intrface.cpp
@@ -398,8 +398,8 @@ CPlaqText::CPlaqText(gPanelList     &list,
                      int16         ident,
                      AppFunc       *cmd)
 	: gControl(list, box, msg, ident, cmd) {
-	if (strlen(msg) <= bufSize) {
-		strcpy(_lineBuf, msg);
+	if (strlen(msg) < bufSize) {
+		Common::strcpy_s(_lineBuf, msg);
 	} else {
 		*_lineBuf = '\0';
 	}
@@ -624,11 +624,10 @@ void CStatusLine::setLine(char *msg, uint32 frameTime) { // frametime def
 	if (newHead != _queueTail) {
 		size_t      msgLen = strlen(msg);
 
-		if ((_lineQueue[_queueHead].text = new char[msgLen + 1]()) !=  nullptr) {
-			strcpy(_lineQueue[_queueHead].text, msg);
-			_lineQueue[_queueHead].frameTime = frameTime;
-			_queueHead = newHead;
-		}
+		_lineQueue[_queueHead].text = new char[msgLen + 1];
+		Common::strcpy_s(_lineQueue[_queueHead].text, msgLen + 1, msg);
+		_lineQueue[_queueHead].frameTime = frameTime;
+		_queueHead = newHead;
 	}
 }
 
diff --git a/engines/saga2/mapfeatr.cpp b/engines/saga2/mapfeatr.cpp
index 71eea671d6e..66087ad650d 100644
--- a/engines/saga2/mapfeatr.cpp
+++ b/engines/saga2/mapfeatr.cpp
@@ -338,7 +338,7 @@ void CMapFeature::draw(TileRegion viewRegion,
 	else {
 		char msg[256];
 		sprintf(msg, "Hide: ");
-		if (!visible) strcat(msg, "not visible");
+		if (!visible) Common::strcat_s(msg, "not visible");
 		if (!(fCoords.u >= viewRegion.min.u)) sprintf(msg + strlen(msg), "U lo %d,%d ", fCoords.u, viewRegion.min.u);
 		if (!(fCoords.u <= viewRegion.max.u)) sprintf(msg + strlen(msg), "U hi %d,%d ", fCoords.u, viewRegion.max.u);
 		if (!(fCoords.v >= viewRegion.min.v)) sprintf(msg + strlen(msg), "V lo %d,%d ", fCoords.v, viewRegion.min.v);
diff --git a/engines/saga2/msgbox.cpp b/engines/saga2/msgbox.cpp
index f0644332df6..135e0903523 100644
--- a/engines/saga2/msgbox.cpp
+++ b/engines/saga2/msgbox.cpp
@@ -128,8 +128,8 @@ ErrorWindow::ErrorWindow(const char *msg, const char *btnMsg1, const char *btnMs
 	_rInfo.result    = -1;
 	_rInfo.running   = true;
 
-	strcpy(_mbChs1Text, "\x13");
-	strcpy(_mbChs2Text, "\x1B");
+	Common::strcpy_s(_mbChs1Text, "\x13");
+	Common::strcpy_s(_mbChs2Text, "\x1B");
 	const char *eq;
 	// button one
 	if (btnMsg1) {
diff --git a/engines/saga2/uidialog.cpp b/engines/saga2/uidialog.cpp
index 025bb49f8a0..056b6f21f13 100644
--- a/engines/saga2/uidialog.cpp
+++ b/engines/saga2/uidialog.cpp
@@ -967,16 +967,16 @@ int16 OptionsDialog(bool disableSaveResume) {
    message dialog box
  * ===================================================================== */
 
-char stripAccel(char *t, const char *s) {
+static char stripAccel(char (&t)[32], const char *s) {
 	char accel = '\0';
 	char    *underscore;
 
-	if (t == nullptr || s == nullptr) return accel;
-	strcpy(t, s);
+	if (s == nullptr) return accel;
+	Common::strcpy_s(t, s);
 
 	if ((underscore = strchr(t, '_')) != nullptr) {
 		accel = toupper(underscore[1]);
-		strcpy(underscore, s + (underscore - t) + 1);
+		Common::strcpy_s(underscore, sizeof(t) - (underscore - t), s + (underscore - t) + 1);
 	}
 	return accel;
 }
@@ -1634,7 +1634,7 @@ APPFUNC(cmdFileSave) {
 #else
 		deferredLoadID = saveIndex;
 		deferredSaveFlag = true;
-		strcpy(deferredSaveName, textBox->getLine(saveIndex));
+		Common::strcpy_s(deferredSaveName, textBox->getLine(saveIndex));
 #endif
 	}
 }


Commit: 0b918a5352a93d09cf45789e3581d1ee45c9cb9b
    https://github.com/scummvm/scummvm/commit/0b918a5352a93d09cf45789e3581d1ee45c9cb9b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SCI: Rename strcpy function to prepare for forbidden name

Even though strcpy in SegManager isn't a problem, our forbidden symbols
list being defined at preprocessor level, we won't be able to use this
name anymore.

Changed paths:
    engines/sci/engine/file.cpp
    engines/sci/engine/kfile.cpp
    engines/sci/engine/kgraphics.cpp
    engines/sci/engine/kmisc.cpp
    engines/sci/engine/kparse.cpp
    engines/sci/engine/kstring.cpp
    engines/sci/engine/message.cpp
    engines/sci/engine/seg_manager.cpp
    engines/sci/engine/seg_manager.h
    engines/sci/graphics/controls16.cpp


diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp
index c98fcb34213..57279810a9d 100644
--- a/engines/sci/engine/file.cpp
+++ b/engines/sci/engine/file.cpp
@@ -595,7 +595,7 @@ reg_t DirSeeker::nextFile(SegManager *segMan) {
 	}
 	if (string.size() > 12)
 		string = Common::String(string.c_str(), 12);
-	segMan->strcpy(_outbuffer, string.c_str());
+	segMan->strcpy_(_outbuffer, string.c_str());
 
 	// Return the result and advance the list iterator :)
 	++_iter;
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index eef93120829..9c9a934f81e 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -56,7 +56,7 @@ reg_t kGetCWD(EngineState *s, int argc, reg_t *argv) {
 	// We do not let the scripts see the file system, instead pretending
 	// we are always in the same directory.
 	// TODO/FIXME: Is "/" a good value? Maybe "" or "." or "C:\" are better?
-	s->_segMan->strcpy(argv[0], "/");
+	s->_segMan->strcpy_(argv[0], "/");
 
 	debugC(kDebugLevelFile, "kGetCWD() -> %s", "/");
 
@@ -78,7 +78,7 @@ reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) {
 		// WORKAROUND: The fan game script library calls kDeviceInfo with one parameter.
 		// According to the scripts, it wants to call CurDevice. However, it fails to
 		// provide the subop to the function.
-		s->_segMan->strcpy(argv[0], "/");
+		s->_segMan->strcpy_(argv[0], "/");
 		return s->r_acc;
 	}
 
@@ -88,12 +88,12 @@ reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) {
 	case K_DEVICE_INFO_GET_DEVICE: {
 		Common::String input_str = s->_segMan->getString(argv[1]);
 
-		s->_segMan->strcpy(argv[2], "/");
+		s->_segMan->strcpy_(argv[2], "/");
 		debug(3, "K_DEVICE_INFO_GET_DEVICE(%s) -> %s", input_str.c_str(), "/");
 		break;
 	}
 	case K_DEVICE_INFO_GET_CURRENT_DEVICE:
-		s->_segMan->strcpy(argv[1], "/");
+		s->_segMan->strcpy_(argv[1], "/");
 		debug(3, "K_DEVICE_INFO_GET_CURRENT_DEVICE() -> %s", "/");
 		break;
 
@@ -122,7 +122,7 @@ reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) {
 	*/
 	case K_DEVICE_INFO_GET_SAVECAT_NAME: {
 		Common::String game_prefix = s->_segMan->getString(argv[2]);
-		s->_segMan->strcpy(argv[1], "__throwaway");
+		s->_segMan->strcpy_(argv[1], "__throwaway");
 		debug(3, "K_DEVICE_INFO_GET_SAVECAT_NAME(%s) -> %s", game_prefix.c_str(), "__throwaway");
 		}
 
@@ -130,7 +130,7 @@ reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) {
 	case K_DEVICE_INFO_GET_SAVEFILE_NAME: {
 		Common::String game_prefix = s->_segMan->getString(argv[2]);
 		uint virtualId = argv[3].toUint16();
-		s->_segMan->strcpy(argv[1], "__throwaway");
+		s->_segMan->strcpy_(argv[1], "__throwaway");
 		debug(3, "K_DEVICE_INFO_GET_SAVEFILE_NAME(%s,%d) -> %s", game_prefix.c_str(), virtualId, "__throwaway");
 		if ((virtualId < SAVEGAMEID_OFFICIALRANGE_START) || (virtualId > SAVEGAMEID_OFFICIALRANGE_END))
 			error("kDeviceInfo(deleteSave): invalid savegame ID specified");
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index cffec3b31e8..785ae5bf263 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -375,7 +375,7 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
 		warning("kTextSize: string would be too big to fit on screen. Trimming it");
 		text.trim();
 		// Copy over the trimmed string...
-		s->_segMan->strcpy(argv[1], text.c_str());
+		s->_segMan->strcpy_(argv[1], text.c_str());
 		// ...and recalculate bounding box dimensions
 		g_sci->_gfxText16->kernelTextSize(splitText.c_str(), languageSplitter, font, maxWidth, &textWidth, &textHeight);
 	}
@@ -1044,7 +1044,7 @@ reg_t kDrawControl(EngineState *s, int argc, reg_t *argv) {
 				// The french version of Quest For Glory 3 uses "gloire3.sauv". It seems a translator translated the filename.
 				text.deleteChar(0);
 				text.deleteChar(0);
-				s->_segMan->strcpy(textReference, text.c_str());
+				s->_segMan->strcpy_(textReference, text.c_str());
 			}
 		}
 	}
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index 63a4b8b5248..baee4239f30 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -434,26 +434,26 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) {
 	setting.toLowercase();
 
 	if (setting == "videospeed") {
-		s->_segMan->strcpy(data, "500");
+		s->_segMan->strcpy_(data, "500");
 	} else if (setting == "cpu") {
 		// We always return the fastest CPU setting that CPUID can detect
 		// (i.e. 586).
-		s->_segMan->strcpy(data, "586");
+		s->_segMan->strcpy_(data, "586");
 	} else if (setting == "cpuspeed") {
-		s->_segMan->strcpy(data, "500");
+		s->_segMan->strcpy_(data, "500");
 	} else if (setting == "language") {
 		Common::String languageId = Common::String::format("%d", g_sci->getSciLanguage());
-		s->_segMan->strcpy(data, languageId.c_str());
+		s->_segMan->strcpy_(data, languageId.c_str());
 	} else if (setting == "torindebug") {
 		// Used to enable the debug mode in Torin's Passage (French).
 		// If true, the debug mode is enabled.
-		s->_segMan->strcpy(data, "");
+		s->_segMan->strcpy_(data, "");
 	} else if (setting == "leakdump") {
 		// An unknown setting in LSL7. Likely used for debugging.
-		s->_segMan->strcpy(data, "");
+		s->_segMan->strcpy_(data, "");
 	} else if (setting == "startroom") {
 		// Debug setting in LSL7, specifies the room to start from.
-		s->_segMan->strcpy(data, "");
+		s->_segMan->strcpy_(data, "");
 	} else if (setting == "game") {
 		// Hoyle 5 startup, specifies the number of the game to start.
 		if (g_sci->getGameId() == GID_HOYLE5 &&
@@ -461,25 +461,25 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) {
 			g_sci->getResMan()->testResource(ResourceId(kResourceTypeScript, 700))) {
 			// Special case for Hoyle 5 Bridge: only one game is included (Bridge),
 			// so mimic the setting in 700.cfg and set the starting room number to 700.
-			s->_segMan->strcpy(data, "700");
+			s->_segMan->strcpy_(data, "700");
 		} else {
-			s->_segMan->strcpy(data, "");
+			s->_segMan->strcpy_(data, "");
 		}
 	} else if (setting == "laptop") {
 		// Hoyle 5 startup.
-		s->_segMan->strcpy(data, "");
+		s->_segMan->strcpy_(data, "");
 	} else if (setting == "jumpto") {
 		// Hoyle 5 startup.
-		s->_segMan->strcpy(data, "");
+		s->_segMan->strcpy_(data, "");
 	} else if (setting == "klonchtsee") {
 		// Hoyle 5 - starting Solitaire.
-		s->_segMan->strcpy(data, "");
+		s->_segMan->strcpy_(data, "");
 	} else if (setting == "klonchtarr") {
 		// Hoyle 5 - starting Solitaire.
-		s->_segMan->strcpy(data, "");
+		s->_segMan->strcpy_(data, "");
 	} else if (setting == "deflang") {
 		// MGDX 4-language startup.
-		s->_segMan->strcpy(data, "");
+		s->_segMan->strcpy_(data, "");
 	} else {
 		error("GetConfig: Unknown configuration setting %s", setting.c_str());
 	}
diff --git a/engines/sci/engine/kparse.cpp b/engines/sci/engine/kparse.cpp
index 9128c648558..f446576da59 100644
--- a/engines/sci/engine/kparse.cpp
+++ b/engines/sci/engine/kparse.cpp
@@ -145,7 +145,7 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) {
 		writeSelectorValue(segMan, event, SELECTOR(claimed), 1);
 
 		if (error) {
-			s->_segMan->strcpy(s->_segMan->getParserPtr(), error);
+			s->_segMan->strcpy_(s->_segMan->getParserPtr(), error);
 			debugC(kDebugLevelParser, "Word unknown: %s", error);
 			/* Issue warning: */
 
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 458cea39b36..2eefa03a5fc 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -53,7 +53,7 @@ reg_t kStrCat(EngineState *s, int argc, reg_t *argv) {
 	}
 
 	s1 += s2;
-	s->_segMan->strcpy(argv[0], s1.c_str());
+	s->_segMan->strcpy_(argv[0], s1.c_str());
 	return argv[0];
 }
 
@@ -77,7 +77,7 @@ reg_t kStrCpy(EngineState *s, int argc, reg_t *argv) {
 		else
 			s->_segMan->memcpy(argv[0], argv[1], -length);
 	} else {
-		s->_segMan->strcpy(argv[0], argv[1]);
+		s->_segMan->strcpy_(argv[0], argv[1]);
 	}
 
 	return argv[0];
@@ -430,7 +430,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
 
 	*target = 0; /* Terminate string */
 
-	s->_segMan->strcpy(dest, targetbuf);
+	s->_segMan->strcpy_(dest, targetbuf);
 
 	return dest; /* Return target addr */
 }
@@ -451,7 +451,7 @@ reg_t kGetFarText(EngineState *s, int argc, reg_t *argv) {
 	if (argv[2] == NULL_REG)
 		s->_segMan->allocDynmem(text.size() + 1, "Mac FarText", &argv[2]);
 
-	s->_segMan->strcpy(argv[2], text.c_str()); // Copy the string and get return value
+	s->_segMan->strcpy_(argv[2], text.c_str()); // Copy the string and get return value
 	return argv[2];
 }
 
@@ -603,7 +603,7 @@ reg_t kStrSplit(EngineState *s, int argc, reg_t *argv) {
 						PRINT_REG(argv[0]), str.size() + 1, str.c_str());
 		return NULL_REG;
 	}
-	s->_segMan->strcpy(argv[0], str.c_str());
+	s->_segMan->strcpy_(argv[0], str.c_str());
 	return argv[0];
 }
 
@@ -819,14 +819,14 @@ reg_t kStringTrim(EngineState *s, int argc, reg_t *argv) {
 reg_t kStringToUpperCase(EngineState *s, int argc, reg_t *argv) {
 	Common::String string = s->_segMan->getString(argv[0]);
 	string.toUppercase();
-	s->_segMan->strcpy(argv[0], string.c_str());
+	s->_segMan->strcpy_(argv[0], string.c_str());
 	return argv[0];
 }
 
 reg_t kStringToLowerCase(EngineState *s, int argc, reg_t *argv) {
 	Common::String string = s->_segMan->getString(argv[0]);
 	string.toLowercase();
-	s->_segMan->strcpy(argv[0], string.c_str());
+	s->_segMan->strcpy_(argv[0], string.c_str());
 	return argv[0];
 }
 
diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp
index 4a4b2bf9fd3..4d9c2de7172 100644
--- a/engines/sci/engine/message.cpp
+++ b/engines/sci/engine/message.cpp
@@ -498,7 +498,7 @@ void MessageState::outputString(reg_t buf, const Common::String &str) {
 		SegmentRef buffer_r = _segMan->dereference(buf);
 
 		if ((unsigned)buffer_r.maxSize >= str.size() + 1) {
-			_segMan->strcpy(buf, str.c_str());
+			_segMan->strcpy_(buf, str.c_str());
 		} else {
 			// LSL6 sets an exit text here, but the buffer size allocated
 			// is too small. Don't display a warning in this case, as we
@@ -511,7 +511,7 @@ void MessageState::outputString(reg_t buf, const Common::String &str) {
 
 			// Set buffer to empty string if possible
 			if (buffer_r.maxSize > 0)
-				_segMan->strcpy(buf, "");
+				_segMan->strcpy_(buf, "");
 		}
 #ifdef ENABLE_SCI32
 	}
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 6d0a13a8ec3..2b55d5b0998 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -710,7 +710,7 @@ void SegManager::strncpy(reg_t dest, reg_t src, size_t n) {
 	if (src.isNull()) {
 		// Clear target string instead.
 		if (n > 0)
-			strcpy(dest, "");
+			strcpy_(dest, "");
 
 		return;	// empty text
 	}
@@ -722,7 +722,7 @@ void SegManager::strncpy(reg_t dest, reg_t src, size_t n) {
 
 		// Clear target string instead.
 		if (n > 0)
-			strcpy(dest, "");
+			strcpy_(dest, "");
 		return;
 	}
 
@@ -754,11 +754,11 @@ void SegManager::strncpy(reg_t dest, reg_t src, size_t n) {
 	}
 }
 
-void SegManager::strcpy(reg_t dest, const char* src) {
+void SegManager::strcpy_(reg_t dest, const char* src) {
 	strncpy(dest, src, 0xFFFFFFFFU);
 }
 
-void SegManager::strcpy(reg_t dest, reg_t src) {
+void SegManager::strcpy_(reg_t dest, reg_t src) {
 	strncpy(dest, src, 0xFFFFFFFFU);
 }
 
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 189264a6f05..9a417a793ec 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -316,14 +316,14 @@ public:
 	 * src and dest can point to raw and non-raw segments.
 	 * Conversion is performed as required.
 	 */
-	void strcpy(reg_t dest, reg_t src);
+	void strcpy_(reg_t dest, reg_t src);
 
 	/**
 	 * Copies a string from src to dest.
 	 * dest can point to a raw or non-raw segment.
 	 * Conversion is performed as required.
 	 */
-	void strcpy(reg_t dest, const char *src);
+	void strcpy_(reg_t dest, const char *src);
 
 	/**
 	 * Copies a string from src to dest.
diff --git a/engines/sci/graphics/controls16.cpp b/engines/sci/graphics/controls16.cpp
index f8573852ce2..e350f8dacd7 100644
--- a/engines/sci/graphics/controls16.cpp
+++ b/engines/sci/graphics/controls16.cpp
@@ -292,7 +292,7 @@ void GfxControls16::kernelTexteditChange(reg_t controlObject, reg_t eventObject)
 		texteditCursorDraw(rect, text.c_str(), cursorPos);
 		_text16->SetFont(oldFontId);
 		// Write back string
-		_segMan->strcpy(textReference, text.c_str());
+		_segMan->strcpy_(textReference, text.c_str());
 	} else {
 		if (g_system->getMillis() >= _texteditBlinkTime) {
 			_paint16->invertRect(_texteditCursorRect);


Commit: 682c11e801874c034f38acf1afd81bca1240dfbc
    https://github.com/scummvm/scummvm/commit/682c11e801874c034f38acf1afd81bca1240dfbc
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SCI: Don't use unsafe strcat and strcpy

Changed paths:
    engines/sci/engine/kstring.cpp


diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 2eefa03a5fc..083d5ee2a8c 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -338,7 +338,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
 
 				}
 
-				strcpy(target, tempsource.c_str());
+				Common::strcpy_s(target, sizeof(targetbuf) - (target - targetbuf), tempsource.c_str());
 				target += slen;
 
 				switch (align) {


Commit: 5b67238944a93a52714e267df5a20fc2ac099e6c
    https://github.com/scummvm/scummvm/commit/5b67238944a93a52714e267df5a20fc2ac099e6c
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SKY: Don't use unsafe strcat and strcpy

Changed paths:
    engines/sky/compact.cpp
    engines/sky/compact.h
    engines/sky/control.cpp
    engines/sky/debug.cpp
    engines/sky/text.cpp


diff --git a/engines/sky/compact.cpp b/engines/sky/compact.cpp
index 448a03ee075..5bad4015f76 100644
--- a/engines/sky/compact.cpp
+++ b/engines/sky/compact.cpp
@@ -288,7 +288,7 @@ Compact *SkyCompact::fetchCpt(uint16 cptId) {
 	return _compacts[cptId >> 12][cptId & 0xFFF];
 }
 
-Compact *SkyCompact::fetchCptInfo(uint16 cptId, uint16 *elems, uint16 *type, char *name) {
+Compact *SkyCompact::fetchCptInfo(uint16 cptId, uint16 *elems, uint16 *type, char *name, size_t nameSize) {
 	assert(((cptId >> 12) < _numDataLists) && ((cptId & 0xFFF) < _dataListLen[cptId >> 12]));
 	if (elems)
 		*elems = _cptSizes[cptId >> 12][cptId & 0xFFF];
@@ -296,9 +296,9 @@ Compact *SkyCompact::fetchCptInfo(uint16 cptId, uint16 *elems, uint16 *type, cha
 		*type  = _cptTypes[cptId >> 12][cptId & 0xFFF];
 	if (name) {
 		if (_cptNames[cptId >> 12][cptId & 0xFFF] != NULL)
-			strcpy(name, _cptNames[cptId >> 12][cptId & 0xFFF]);
+			Common::strcpy_s(name, nameSize, _cptNames[cptId >> 12][cptId & 0xFFF]);
 		else
-			strcpy(name, "(null)");
+			Common::strcpy_s(name, nameSize, "(null)");
 	}
 	return fetchCpt(cptId);
 }
diff --git a/engines/sky/compact.h b/engines/sky/compact.h
index 53bce8ee526..3e72befb276 100644
--- a/engines/sky/compact.h
+++ b/engines/sky/compact.h
@@ -60,7 +60,7 @@ public:
 	SkyCompact();
 	~SkyCompact();
 	Compact *fetchCpt(uint16 cptId);
-	Compact *fetchCptInfo(uint16 cptId, uint16 *elems = NULL, uint16 *type = NULL, char *name = NULL);
+	Compact *fetchCptInfo(uint16 cptId, uint16 *elems = NULL, uint16 *type = NULL, char *name = NULL, size_t nameSize = 0);
 	static uint16 getSub(Compact *cpt, uint16 mode);
 	static void setSub(Compact *cpt, uint16 mode, uint16 value);
 	static MegaSet *getMegaSet(Compact *cpt);
diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp
index 4d325e0993c..f00ab4fbb1e 100644
--- a/engines/sky/control.cpp
+++ b/engines/sky/control.cpp
@@ -1423,7 +1423,7 @@ uint16 Control::parseSaveData(uint8 *srcBuf) {
 			uint16 numElems;
 			uint16 type;
 			char name[128];
-			uint16 *rawCpt = (uint16 *)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, &type, name);
+			uint16 *rawCpt = (uint16 *)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, &type, name, sizeof(name));
 			if (type == COMPACT) {
 				importOldCompact((Compact *)rawCpt, &srcPos, numElems, type, name);
 			} else if (type == ROUTEBUF) {
diff --git a/engines/sky/debug.cpp b/engines/sky/debug.cpp
index f103007c104..002d7fb76c7 100644
--- a/engines/sky/debug.cpp
+++ b/engines/sky/debug.cpp
@@ -1137,7 +1137,7 @@ static const char *const noYes[] = { "no", "yes" };
 void Debugger::dumpCompact(uint16 cptId) {
 	uint16 type, size;
 	char name[256];
-	Compact *cpt = _skyCompact->fetchCptInfo(cptId, &size, &type, name);
+	Compact *cpt = _skyCompact->fetchCptInfo(cptId, &size, &type, name, sizeof(name));
 
 	if (type == COMPACT) {
 		debugPrintf("Compact %s: id = %04X, section %d, id %d\n", name, cptId, cptId >> 12, cptId & 0xFFF);
@@ -1154,9 +1154,9 @@ void Debugger::dumpCompact(uint16 cptId) {
 		debugPrintf("           : ar priority : %s\n", noYes[(cpt->status & ST_AR_PRIORITY) >> 8]);
 		debugPrintf("sync       : %04X\n", cpt->sync);
 		debugPrintf("screen     : %d\n", cpt->screen);
-		_skyCompact->fetchCptInfo(cpt->place, NULL, NULL, name);
+		_skyCompact->fetchCptInfo(cpt->place, NULL, NULL, name, sizeof(name));
 		debugPrintf("place      : %04X: %s\n", cpt->place, name);
-		_skyCompact->fetchCptInfo(cpt->getToTableId, NULL, NULL, name);
+		_skyCompact->fetchCptInfo(cpt->getToTableId, NULL, NULL, name, sizeof(name));
 		debugPrintf("get to tab : %04X: %s\n", cpt->getToTableId, name);
 		debugPrintf("x/y        : %d/%d\n", cpt->xcood, cpt->ycood);
 	} else {
@@ -1201,7 +1201,7 @@ bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
 						uint16 cptId = (uint16)((sec << 12) | cpt);
 						uint16 type, size;
 						char name[256];
-						_skyCompact->fetchCptInfo(cptId, &size, &type, name);
+						_skyCompact->fetchCptInfo(cptId, &size, &type, name, sizeof(name));
 						linePos += sprintf(linePos, "%04X: %10s %22s", cptId, _skyCompact->nameForType(type), name);
 					}
 					if (linePos != line)
@@ -1211,7 +1211,7 @@ bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
 						uint16 cptId = (uint16)((sec << 12) | cpt);
 						uint16 type, size;
 						char name[256];
-						_skyCompact->fetchCptInfo(cptId, &size, &type, name);
+						_skyCompact->fetchCptInfo(cptId, &size, &type, name, sizeof(name));
 						if (type == COMPACT)
 							debugPrintf("%04X: %s\n", cptId, name);
 					}
@@ -1333,15 +1333,15 @@ bool Debugger::Cmd_LogicList(int argc, const char **argv) {
 
 	char cptName[256];
 	uint16 numElems, type;
-	uint16 *logicList = (uint16 *)_skyCompact->fetchCptInfo(Logic::_scriptVariables[LOGIC_LIST_NO], &numElems, &type, cptName);
+	uint16 *logicList = (uint16 *)_skyCompact->fetchCptInfo(Logic::_scriptVariables[LOGIC_LIST_NO], &numElems, &type, cptName, sizeof(cptName));
 	debugPrintf("Current LogicList: %04X (%s)\n", Logic::_scriptVariables[LOGIC_LIST_NO], cptName);
 	while (*logicList != 0) {
 		if (*logicList == 0xFFFF) {
 			uint16 newList = logicList[1];
-			logicList = (uint16 *)_skyCompact->fetchCptInfo(newList, &numElems, &type, cptName);
+			logicList = (uint16 *)_skyCompact->fetchCptInfo(newList, &numElems, &type, cptName, sizeof(cptName));
 			debugPrintf("New List: %04X (%s)\n", newList, cptName);
 		} else {
-			_skyCompact->fetchCptInfo(*logicList, &numElems, &type, cptName);
+			_skyCompact->fetchCptInfo(*logicList, &numElems, &type, cptName, sizeof(cptName));
 			debugPrintf(" Cpt %04X (%s) (%s)\n", *logicList, cptName, _skyCompact->nameForType(type));
 			logicList++;
 		}
diff --git a/engines/sky/text.cpp b/engines/sky/text.cpp
index 42ca2b59c72..f71f3a9bbdb 100644
--- a/engines/sky/text.cpp
+++ b/engines/sky/text.cpp
@@ -246,14 +246,16 @@ DisplayedText Text::displayText(char *textPtr, uint8 *dest, bool center, uint16
 	// work around bug #1080 (line width exceeded)
 	char *tmpPtr = strstr(textPtr, "MUND-BEATMUNG!");
 	if (tmpPtr)
-		strcpy(tmpPtr, "MUND BEATMUNG!");
+		// We are sure there is at least this space and we replace it by something of same length
+		Common::strcpy_s(tmpPtr, sizeof("MUND-BEATMUNG!"), "MUND BEATMUNG!");
 
 	// work around bug #1940 (line width exceeded when talking to gardener using spanish text)
 	// This text apparently only is broken in the floppy versions, the CD versions contain
 	// the correct string "MANIFESTACION - ARTISTICA.", which doesn't break the algorithm/game.
 	tmpPtr = strstr(textPtr, "MANIFESTACION-ARTISTICA.");
 	if (tmpPtr)
-		strcpy(tmpPtr, "MANIFESTACION ARTISTICA.");
+		// We are sure there is at least this space and we replace it by something of same length
+		Common::strcpy_s(tmpPtr, sizeof("MANIFESTACION-ARTISTICA."), "MANIFESTACION ARTISTICA.");
 
 	char *curPos = textPtr;
 	char *lastSpace = textPtr;
@@ -455,7 +457,7 @@ bool Text::patchMessage(uint32 textNum) {
 	uint16 patchNum = _patchLangNum[SkyEngine::_systemVars->language];
 	for (uint16 cnt = 0; cnt < patchNum; cnt++) {
 		if (_patchedMessages[cnt + patchIdx].textNr == textNum) {
-			strcpy(_textBuffer, _patchedMessages[cnt + patchIdx].text);
+			Common::strcpy_s(_textBuffer, _patchedMessages[cnt + patchIdx].text);
 			return true;
 		}
 	}


Commit: 1a5ef8794a74ca36d1fa8e5209cfee31db96eb4a
    https://github.com/scummvm/scummvm/commit/1a5ef8794a74ca36d1fa8e5209cfee31db96eb4a
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
STARTREK: Don't use unsafe strcat and strcpy

Changed paths:
    engines/startrek/actors.cpp
    engines/startrek/metaengine.cpp
    engines/startrek/rooms/demon1.cpp
    engines/startrek/rooms/demon3.cpp
    engines/startrek/rooms/love1.cpp
    engines/startrek/rooms/love2.cpp
    engines/startrek/textbox.cpp


diff --git a/engines/startrek/actors.cpp b/engines/startrek/actors.cpp
index 06628446c13..e48b2d5ab9d 100644
--- a/engines/startrek/actors.cpp
+++ b/engines/startrek/actors.cpp
@@ -1171,7 +1171,7 @@ int StarTrekEngine::showInventoryMenu(int x, int y, bool restoreMouse) {
 
 	while (itemIndex < NUM_OBJECTS) {
 		if (_itemList[itemIndex].have) {
-			strcpy(itemNames[numItems], _itemList[itemIndex].name);
+			Common::strcpy_s(itemNames[numItems], _itemList[itemIndex].name);
 
 			int16 itemX = (numItems % ITEMS_PER_ROW) * 32 + x;
 			int16 itemY = (numItems / ITEMS_PER_ROW) * 32 + y;
diff --git a/engines/startrek/metaengine.cpp b/engines/startrek/metaengine.cpp
index 625c7fc9f53..72903fcabf3 100644
--- a/engines/startrek/metaengine.cpp
+++ b/engines/startrek/metaengine.cpp
@@ -114,7 +114,7 @@ SaveStateList StarTrekMetaEngine::listSaves(const char *target) const {
 						break;
 				}
 				if (descriptionPos >= sizeof(meta.description)) {
-					strcpy(meta.description, "[broken saved game]");
+					Common::strcpy_s(meta.description, "[broken saved game]");
 				}
 
 				saveList.push_back(SaveStateDescriptor(this, slotNr, meta.description));
diff --git a/engines/startrek/rooms/demon1.cpp b/engines/startrek/rooms/demon1.cpp
index c1048e81d71..b50ee350a48 100644
--- a/engines/startrek/rooms/demon1.cpp
+++ b/engines/startrek/rooms/demon1.cpp
@@ -275,16 +275,16 @@ void Room::demon1Timer1Expired() {
 
 		switch (_roomVar.demon.attackIndex) {
 		case 0:
-			strcpy(_roomVar.demon.d6, "klg1fr");
+			Common::strcpy_s(_roomVar.demon.d6, "klg1fr");
 			break;
 		case 1:
-			strcpy(_roomVar.demon.d6, "klg1fm");
+			Common::strcpy_s(_roomVar.demon.d6, "klg1fm");
 			break;
 		case 2:
-			strcpy(_roomVar.demon.d6, "klg1fs");
+			Common::strcpy_s(_roomVar.demon.d6, "klg1fs");
 			break;
 		case 3:
-			strcpy(_roomVar.demon.d6, "klg1fk");
+			Common::strcpy_s(_roomVar.demon.d6, "klg1fk");
 			break;
 		default:
 			return;
@@ -294,16 +294,16 @@ void Room::demon1Timer1Expired() {
 		shooter = 9;
 		switch (_roomVar.demon.attackIndex) {
 		case 0:
-			strcpy(_roomVar.demon.d6, "klg2fr");
+			Common::strcpy_s(_roomVar.demon.d6, "klg2fr");
 			break;
 		case 1:
-			strcpy(_roomVar.demon.d6, "klg2fm");
+			Common::strcpy_s(_roomVar.demon.d6, "klg2fm");
 			break;
 		case 2:
-			strcpy(_roomVar.demon.d6, "klg2fs");
+			Common::strcpy_s(_roomVar.demon.d6, "klg2fs");
 			break;
 		case 3:
-			strcpy(_roomVar.demon.d6, "klg2fk");
+			Common::strcpy_s(_roomVar.demon.d6, "klg2fk");
 			break;
 		default:
 			return;
@@ -313,16 +313,16 @@ void Room::demon1Timer1Expired() {
 		shooter = 10;
 		switch (_roomVar.demon.attackIndex) {
 		case 0:
-			strcpy(_roomVar.demon.d6, "klg3fr");
+			Common::strcpy_s(_roomVar.demon.d6, "klg3fr");
 			break;
 		case 1:
-			strcpy(_roomVar.demon.d6, "klg3fm");
+			Common::strcpy_s(_roomVar.demon.d6, "klg3fm");
 			break;
 		case 2:
-			strcpy(_roomVar.demon.d6, "klg3fs");
+			Common::strcpy_s(_roomVar.demon.d6, "klg3fs");
 			break;
 		case 3:
-			strcpy(_roomVar.demon.d6, "klg3fk");
+			Common::strcpy_s(_roomVar.demon.d6, "klg3fk");
 			break;
 		default:
 			return;
diff --git a/engines/startrek/rooms/demon3.cpp b/engines/startrek/rooms/demon3.cpp
index 914f196c988..eb653d412e3 100644
--- a/engines/startrek/rooms/demon3.cpp
+++ b/engines/startrek/rooms/demon3.cpp
@@ -399,7 +399,7 @@ void Room::demon3UsePhaserOnBoulder1() {
 	_awayMission->demon.numBouldersGone++;
 	_roomVar.demon.boulderBeingShot = 1;
 	_roomVar.demon.boulder1Shot = true;
-	strcpy(_roomVar.demon.boulderAnim, "s0r3s2");
+	Common::strcpy_s(_roomVar.demon.boulderAnim, "s0r3s2");
 	demon3BoulderCommon();
 }
 
@@ -409,7 +409,7 @@ void Room::demon3UsePhaserOnBoulder2() {
 	_awayMission->demon.boulder2Gone = true;
 	_awayMission->demon.numBouldersGone++;
 	_roomVar.demon.boulderBeingShot = 2;
-	strcpy(_roomVar.demon.boulderAnim, "s0r3s3");
+	Common::strcpy_s(_roomVar.demon.boulderAnim, "s0r3s3");
 	demon3BoulderCommon();
 }
 
@@ -420,7 +420,7 @@ void Room::demon3UsePhaserOnBoulder3() {
 		_awayMission->demon.boulder3Gone = true;
 		_awayMission->demon.numBouldersGone++;
 		_roomVar.demon.boulderBeingShot = 3;
-		strcpy(_roomVar.demon.boulderAnim, "s0r3s1");
+		Common::strcpy_s(_roomVar.demon.boulderAnim, "s0r3s1");
 		demon3BoulderCommon();
 	} else {
 		showText(TX_SPEAKER_SPOCK, TX_DEM3_006);
@@ -434,7 +434,7 @@ void Room::demon3UsePhaserOnBoulder4() {
 		_awayMission->demon.boulder4Gone = true;
 		_awayMission->demon.numBouldersGone++;
 		_roomVar.demon.boulderBeingShot = 4;
-		strcpy(_roomVar.demon.boulderAnim, "s0r3s4");
+		Common::strcpy_s(_roomVar.demon.boulderAnim, "s0r3s4");
 		_awayMission->demon.foundMiner = true;
 		demon3BoulderCommon();
 	} else {
diff --git a/engines/startrek/rooms/love1.cpp b/engines/startrek/rooms/love1.cpp
index e92f7e0ce9a..a46a09e79f9 100644
--- a/engines/startrek/rooms/love1.cpp
+++ b/engines/startrek/rooms/love1.cpp
@@ -359,22 +359,22 @@ void Room::love1Tick1() {
 
 	switch (_awayMission->love.bottleInNozzle) {
 	case BOTTLETYPE_N2O:
-		strcpy(_roomVar.love.bottleAnimation, "btle1");
+		Common::strcpy_s(_roomVar.love.bottleAnimation, "btle1");
 		_roomVar.love.itemInNozzle = OBJECT_IN2O;
 		loadActorAnim(OBJECT_BOTTLE, _roomVar.love.bottleAnimation, 0xa3, 0x72, 0);
 		break;
 	case BOTTLETYPE_NH3:
-		strcpy(_roomVar.love.bottleAnimation, "btle2");
+		Common::strcpy_s(_roomVar.love.bottleAnimation, "btle2");
 		_roomVar.love.itemInNozzle = OBJECT_INH3;
 		loadActorAnim(OBJECT_BOTTLE, _roomVar.love.bottleAnimation, 0xa3, 0x72, 0);
 		break;
 	case BOTTLETYPE_H2O:
-		strcpy(_roomVar.love.bottleAnimation, "btle3");
+		Common::strcpy_s(_roomVar.love.bottleAnimation, "btle3");
 		_roomVar.love.itemInNozzle = OBJECT_IH2O;
 		loadActorAnim(OBJECT_BOTTLE, _roomVar.love.bottleAnimation, 0xa3, 0x72, 0);
 		break;
 	case BOTTLETYPE_RLG:
-		strcpy(_roomVar.love.bottleAnimation, "btle4");
+		Common::strcpy_s(_roomVar.love.bottleAnimation, "btle4");
 		_roomVar.love.itemInNozzle = OBJECT_IRLG;
 		loadActorAnim(OBJECT_BOTTLE, _roomVar.love.bottleAnimation, 0xa3, 0x72, 0);
 		break;
@@ -662,7 +662,7 @@ void Room::love1KirkGotBottleFromNozzle() {
 void Room::love1UseN2OOnNozzle() {
 	if (_awayMission->love.bottleInNozzle == BOTTLETYPE_NONE) {
 		_roomVar.love.itemInNozzle = OBJECT_IN2O;
-		strcpy(_roomVar.love.bottleAnimation, "btle1");
+		Common::strcpy_s(_roomVar.love.bottleAnimation, "btle1");
 		_awayMission->love.bottleInNozzle = BOTTLETYPE_N2O;
 		walkCrewman(OBJECT_KIRK, 0xa6, 0x90, 3);
 	}
@@ -671,7 +671,7 @@ void Room::love1UseN2OOnNozzle() {
 void Room::love1UseH2OOnNozzle() {
 	if (_awayMission->love.bottleInNozzle == BOTTLETYPE_NONE) {
 		_roomVar.love.itemInNozzle = OBJECT_IH2O;
-		strcpy(_roomVar.love.bottleAnimation, "btle3");
+		Common::strcpy_s(_roomVar.love.bottleAnimation, "btle3");
 		_awayMission->love.bottleInNozzle = BOTTLETYPE_H2O;
 		walkCrewman(OBJECT_KIRK, 0xa6, 0x90, 3);
 	}
@@ -680,7 +680,7 @@ void Room::love1UseH2OOnNozzle() {
 void Room::love1UseNH3OnNozzle() {
 	if (_awayMission->love.bottleInNozzle == BOTTLETYPE_NONE) {
 		_roomVar.love.itemInNozzle = OBJECT_INH3;
-		strcpy(_roomVar.love.bottleAnimation, "btle2");
+		Common::strcpy_s(_roomVar.love.bottleAnimation, "btle2");
 		_awayMission->love.bottleInNozzle = BOTTLETYPE_NH3;
 		walkCrewman(OBJECT_KIRK, 0xa6, 0x90, 3);
 	}
@@ -689,7 +689,7 @@ void Room::love1UseNH3OnNozzle() {
 void Room::love1UseRLGOnNozzle() {
 	if (_awayMission->love.bottleInNozzle == BOTTLETYPE_NONE) {
 		_roomVar.love.itemInNozzle = OBJECT_IRLG;
-		strcpy(_roomVar.love.bottleAnimation, "btle4");
+		Common::strcpy_s(_roomVar.love.bottleAnimation, "btle4");
 		_awayMission->love.bottleInNozzle = BOTTLETYPE_RLG;
 		walkCrewman(OBJECT_KIRK, 0xa6, 0x90, 3);
 	}
diff --git a/engines/startrek/rooms/love2.cpp b/engines/startrek/rooms/love2.cpp
index 8c6d591656a..7b9b1ec8630 100644
--- a/engines/startrek/rooms/love2.cpp
+++ b/engines/startrek/rooms/love2.cpp
@@ -391,13 +391,13 @@ void Room::love2Tick1() {
 
 	switch (_awayMission->love.canister1) {
 	case CANTYPE_O2:
-		strcpy(canName, "o2can");
+		Common::strcpy_s(canName, "o2can");
 		break;
 	case CANTYPE_H2:
-		strcpy(canName, "h2can");
+		Common::strcpy_s(canName, "h2can");
 		break;
 	case CANTYPE_N2:
-		strcpy(canName, "n2can");
+		Common::strcpy_s(canName, "n2can");
 		break;
 	default:
 		break;
@@ -408,13 +408,13 @@ void Room::love2Tick1() {
 
 	switch (_awayMission->love.canister2) {
 	case CANTYPE_O2:
-		strcpy(canName, "o2can");
+		Common::strcpy_s(canName, "o2can");
 		break;
 	case CANTYPE_H2:
-		strcpy(canName, "h2can");
+		Common::strcpy_s(canName, "h2can");
 		break;
 	case CANTYPE_N2:
-		strcpy(canName, "n2can");
+		Common::strcpy_s(canName, "n2can");
 		break;
 	default:
 		break;
@@ -445,37 +445,37 @@ void Room::love2Tick1() {
 
 	switch (_awayMission->love.synthesizerContents) {
 	case SYNTHITEM_PBC:
-		strcpy(_roomVar.love.chamberInputAnim, "pbcanm");
+		Common::strcpy_s(_roomVar.love.chamberInputAnim, "pbcanm");
 		_roomVar.love.chamberObject = OBJECT_POLYBERYLCARBONATE;
 		break;
 	case SYNTHITEM_VIRUS_SAMPLE:
-		strcpy(_roomVar.love.chamberInputAnim, "dishes");
+		Common::strcpy_s(_roomVar.love.chamberInputAnim, "dishes");
 		_roomVar.love.chamberObject = OBJECT_VIRUSSAMPLE;
 		break;
 	case SYNTHITEM_CURE_SAMPLE:
-		strcpy(_roomVar.love.chamberInputAnim, "dishes");
+		Common::strcpy_s(_roomVar.love.chamberInputAnim, "dishes");
 		_roomVar.love.chamberObject = OBJECT_CURESAMPLE;
 		break;
 	case SYNTHITEM_BOTTLE:
 		switch (_awayMission->love.synthesizerBottleIndex) {
 		case 1:
-			strcpy(_roomVar.love.chamberOutputAnim, "btle1");
+			Common::strcpy_s(_roomVar.love.chamberOutputAnim, "btle1");
 			_roomVar.love.chamberObject = OBJECT_SYNTHESIZER_OUTPUT;
 			break;
 		case 2:
-			strcpy(_roomVar.love.chamberOutputAnim, "btle2");
+			Common::strcpy_s(_roomVar.love.chamberOutputAnim, "btle2");
 			_roomVar.love.chamberObject = OBJECT_SYNTHESIZER_OUTPUT;
 			break;
 		case 3:
-			strcpy(_roomVar.love.chamberOutputAnim, "btle3");
+			Common::strcpy_s(_roomVar.love.chamberOutputAnim, "btle3");
 			_roomVar.love.chamberObject = OBJECT_SYNTHESIZER_OUTPUT;
 			break;
 		case 4:
-			strcpy(_roomVar.love.chamberOutputAnim, "btle4");
+			Common::strcpy_s(_roomVar.love.chamberOutputAnim, "btle4");
 			_roomVar.love.chamberObject = OBJECT_SYNTHESIZER_OUTPUT;
 			break;
 		default:
-			strcpy(_roomVar.love.chamberOutputAnim, "cure");
+			Common::strcpy_s(_roomVar.love.chamberOutputAnim, "cure");
 			_roomVar.love.chamberObject = OBJECT_CURE;
 			break;
 		}
@@ -707,21 +707,21 @@ void Room::love2ChangedGasFeed() {
 
 void Room::love2UseO2GasOnCanisterSlot() {
 	_roomVar.love.canisterType = CANTYPE_O2;
-	strcpy(_roomVar.love.canisterAnim, "o2can");
+	Common::strcpy_s(_roomVar.love.canisterAnim, "o2can");
 	_roomVar.love.canisterItem = OBJECT_IO2GAS;
 	walkCrewman(OBJECT_KIRK, 0xa8, 0xb7, 3);
 }
 
 void Room::love2UseH2GasOnCanisterSlot() {
 	_roomVar.love.canisterType = CANTYPE_H2;
-	strcpy(_roomVar.love.canisterAnim, "h2can");
+	Common::strcpy_s(_roomVar.love.canisterAnim, "h2can");
 	_roomVar.love.canisterItem = OBJECT_IH2GAS;
 	walkCrewman(OBJECT_KIRK, 0xa8, 0xb7, 3);
 }
 
 void Room::love2UseN2GasOnCanisterSlot() {
 	_roomVar.love.canisterType = CANTYPE_N2;
-	strcpy(_roomVar.love.canisterAnim, "n2can");
+	Common::strcpy_s(_roomVar.love.canisterAnim, "n2can");
 	_roomVar.love.canisterItem = OBJECT_IN2GAS;
 	walkCrewman(OBJECT_KIRK, 0xa8, 0xb7, 3);
 }
@@ -926,7 +926,7 @@ void Room::love2UseSynthesizer() {
 				case SYNTHITEM_NONE: // Water
 				default:
 					_awayMission->love.synthesizerBottleIndex = BOTTLETYPE_H2O;
-					strcpy(_roomVar.love.chamberOutputAnim, "btle3");
+					Common::strcpy_s(_roomVar.love.chamberOutputAnim, "btle3");
 					// Produce bottle
 					loadActorAnim(OBJECT_SYNTHESIZER_DOOR, "s3r3d2", 0x8a, 0x8d, 3); // -> love2SynthesizerDoorClosed
 					playSoundEffectIndex(kSfxDoor);
@@ -968,7 +968,7 @@ void Room::love2UseSynthesizer() {
 				case SYNTHITEM_NONE: // Ammonia
 				default:
 					_awayMission->love.synthesizerBottleIndex = BOTTLETYPE_NH3;
-					strcpy(_roomVar.love.chamberOutputAnim, "btle2");
+					Common::strcpy_s(_roomVar.love.chamberOutputAnim, "btle2");
 					// Produce bottle
 					loadActorAnim(OBJECT_SYNTHESIZER_DOOR, "s3r3d2", 0x8a, 0x8d, 3); // -> love2SynthesizerDoorClosed
 					playSoundEffectIndex(kSfxDoor);
@@ -1013,7 +1013,7 @@ void Room::love2UseSynthesizer() {
 				case SYNTHITEM_NONE: // Laughing gas
 				default:
 					_awayMission->love.synthesizerBottleIndex = BOTTLETYPE_N2O;
-					strcpy(_roomVar.love.chamberOutputAnim, "btle1");
+					Common::strcpy_s(_roomVar.love.chamberOutputAnim, "btle1");
 					// Produce bottle
 					loadActorAnim(OBJECT_SYNTHESIZER_DOOR, "s3r3d2", 0x8a, 0x8d, 3); // -> love2SynthesizerDoorClosed
 					playSoundEffectIndex(kSfxDoor);
@@ -1075,7 +1075,7 @@ void Room::love2SynthesizerFinished() {
 
 void Room::love2ClosedSynthesizerDoorMakingRLG() {
 	_awayMission->love.synthesizerBottleIndex = BOTTLETYPE_RLG;
-	strcpy(_roomVar.love.chamberOutputAnim, "btle4");
+	Common::strcpy_s(_roomVar.love.chamberOutputAnim, "btle4");
 	loadActorAnim(OBJECT_SYNTHESIZER_DOOR, "s3r3d2", 0x8a, 0x8d, 3); // -> love2SynthesizerDoorClosed
 	playSoundEffectIndex(kSfxDoor);
 }
diff --git a/engines/startrek/textbox.cpp b/engines/startrek/textbox.cpp
index 124cbc467ed..f6a60a6ce1f 100644
--- a/engines/startrek/textbox.cpp
+++ b/engines/startrek/textbox.cpp
@@ -728,7 +728,7 @@ Common::String StarTrekEngine::showComputerInputBox() {
 void StarTrekEngine::redrawTextInput() {
 	char buf[MAX_TEXT_INPUT_LEN * 2 + 2];
 	memset(buf, 0, MAX_TEXT_INPUT_LEN * 2);
-	strcpy(buf, _textInputBuffer);
+	Common::strcpy_s(buf, _textInputBuffer);
 
 	if (_textInputCursorChar != 0)
 		buf[_textInputCursorPos] = _textInputCursorChar;
@@ -790,7 +790,7 @@ Common::String StarTrekEngine::showTextInputBox(int16 x, int16 y, const Common::
 					_textInputCursorPos--;
 					Common::String str(_textInputBuffer);
 					str.deleteChar(_textInputCursorPos);
-					strcpy(_textInputBuffer, str.c_str());
+					Common::strcpy_s(_textInputBuffer, str.c_str());
 				}
 				redrawTextInput();
 				break;
@@ -799,7 +799,7 @@ Common::String StarTrekEngine::showTextInputBox(int16 x, int16 y, const Common::
 				Common::String str(_textInputBuffer);
 				if (_textInputCursorPos < (int)str.size()) {
 					str.deleteChar(_textInputCursorPos);
-					strcpy(_textInputBuffer, str.c_str());
+					Common::strcpy_s(_textInputBuffer, str.c_str());
 					redrawTextInput();
 				}
 				break;


Commit: 51da2bbd7cb168a2dee74d5ec589c0e1733854a1
    https://github.com/scummvm/scummvm/commit/51da2bbd7cb168a2dee74d5ec589c0e1733854a1
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SWORD2: Don't use unsafe strcat and strcpy

Changed paths:
    engines/sword2/controls.cpp
    engines/sword2/function.cpp
    engines/sword2/screen.cpp


diff --git a/engines/sword2/controls.cpp b/engines/sword2/controls.cpp
index 91a22135f8f..ff718ddb920 100644
--- a/engines/sword2/controls.cpp
+++ b/engines/sword2/controls.cpp
@@ -1343,7 +1343,7 @@ void SaveRestoreDialog::onAction(Widget *widget, int result) {
 			else
 				_firstPos = 4;
 
-			strcpy((char *)_editBuffer, (char *)slot->getText());
+			Common::strcpy_s(_editBuffer, (char *)slot->getText());
 			_editPos = strlen((char *)_editBuffer);
 			_cursorTick = 0;
 			_editBuffer[_editPos] = '_';
diff --git a/engines/sword2/function.cpp b/engines/sword2/function.cpp
index 387ea628769..d324a34d19d 100644
--- a/engines/sword2/function.cpp
+++ b/engines/sword2/function.cpp
@@ -2125,9 +2125,9 @@ int32 Logic::fnPlaySequence(int32 *params) {
 
 	// add the appropriate file extension & play it
 
-	strcpy(filename, (const char *)decodePtr(params[0]));
+	Common::strcpy_s(filename, (const char *)decodePtr(params[0]));
 	if (Sword2Engine::isPsx() && readVar(DEMO) && strcmp(filename, "enddemo") == 0) {
-		strcpy(filename, "rdemo");
+		Common::strcpy_s(filename, "rdemo");
 	}
 
 	// Write to walkthrough file (zebug0.txt)
diff --git a/engines/sword2/screen.cpp b/engines/sword2/screen.cpp
index 0c5272f2927..a33939f1b60 100644
--- a/engines/sword2/screen.cpp
+++ b/engines/sword2/screen.cpp
@@ -85,8 +85,8 @@ Screen::Screen(Sword2Engine *vm, int16 width, int16 height) {
 	_largestLayerArea = 0;
 	_largestSpriteArea = 0;
 
-	strcpy(_largestLayerInfo,  "largest layer:  none registered");
-	strcpy(_largestSpriteInfo, "largest sprite: none registered");
+	Common::strcpy_s(_largestLayerInfo,  "largest layer:  none registered");
+	Common::strcpy_s(_largestSpriteInfo, "largest sprite: none registered");
 
 	_fadeStatus = RDFADE_NONE;
 	_renderAverageTime = 60;


Commit: b7ef4078dc3f40788e57dcb0bbe60303c8704705
    https://github.com/scummvm/scummvm/commit/b7ef4078dc3f40788e57dcb0bbe60303c8704705
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SWORD25: Don't use unsafe strcat and strcpy

Changed paths:
    engines/sword25/package/packagemanager.h


diff --git a/engines/sword25/package/packagemanager.h b/engines/sword25/package/packagemanager.h
index 23e3c8b7ec7..8dadb02ef1b 100644
--- a/engines/sword25/package/packagemanager.h
+++ b/engines/sword25/package/packagemanager.h
@@ -153,13 +153,14 @@ public:
 		const char *versionStr = "<?xml version=\"1.0\"?>";
 		uint fileSize;
 		char *data = (char *)getFile(fileName, &fileSize);
-		char *result = (char *)malloc(fileSize + strlen(versionStr) + 1);
+		size_t resultSize = fileSize + strlen(versionStr) + 1;
+		char *result = (char *)malloc(resultSize);
 		if (!result)
 			error("[PackageManager::getXmlFile] Cannot allocate memory");
 
-		strcpy(result, versionStr);
+		Common::strcpy_s(result, resultSize, versionStr);
 		Common::copy(data, data + fileSize, result + strlen(versionStr));
-		result[fileSize + strlen(versionStr)] = '\0';
+		result[resultSize - 1] = '\0';
 
 		delete[] data;
 		if (pFileSize)


Commit: 422d8d98ae6cd4a38a5519a5d5f1774c55452f44
    https://github.com/scummvm/scummvm/commit/422d8d98ae6cd4a38a5519a5d5f1774c55452f44
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
TEENAGENT: Don't use unsafe strcat and strcpy

Changed paths:
    engines/teenagent/objects.cpp
    engines/teenagent/objects.h


diff --git a/engines/teenagent/objects.cpp b/engines/teenagent/objects.cpp
index e4bb75edd2b..262a04ee2fb 100644
--- a/engines/teenagent/objects.cpp
+++ b/engines/teenagent/objects.cpp
@@ -66,7 +66,8 @@ void Object::load(byte *src) {
 	actorOrientation = *src++;
 	enabled = *src++;
 	name = (const char *)src;
-	description = parseDescription((const char *)src);
+	_nameSize = name.size() + 1;
+	description = parseDescription((const char *)src + _nameSize);
 }
 
 void Object::save() const {
@@ -80,7 +81,7 @@ void Object::save() const {
 
 void Object::setName(const Common::String &newName) {
 	assert(_base != 0);
-	strcpy((char *)(_base + 19), newName.c_str());
+	Common::strcpy_s((char *)(_base + 19), _nameSize, newName.c_str());
 	name = newName;
 }
 
@@ -92,8 +93,7 @@ void Object::dump(int level) const {
 	     );
 }
 
-Common::String Object::parseDescription(const char *name) {
-	const char *desc = name + strlen(name) + 1;
+Common::String Object::parseDescription(const char *desc) {
 	if (*desc == 0)
 		return Common::String();
 
diff --git a/engines/teenagent/objects.h b/engines/teenagent/objects.h
index 5ff18b1c4e1..eea39f0d36d 100644
--- a/engines/teenagent/objects.h
+++ b/engines/teenagent/objects.h
@@ -164,16 +164,17 @@ struct Object {
 	//19
 	Common::String name, description;
 
-	Object(): _base(NULL) { id = 0; actorOrientation = 0; enabled = 0;  }
+	Object(): _base(NULL), _nameSize(0) { id = 0; actorOrientation = 0; enabled = 0;  }
 	void dump(int level = 0) const;
 	void setName(const Common::String &newName);
 	void load(byte *addr);
 	void save() const;
 
-	static Common::String parseDescription(const char *name);
+	static Common::String parseDescription(const char *desc);
 
 protected:
 	byte *_base;
+	size_t _nameSize;
 };
 
 struct InventoryObject {


Commit: 52caebf8aff93333ed811fb6b1493abbaa6a43a1
    https://github.com/scummvm/scummvm/commit/52caebf8aff93333ed811fb6b1493abbaa6a43a1
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
TINSEL: Don't use unsafe strcat and strcpy

Changed paths:
    engines/tinsel/drives.cpp
    engines/tinsel/strres.cpp


diff --git a/engines/tinsel/drives.cpp b/engines/tinsel/drives.cpp
index 1ab7ef4ddde..931b2766fb3 100644
--- a/engines/tinsel/drives.cpp
+++ b/engines/tinsel/drives.cpp
@@ -193,7 +193,7 @@ bool TinselFile::open(const Common::String &filename) {
 	// Form a filename without the CD number character
 	char newFilename[50];
 	strncpy(newFilename, fname, p - fname);
-	strcpy(newFilename + (p - fname), p + 1);
+	Common::strcpy_s(newFilename + (p - fname), sizeof(newFilename) - (p - fname), p + 1);
 
 	return openInternal(newFilename);
 }
diff --git a/engines/tinsel/strres.cpp b/engines/tinsel/strres.cpp
index 737d25060f9..dd3582dd1d1 100644
--- a/engines/tinsel/strres.cpp
+++ b/engines/tinsel/strres.cpp
@@ -234,7 +234,7 @@ int LoadStringResource(int id, int sub, char *pBuffer, int bufferMax) {
 	byte *pText = FindStringBase(id);
 
 	if (pText == NULL) {
-		strcpy(pBuffer, "!! HIGH STRING !!");
+		Common::strcpy_s(pBuffer, bufferMax, "!! HIGH STRING !!");
 		return 0;
 	}
 
@@ -310,7 +310,7 @@ int LoadStringResource(int id, int sub, char *pBuffer, int bufferMax) {
 	}
 
 	// TEMPORARY DIRTY BODGE
-	strcpy(pBuffer, "!! NULL STRING !!");
+	Common::strcpy_s(pBuffer, bufferMax, "!! NULL STRING !!");
 
 	// string does not exist
 	return 0;


Commit: 4bbe3d9286337b28862fb6b048a50dad9503c078
    https://github.com/scummvm/scummvm/commit/4bbe3d9286337b28862fb6b048a50dad9503c078
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
ULTIMA: Don't use unsafe strcat and strcpy

Changed paths:
    engines/ultima/nuvie/gui/gui_text_toggle_button.cpp
    engines/ultima/nuvie/gui/widgets/fps_counter.cpp
    engines/ultima/nuvie/usecode/u6_usecode.cpp
    engines/ultima/ultima4/views/stats.cpp


diff --git a/engines/ultima/nuvie/gui/gui_text_toggle_button.cpp b/engines/ultima/nuvie/gui/gui_text_toggle_button.cpp
index de99087e4f2..10a36568f37 100644
--- a/engines/ultima/nuvie/gui/gui_text_toggle_button.cpp
+++ b/engines/ultima/nuvie/gui/gui_text_toggle_button.cpp
@@ -40,9 +40,9 @@ GUI_TextToggleButton::GUI_TextToggleButton(void *data, int x, int y, int w, int
 
 	texts = new char *[count];
 	for (int i = 0; i < count; ++i) {
-		int l = strlen(texts_[i]);
-		texts[i] = new char[l + 1];
-		strcpy(texts[i], texts_[i]);
+		int l = strlen(texts_[i]) + 1;
+		texts[i] = new char[l];
+		Common::strcpy_s(texts[i], l, texts_[i]);
 	}
 
 	ChangeTextButton(-1, -1, -1, -1, texts[selection], alignment);
diff --git a/engines/ultima/nuvie/gui/widgets/fps_counter.cpp b/engines/ultima/nuvie/gui/widgets/fps_counter.cpp
index c81aa441135..9ee84962f66 100644
--- a/engines/ultima/nuvie/gui/widgets/fps_counter.cpp
+++ b/engines/ultima/nuvie/gui/widgets/fps_counter.cpp
@@ -42,7 +42,7 @@ FpsCounter::FpsCounter(Game *g) : GUI_Widget(NULL) {
 
 	Init(NULL, x_off + 280, y_off, 40, 10);
 
-	strcpy(fps_string, "000.00");
+	Common::strcpy_s(fps_string, "000.00");
 }
 
 FpsCounter::~FpsCounter() {
diff --git a/engines/ultima/nuvie/usecode/u6_usecode.cpp b/engines/ultima/nuvie/usecode/u6_usecode.cpp
index c2e0ca963b9..be75ff0248e 100644
--- a/engines/ultima/nuvie/usecode/u6_usecode.cpp
+++ b/engines/ultima/nuvie/usecode/u6_usecode.cpp
@@ -528,7 +528,7 @@ bool U6UseCode::use_passthrough(Obj *obj, UseCodeEvent ev) {
 			new_x--;
 
 		new_frame_n = 2; // open the pass through
-		strcpy(action_string, "Open");
+		Common::strcpy_s(action_string, "Open");
 	} else { // the pass through is currently open.
 		if (obj->obj_n == OBJ_U6_V_PASSTHROUGH)
 			new_y++;
@@ -536,7 +536,7 @@ bool U6UseCode::use_passthrough(Obj *obj, UseCodeEvent ev) {
 			new_x++;
 
 		new_frame_n = 0; // close the pass through
-		strcpy(action_string, "Close");
+		Common::strcpy_s(action_string, "Close");
 	}
 
 	if (!map->actor_at_location(new_x, new_y, obj->z)) {
@@ -729,8 +729,9 @@ bool U6UseCode::use_rune(Obj *obj, UseCodeEvent ev) {
 	} else if (ev == USE_EVENT_MESSAGE && items.string_ref) {
 		scroll->display_string("\n");
 
-		char *mantra = new char[items.string_ref->size() + 1];
-		strcpy(mantra, items.string_ref->c_str());
+		size_t mantraSize = items.string_ref->size() + 1;
+		char *mantra = new char[mantraSize];
+		Common::strcpy_s(mantra, mantraSize, items.string_ref->c_str());
 
 		if (scumm_stricmp(mantra,  mantras[rune_obj_offset]) == 0) {
 			// find the matching force field for this shrine. match rune offset against force field quality
@@ -1386,8 +1387,9 @@ bool U6UseCode::use_fountain(Obj *obj, UseCodeEvent ev) {
 		} else { // answered with wish
 			get_wish = false;
 			bool wished_for_food = false;
-			char *wish = (char *)malloc(items.string_ref->size() + 1);
-			strcpy(wish, items.string_ref->c_str());
+			size_t wishSize = items.string_ref->size() + 1;
+			char *wish = (char *)malloc(wishSize);
+			Common::strcpy_s(wish, wishSize, items.string_ref->c_str());
 			if (scumm_stricmp(wish, "Food") == 0 || scumm_stricmp(wish, "Mutton") == 0
 			        || scumm_stricmp(wish, "Wine") == 0 || scumm_stricmp(wish, "Fruit") == 0
 			        || scumm_stricmp(wish, "Mead") == 0)
diff --git a/engines/ultima/ultima4/views/stats.cpp b/engines/ultima/ultima4/views/stats.cpp
index bab0da15031..79f85455da1 100644
--- a/engines/ultima/ultima4/views/stats.cpp
+++ b/engines/ultima/ultima4/views/stats.cpp
@@ -318,15 +318,15 @@ void StatsArea::showItems() {
 	if (g_ultima->_saveGame->_items & (ITEM_CANDLE | ITEM_BOOK | ITEM_BELL)) {
 		buffer[0] = '\0';
 		if (g_ultima->_saveGame->_items & ITEM_BELL) {
-			strcat(buffer, getItemName(ITEM_BELL));
-			strcat(buffer, " ");
+			Common::strcat_s(buffer, getItemName(ITEM_BELL));
+			Common::strcat_s(buffer, " ");
 		}
 		if (g_ultima->_saveGame->_items & ITEM_BOOK) {
-			strcat(buffer, getItemName(ITEM_BOOK));
-			strcat(buffer, " ");
+			Common::strcat_s(buffer, getItemName(ITEM_BOOK));
+			Common::strcat_s(buffer, " ");
 		}
 		if (g_ultima->_saveGame->_items & ITEM_CANDLE) {
-			strcat(buffer, getItemName(ITEM_CANDLE));
+			Common::strcat_s(buffer, getItemName(ITEM_CANDLE));
 			buffer[15] = '\0';
 		}
 		_mainArea.textAt(0, line++, "%s", buffer);


Commit: 73c09b1d5677fa2360bcf21e9cdcd7d0d40ddf3d
    https://github.com/scummvm/scummvm/commit/73c09b1d5677fa2360bcf21e9cdcd7d0d40ddf3d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
WINTERMUTE: Don't use unsafe strcat and strcpy

Changed paths:
    engines/wintermute/ad/ad_game.cpp
    engines/wintermute/ad/ad_node_state.cpp
    engines/wintermute/ad/ad_object.cpp
    engines/wintermute/ad/ad_response_context.cpp
    engines/wintermute/ad/ad_scene_state.cpp
    engines/wintermute/ad/ad_sentence.cpp
    engines/wintermute/base/base.cpp
    engines/wintermute/base/base_frame.cpp
    engines/wintermute/base/base_game.cpp
    engines/wintermute/base/base_game_settings.cpp
    engines/wintermute/base/base_named_object.cpp
    engines/wintermute/base/base_object.cpp
    engines/wintermute/base/base_parser.cpp
    engines/wintermute/base/base_script_holder.cpp
    engines/wintermute/base/base_scriptable.cpp
    engines/wintermute/base/base_sprite.cpp
    engines/wintermute/base/base_string_table.cpp
    engines/wintermute/base/base_sub_frame.cpp
    engines/wintermute/base/file/base_save_thumb_file.cpp
    engines/wintermute/base/gfx/xmodel.cpp
    engines/wintermute/base/particles/part_emitter.cpp
    engines/wintermute/base/scriptables/script.cpp
    engines/wintermute/base/scriptables/script_ext_array.cpp
    engines/wintermute/base/scriptables/script_ext_string.cpp
    engines/wintermute/base/scriptables/script_value.cpp
    engines/wintermute/ui/ui_edit.cpp
    engines/wintermute/ui/ui_object.cpp
    engines/wintermute/utils/utils.cpp


diff --git a/engines/wintermute/ad/ad_game.cpp b/engines/wintermute/ad/ad_game.cpp
index 3767c47af60..db3c1d189d5 100644
--- a/engines/wintermute/ad/ad_game.cpp
+++ b/engines/wintermute/ad/ad_game.cpp
@@ -1559,10 +1559,9 @@ void AdGame::setPrevSceneName(const char *name) {
 	delete[] _prevSceneName;
 	_prevSceneName = nullptr;
 	if (name) {
-		_prevSceneName = new char[strlen(name) + 1];
-		if (_prevSceneName) {
-			strcpy(_prevSceneName, name);
-		}
+		size_t nameSize = strlen(name) + 1;
+		_prevSceneName = new char[nameSize];
+		Common::strcpy_s(_prevSceneName, nameSize, name);
 	}
 }
 
@@ -1572,10 +1571,9 @@ void AdGame::setPrevSceneFilename(const char *name) {
 	delete[] _prevSceneFilename;
 	_prevSceneFilename = nullptr;
 	if (name) {
-		_prevSceneFilename = new char[strlen(name) + 1];
-		if (_prevSceneFilename) {
-			strcpy(_prevSceneFilename, name);
-		}
+		size_t nameSize = strlen(name) + 1;
+		_prevSceneFilename = new char[nameSize];
+		Common::strcpy_s(_prevSceneFilename, nameSize, name);
 	}
 }
 
@@ -1588,8 +1586,9 @@ bool AdGame::scheduleChangeScene(const char *filename, bool fadeIn) {
 	if (_scene && !_scene->_initialized) {
 		return changeScene(filename, fadeIn);
 	} else {
-		_scheduledScene = new char [strlen(filename) + 1];
-		strcpy(_scheduledScene, filename);
+		size_t filenameSize = strlen(filename) + 1;
+		_scheduledScene = new char [filenameSize];
+		Common::strcpy_s(_scheduledScene, filenameSize, filename);
 
 		_scheduledFadeIn = fadeIn;
 
@@ -1736,8 +1735,9 @@ bool AdGame::loadItemsFile(const char *filename, bool merge) {
 
 	bool ret;
 
-	//_filename = new char [strlen(filename)+1];
-	//strcpy(_filename, filename);
+	//size_t filenameSize = strlen(filename) + 1;
+	//_filename = new char [filenameSize];
+	//Common::strcpy_s(_filename, filenameSize, filename);
 
 	if (DID_FAIL(ret = loadItemsBuffer(buffer, merge))) {
 		_gameRef->LOG(0, "Error parsing ITEMS file '%s'", filename);
@@ -1807,8 +1807,9 @@ bool AdGame::loadItemsBuffer(char *buffer, bool merge) {
 
 //////////////////////////////////////////////////////////////////////////
 AdSceneState *AdGame::getSceneState(const char *filename, bool saving) {
-	char *filenameCor = new char[strlen(filename) + 1];
-	strcpy(filenameCor, filename);
+	size_t filenameSize = strlen(filename) + 1;
+	char *filenameCor = new char[filenameSize];
+	Common::strcpy_s(filenameCor, filenameSize, filename);
 	for (uint32 i = 0; i < strlen(filenameCor); i++) {
 		if (filenameCor[i] == '/') {
 			filenameCor[i] = '\\';
@@ -2274,10 +2275,11 @@ bool AdGame::addSpeechDir(const char *dir) {
 		return STATUS_FAILED;
 	}
 
-	char *temp = new char[strlen(dir) + 2];
-	strcpy(temp, dir);
-	if (temp[strlen(temp) - 1] != '\\' && temp[strlen(temp) - 1] != '/') {
-		strcat(temp, "\\");
+	size_t dirSize = strlen(dir) + 2;
+	char *temp = new char[dirSize];
+	Common::strcpy_s(temp, dirSize, dir);
+	if (temp[dirSize - 2 - 1] != '\\' && temp[dirSize - 2 - 1] != '/') {
+		Common::strcat_s(temp, dirSize, "\\");
 	}
 
 	for (uint32 i = 0; i < _speechDirs.size(); i++) {
@@ -2298,10 +2300,11 @@ bool AdGame::removeSpeechDir(const char *dir) {
 		return STATUS_FAILED;
 	}
 
-	char *temp = new char[strlen(dir) + 2];
-	strcpy(temp, dir);
-	if (temp[strlen(temp) - 1] != '\\' && temp[strlen(temp) - 1] != '/') {
-		strcat(temp, "\\");
+	size_t dirSize = strlen(dir) + 2;
+	char *temp = new char[dirSize];
+	Common::strcpy_s(temp, dirSize, dir);
+	if (temp[dirSize - 2 - 1] != '\\' && temp[dirSize - 2 - 1] != '/') {
+		Common::strcat_s(temp, dirSize, "\\");
 	}
 
 	bool found = false;
diff --git a/engines/wintermute/ad/ad_node_state.cpp b/engines/wintermute/ad/ad_node_state.cpp
index 2ebe79bea2e..6c1cba36f5e 100644
--- a/engines/wintermute/ad/ad_node_state.cpp
+++ b/engines/wintermute/ad/ad_node_state.cpp
@@ -118,11 +118,10 @@ void AdNodeState::setCaption(const char *caption, int caseVal) {
 	}
 
 	delete[] _caption[caseVal - 1];
-	_caption[caseVal - 1] = new char[strlen(caption) + 1];
-	if (_caption[caseVal - 1]) {
-		strcpy(_caption[caseVal - 1], caption);
-		_gameRef->expandStringByStringTable(&_caption[caseVal - 1]);
-	}
+	size_t captionSize = strlen(caption) + 1;
+	_caption[caseVal - 1] = new char[captionSize];
+	Common::strcpy_s(_caption[caseVal - 1], captionSize, caption);
+	_gameRef->expandStringByStringTable(&_caption[caseVal - 1]);
 }
 
 
diff --git a/engines/wintermute/ad/ad_object.cpp b/engines/wintermute/ad/ad_object.cpp
index cf7557f6da3..bc860f14070 100644
--- a/engines/wintermute/ad/ad_object.cpp
+++ b/engines/wintermute/ad/ad_object.cpp
@@ -254,8 +254,9 @@ bool AdObject::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
 		stack->correctParams(1);
 		const char *animName = stack->pop()->getString();
 		delete[] _forcedTalkAnimName;
-		_forcedTalkAnimName = new char[strlen(animName) + 1];
-		strcpy(_forcedTalkAnimName, animName);
+		size_t animNameSize = strlen(animName) + 1;
+		_forcedTalkAnimName = new char[animNameSize];
+		Common::strcpy_s(_forcedTalkAnimName, animNameSize, animName);
 		_forcedTalkAnimUsed = false;
 		stack->pushBool(true);
 		return STATUS_OK;
diff --git a/engines/wintermute/ad/ad_response_context.cpp b/engines/wintermute/ad/ad_response_context.cpp
index ec2eaa98fb0..40f0f155173 100644
--- a/engines/wintermute/ad/ad_response_context.cpp
+++ b/engines/wintermute/ad/ad_response_context.cpp
@@ -60,10 +60,9 @@ void AdResponseContext::setContext(const char *context) {
 	delete[] _context;
 	_context = nullptr;
 	if (context) {
-		_context = new char [strlen(context) + 1];
-		if (_context) {
-			strcpy(_context, context);
-		}
+		size_t contextSize = strlen(context) + 1;
+		_context = new char [contextSize];
+		Common::strcpy_s(_context, contextSize, context);
 	}
 }
 
diff --git a/engines/wintermute/ad/ad_scene_state.cpp b/engines/wintermute/ad/ad_scene_state.cpp
index a576826aa7a..2959cd4d99b 100644
--- a/engines/wintermute/ad/ad_scene_state.cpp
+++ b/engines/wintermute/ad/ad_scene_state.cpp
@@ -65,10 +65,9 @@ bool AdSceneState::persist(BasePersistenceManager *persistMgr) {
 //////////////////////////////////////////////////////////////////////////
 void AdSceneState::setFilename(const char *filename) {
 	delete[] _filename;
-	_filename = new char [strlen(filename) + 1];
-	if (_filename) {
-		strcpy(_filename, filename);
-	}
+	size_t filenameSize = strlen(filename) + 1;
+	_filename = new char [filenameSize];
+	Common::strcpy_s(_filename, filenameSize, filename);
 }
 
 const char *AdSceneState::getFilename() const {
diff --git a/engines/wintermute/ad/ad_sentence.cpp b/engines/wintermute/ad/ad_sentence.cpp
index 3c60468985b..3f30d36c8c6 100644
--- a/engines/wintermute/ad/ad_sentence.cpp
+++ b/engines/wintermute/ad/ad_sentence.cpp
@@ -91,26 +91,20 @@ AdSentence::~AdSentence() {
 
 //////////////////////////////////////////////////////////////////////////
 void AdSentence::setText(const char *text) {
-	if (_text) {
-		delete[] _text;
-	}
-	_text = new char[strlen(text) + 1];
-	if (_text) {
-		strcpy(_text, text);
-	}
+	delete[] _text;
+	size_t textSize = strlen(text) + 1;
+	_text = new char[textSize];
+	Common::strcpy_s(_text, textSize, text);
 }
 
 
 //////////////////////////////////////////////////////////////////////////
 void AdSentence::setStances(const char *stances) {
-	if (_stances) {
-		delete[] _stances;
-	}
+	delete[] _stances;
 	if (stances) {
-		_stances = new char[strlen(stances) + 1];
-		if (_stances) {
-			strcpy(_stances, stances);
-		}
+		size_t stancesSize = strlen(stances) + 1;
+		_stances = new char[stancesSize];
+		Common::strcpy_s(_stances, stancesSize, stances);
 	} else {
 		_stances = nullptr;
 	}
diff --git a/engines/wintermute/base/base.cpp b/engines/wintermute/base/base.cpp
index 6d27dfd75e3..4146a0d153e 100644
--- a/engines/wintermute/base/base.cpp
+++ b/engines/wintermute/base/base.cpp
@@ -116,26 +116,20 @@ bool BaseClass::parseEditorProperty(char *buffer, bool complete) {
 
 	while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
 		switch (cmd) {
-		case TOKEN_NAME:
+		case TOKEN_NAME: {
 			delete[] propName;
-			propName = new char[strlen(params) + 1];
-			if (propName) {
-				strcpy(propName, params);
-			} else {
-				cmd = PARSERR_GENERIC;
-			}
+			size_t propNameSize = strlen(params) + 1;
+			propName = new char[propNameSize];
+			Common::strcpy_s(propName, propNameSize, params);
 			break;
-
-		case TOKEN_VALUE:
+		}
+		case TOKEN_VALUE: {
 			delete[] propValue;
-			propValue = new char[strlen(params) + 1];
-			if (propValue) {
-				strcpy(propValue, params);
-			} else {
-				cmd = PARSERR_GENERIC;
-			}
+			size_t propValueSize = strlen(params) + 1;
+			propValue = new char[propValueSize];
+			Common::strcpy_s(propValue, propValueSize, params);
 			break;
-
+		}
 		default:
 			break;
 		}
diff --git a/engines/wintermute/base/base_frame.cpp b/engines/wintermute/base/base_frame.cpp
index a863d0d1760..6d5e3b38e81 100644
--- a/engines/wintermute/base/base_frame.cpp
+++ b/engines/wintermute/base/base_frame.cpp
@@ -280,8 +280,9 @@ bool BaseFrame::loadBuffer(char *buffer, int lifeTime, bool keepLoaded) {
 		break;
 
 		case TOKEN_APPLY_EVENT: {
-			char *event = new char[strlen(params) + 1];
-			strcpy(event, params);
+			size_t eventSize = strlen(params) + 1;
+			char *event = new char[eventSize];
+			Common::strcpy_s(event, eventSize, params);
 			_applyEvent.add(event);
 		}
 		break;
diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp
index 31fd8d4c591..3864063f6d5 100644
--- a/engines/wintermute/base/base_game.cpp
+++ b/engines/wintermute/base/base_game.cpp
@@ -1228,8 +1228,9 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
 	else if (strcmp(name, "ExpandString") == 0) {
 		stack->correctParams(1);
 		ScValue *val = stack->pop();
-		char *str = new char[strlen(val->getString()) + 1];
-		strcpy(str, val->getString());
+		size_t strSize = strlen(val->getString()) + 1;
+		char *str = new char[strSize];
+		Common::strcpy_s(str, strSize, val->getString());
 		expandStringByStringTable(&str);
 		stack->pushString(str);
 		delete[] str;
@@ -1460,8 +1461,9 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
 		const char *xdesc = stack->pop()->getString();
 		bool quick = stack->pop()->getBool(false);
 
-		char *desc = new char[strlen(xdesc) + 1];
-		strcpy(desc, xdesc);
+		size_t descSize = strlen(xdesc) + 1;
+		char *desc = new char[descSize];
+		Common::strcpy_s(desc, descSize, xdesc);
 		stack->pushBool(true);
 		if (DID_FAIL(saveGame(slot, desc, quick))) {
 			stack->pop();
@@ -3633,8 +3635,9 @@ bool BaseGame::externalCall(ScScript *script, ScStack *stack, ScStack *thisStack
 	else if (strcmp(name, "ToString") == 0) {
 		stack->correctParams(1);
 		const char *str = stack->pop()->getString();
-		char *str2 = new char[strlen(str) + 1];
-		strcpy(str2, str);
+		size_t strSize = strlen(str) + 1;
+		char *str2 = new char[strSize];
+		Common::strcpy_s(str2, strSize, str);
 		stack->pushString(str2);
 		delete[] str2;
 	}
@@ -3703,7 +3706,7 @@ bool BaseGame::externalCall(ScScript *script, ScStack *stack, ScStack *thisStack
 
 		// Let's make copies before modifying stack
 		char *copy = new char[size];
-		strcpy(copy, str);
+		Common::strcpy_s(copy, size, str);
 
 		// There is no way to makeSXArray() with exactly 1 given element
 		// That's why we are creating empty Array and SXArray::push() later
@@ -3737,8 +3740,9 @@ bool BaseGame::externalCall(ScScript *script, ScStack *stack, ScStack *thisStack
 	else if (strcmp(name, "Trim") == 0 || strcmp(name, "lTrim") == 0 || strcmp(name, "rTrim") == 0) {
 		stack->correctParams(1);
 		const char *str = stack->pop()->getString();
-		char *copy = new char[strlen(str) + 1];
-		strcpy(copy, str);
+		size_t copySize = strlen(str) + 1;
+		char *copy = new char[copySize];
+		Common::strcpy_s(copy, copySize, str);
 
 		char *ptr = copy;
 		if (strcmp(name, "rTrim") != 0) {
diff --git a/engines/wintermute/base/base_game_settings.cpp b/engines/wintermute/base/base_game_settings.cpp
index f6e8808129f..5643c56ad04 100644
--- a/engines/wintermute/base/base_game_settings.cpp
+++ b/engines/wintermute/base/base_game_settings.cpp
@@ -122,14 +122,13 @@ bool BaseGameSettings::loadSettings(const char *filename) {
 	buffer = params;
 	while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
 		switch (cmd) {
-			case TOKEN_GAME:
+			case TOKEN_GAME: {
 				delete[] _gameFile;
-				_gameFile = new char[strlen(params) + 1];
-				if (_gameFile) {
-					strcpy(_gameFile, params);
-				}
+				size_t gameFileSize = strlen(params) + 1;
+				_gameFile = new char[gameFileSize];
+				Common::strcpy_s(_gameFile, gameFileSize, params);
 				break;
-
+			}
 			case TOKEN_STRING_TABLE:
 				if (DID_FAIL(_stringTable->loadFile(params))) {
 					cmd = PARSERR_GENERIC;
diff --git a/engines/wintermute/base/base_named_object.cpp b/engines/wintermute/base/base_named_object.cpp
index 4743cd14cbb..adafec3e55d 100644
--- a/engines/wintermute/base/base_named_object.cpp
+++ b/engines/wintermute/base/base_named_object.cpp
@@ -61,10 +61,9 @@ void BaseNamedObject::setName(const char *name) {
 		return;
 	}
 
-	_name = new char [strlen(name) + 1];
-	if (_name != nullptr) {
-		strcpy(_name, name);
-	}
+	size_t nameSize = strlen(name) + 1;
+	_name = new char [nameSize];
+	Common::strcpy_s(_name, nameSize, name);
 }
 
 } // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_object.cpp b/engines/wintermute/base/base_object.cpp
index b6f225d95e9..28fc54f39f2 100644
--- a/engines/wintermute/base/base_object.cpp
+++ b/engines/wintermute/base/base_object.cpp
@@ -182,11 +182,10 @@ void BaseObject::setCaption(const char *caption, int caseVal) {
 	}
 
 	delete[] _caption[caseVal - 1];
-	_caption[caseVal - 1] = new char[strlen(caption) + 1];
-	if (_caption[caseVal - 1]) {
-		strcpy(_caption[caseVal - 1], caption);
-		_gameRef->expandStringByStringTable(&_caption[caseVal - 1]);
-	}
+	size_t captionSize = strlen(caption) + 1;
+	_caption[caseVal - 1] = new char[captionSize];
+	Common::strcpy_s(_caption[caseVal - 1], captionSize, caption);
+	_gameRef->expandStringByStringTable(&_caption[caseVal - 1]);
 }
 
 
@@ -1353,10 +1352,9 @@ void BaseObject::setSoundEvent(const char *eventName) {
 	delete[] _soundEvent;
 	_soundEvent = nullptr;
 	if (eventName) {
-		_soundEvent = new char[strlen(eventName) + 1];
-		if (_soundEvent) {
-			strcpy(_soundEvent, eventName);
-		}
+		size_t soundEventSize = strlen(eventName) + 1;
+		_soundEvent = new char[soundEventSize];
+		Common::strcpy_s(_soundEvent, soundEventSize, eventName);
 	}
 }
 
diff --git a/engines/wintermute/base/base_parser.cpp b/engines/wintermute/base/base_parser.cpp
index 527533fe4c1..95b7aea222a 100644
--- a/engines/wintermute/base/base_parser.cpp
+++ b/engines/wintermute/base/base_parser.cpp
@@ -43,8 +43,8 @@ namespace Wintermute {
 
 //////////////////////////////////////////////////////////////////////
 BaseParser::BaseParser() {
-	_whiteSpace = new char [strlen(WHITESPACE) + 1];
-	strcpy(_whiteSpace, WHITESPACE);
+	_whiteSpace = new char [sizeof(WHITESPACE)];
+	Common::strcpy_s(_whiteSpace, sizeof(WHITESPACE), WHITESPACE);
 }
 
 
@@ -93,7 +93,7 @@ int32 BaseParser::getObject(char **buf, const TokenDesc *tokens, char **name, ch
 		if (p && p > *buf) {
 			strncpy(_lastOffender, *buf, MIN((uint32)255, (uint32)(p - *buf))); // TODO, clean
 		} else {
-			strcpy(_lastOffender, "");
+			_lastOffender[0] = '\0';
 		}
 
 		return PARSERR_TOKENNOTFOUND;
@@ -388,7 +388,9 @@ int32 BaseParser::scanStr(const char *in, const char *format, ...) {
 						Common::strlcpy(a, in, (int)(in2 - in) + 1);
 						in = in2 + 1;
 					} else {
-						strcpy(a, in);
+						// FIXME: Use a sensible value here
+						// Happily this is not used
+						Common::strcpy_s(a, 4096, in);
 						in = strchr(in, 0);
 					}
 				} else {
diff --git a/engines/wintermute/base/base_script_holder.cpp b/engines/wintermute/base/base_script_holder.cpp
index 2f0afbc4a7f..81b247e4f5f 100644
--- a/engines/wintermute/base/base_script_holder.cpp
+++ b/engines/wintermute/base/base_script_holder.cpp
@@ -76,10 +76,9 @@ void BaseScriptHolder::setFilename(const char *filename) {
 	if (filename == nullptr) {
 		return;
 	}
-	_filename = new char [strlen(filename) + 1];
-	if (_filename != nullptr) {
-		strcpy(_filename, filename);
-	}
+	size_t filenameSize = strlen(filename) + 1;
+	_filename = new char [filenameSize];
+	Common::strcpy_s(_filename, filenameSize, filename);
 }
 
 
@@ -316,8 +315,9 @@ bool BaseScriptHolder::addScript(const char *filename) {
 #else
 			scr = new ScScript(_gameRef,  _gameRef->_scEngine);
 #endif
-			scr->_filename = new char[strlen(filename) + 1];
-			strcpy(scr->_filename, filename);
+			size_t filenameSize = strlen(filename) + 1;
+			scr->_filename = new char[filenameSize];
+			Common::strcpy_s(scr->_filename, filenameSize, filename);
 			scr->_state = SCRIPT_ERROR;
 			scr->_owner = this;
 			_scripts.add(scr);
@@ -397,26 +397,20 @@ bool BaseScriptHolder::parseProperty(char *buffer, bool complete) {
 
 	while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
 		switch (cmd) {
-		case TOKEN_NAME:
+		case TOKEN_NAME: {
 			delete[] propName;
-			propName = new char[strlen(params) + 1];
-			if (propName) {
-				strcpy(propName, params);
-			} else {
-				cmd = PARSERR_GENERIC;
-			}
+			size_t propNameSize = strlen(params) + 1;
+			propName = new char[propNameSize];
+			Common::strcpy_s(propName, propNameSize, params);
 			break;
-
-		case TOKEN_VALUE:
+		}
+		case TOKEN_VALUE: {
 			delete[] propValue;
-			propValue = new char[strlen(params) + 1];
-			if (propValue) {
-				strcpy(propValue, params);
-			} else {
-				cmd = PARSERR_GENERIC;
-			}
+			size_t propValueSize = strlen(params) + 1;
+			propValue = new char[propValueSize];
+			Common::strcpy_s(propValue, propValueSize, params);
 			break;
-
+		}
 		default:
 			break;
 		}
@@ -494,14 +488,14 @@ ScScript *BaseScriptHolder::invokeMethodThread(const char *methodName) {
 
 //////////////////////////////////////////////////////////////////////////
 void BaseScriptHolder::scDebuggerDesc(char *buf, int bufSize) {
-	strcpy(buf, scToString());
+	Common::strcpy_s(buf, bufSize, scToString());
 	if (getName() && strcmp(getName(), "<unnamed>") != 0) {
-		strcat(buf, "  Name: ");
-		strcat(buf, getName());
+		Common::strcat_s(buf, bufSize, "  Name: ");
+		Common::strcat_s(buf, bufSize, getName());
 	}
 	if (_filename) {
-		strcat(buf, "  File: ");
-		strcat(buf, _filename);
+		Common::strcat_s(buf, bufSize, "  File: ");
+		Common::strcat_s(buf, bufSize, _filename);
 	}
 }
 
diff --git a/engines/wintermute/base/base_scriptable.cpp b/engines/wintermute/base/base_scriptable.cpp
index 3d0ac927a75..b8ca42338da 100644
--- a/engines/wintermute/base/base_scriptable.cpp
+++ b/engines/wintermute/base/base_scriptable.cpp
@@ -173,7 +173,7 @@ int BaseScriptable::scCompare(BaseScriptable *val) {
 
 //////////////////////////////////////////////////////////////////////////
 void BaseScriptable::scDebuggerDesc(char *buf, int bufSize) {
-	strcpy(buf, scToString());
+	Common::strcpy_s(buf, bufSize, scToString());
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/engines/wintermute/base/base_sprite.cpp b/engines/wintermute/base/base_sprite.cpp
index c1d4a9e515c..73fab410bfa 100644
--- a/engines/wintermute/base/base_sprite.cpp
+++ b/engines/wintermute/base/base_sprite.cpp
@@ -281,10 +281,9 @@ bool BaseSprite::loadBuffer(char *buffer, bool complete, int lifeTime, TSpriteCa
 		case TOKEN_EDITOR_BG_FILE:
 			if (_gameRef->_editorMode) {
 				delete[] _editorBgFile;
-				_editorBgFile = new char[strlen(params) + 1];
-				if (_editorBgFile) {
-					strcpy(_editorBgFile, params);
-				}
+				size_t editorBgFileSize = strlen(params) + 1;
+				_editorBgFile = new char[editorBgFileSize];
+				Common::strcpy_s(_editorBgFile, editorBgFileSize, params);
 			}
 			break;
 
diff --git a/engines/wintermute/base/base_string_table.cpp b/engines/wintermute/base/base_string_table.cpp
index 77ad7c9d070..cad4c21e55d 100644
--- a/engines/wintermute/base/base_string_table.cpp
+++ b/engines/wintermute/base/base_string_table.cpp
@@ -92,8 +92,9 @@ char *BaseStringTable::getKey(const char *str) const {
 
 	StringsIter it = _strings.find(key);
 	if (it != _strings.end()) {
-		newStr = new char[it->_value.size() + 1];
-		strcpy(newStr, it->_value.c_str());
+		size_t newStrSize = it->_value.size() + 1;
+		newStr = new char[newStrSize];
+		Common::strcpy_s(newStr, newStrSize, it->_value.c_str());
 		if (strlen(newStr) > 0 && newStr[0] == '/' && strchr(newStr + 1, '/')) {
 			delete[] key;
 			char *ret = getKey(newStr);
@@ -130,11 +131,13 @@ void BaseStringTable::expand(char **str) const {
 
 	StringsIter it = _strings.find(key);
 	if (it != _strings.end()) {
-		newStr = new char[it->_value.size() + 1];
-		strcpy(newStr, it->_value.c_str());
+		size_t newStrSize = it->_value.size() + 1;
+		newStr = new char[newStrSize];
+		Common::strcpy_s(newStr, newStrSize, it->_value.c_str());
 	} else {
-		newStr = new char[strlen(value) + 1];
-		strcpy(newStr, value);
+		size_t newStrSize = strlen(value) + 1;
+		newStr = new char[newStrSize];
+		Common::strcpy_s(newStr, newStrSize, value);
 	}
 
 	delete[] key;
@@ -149,7 +152,7 @@ void BaseStringTable::expand(char **str) const {
 //////////////////////////////////////////////////////////////////////////
 void BaseStringTable::expand(Common::String &str) const {
 	char *tmp = new char[str.size() + 1];
-	strcpy(tmp, str.c_str());
+	Common::strcpy_s(tmp, str.size() + 1, str.c_str());
 	expand(&tmp);
 	str = tmp;
 	delete[] tmp;
diff --git a/engines/wintermute/base/base_sub_frame.cpp b/engines/wintermute/base/base_sub_frame.cpp
index 6a4c06c37d9..c9b288500aa 100644
--- a/engines/wintermute/base/base_sub_frame.cpp
+++ b/engines/wintermute/base/base_sub_frame.cpp
@@ -685,7 +685,7 @@ bool BaseSubFrame::setSurface(const Common::String &filename, bool defaultCK, by
 	_surface = _gameRef->_surfaceStorage->addSurface(filename, defaultCK, ckRed, ckGreen, ckBlue, lifeTime, keepLoaded);
 	if (_surface) {
 		_surfaceFilename = new char[filename.size() + 1];
-		strcpy(_surfaceFilename, filename.c_str());
+		Common::strcpy_s(_surfaceFilename, filename.size() + 1, filename.c_str());
 
 		_cKDefault = defaultCK;
 		_cKRed = ckRed;
diff --git a/engines/wintermute/base/file/base_save_thumb_file.cpp b/engines/wintermute/base/file/base_save_thumb_file.cpp
index 7cea342ae90..a9016e5d691 100644
--- a/engines/wintermute/base/file/base_save_thumb_file.cpp
+++ b/engines/wintermute/base/file/base_save_thumb_file.cpp
@@ -55,8 +55,9 @@ bool BaseSaveThumbFile::open(const Common::String &filename) {
 		return STATUS_FAILED;
 	}
 
-	char *tempFilename = new char[strlen(filename.c_str()) - 8];
-	strcpy(tempFilename, filename.c_str() + 9);
+	size_t filenameSize = strlen(filename.c_str()) - 9 + 1;
+	char *tempFilename = new char[filenameSize];
+	Common::strcpy_s(tempFilename, filenameSize, filename.c_str() + 9);
 	for (uint32 i = 0; i < strlen(tempFilename); i++) {
 		if (tempFilename[i] < '0' || tempFilename[i] > '9') {
 			tempFilename[i] = '\0';
diff --git a/engines/wintermute/base/gfx/xmodel.cpp b/engines/wintermute/base/gfx/xmodel.cpp
index fef8a356e13..4e3cb6cd52a 100644
--- a/engines/wintermute/base/gfx/xmodel.cpp
+++ b/engines/wintermute/base/gfx/xmodel.cpp
@@ -223,7 +223,7 @@ bool XModel::mergeFromFile(const Common::String &filename) {
 	}
 	if (!found) {
 		char *path = new char[filename.size() + 1];
-		strcpy(path, filename.c_str());
+		Common::strcpy_s(path, filename.size() + 1, filename.c_str());
 		_mergedModels.add(path);
 	}
 
diff --git a/engines/wintermute/base/particles/part_emitter.cpp b/engines/wintermute/base/particles/part_emitter.cpp
index d89b13254e5..21826610104 100644
--- a/engines/wintermute/base/particles/part_emitter.cpp
+++ b/engines/wintermute/base/particles/part_emitter.cpp
@@ -136,8 +136,9 @@ bool PartEmitter::addSprite(const char *filename) {
 		BaseFileManager::getEngineInstance()->closeFile(File);
 	}
 
-	char *str = new char[strlen(filename) + 1];
-	strcpy(str, filename);
+	size_t filenameSize = strlen(filename) + 1;
+	char *str = new char[filenameSize];
+	Common::strcpy_s(str, filenameSize, filename);
 	_sprites.add(str);
 
 	return STATUS_OK;
diff --git a/engines/wintermute/base/scriptables/script.cpp b/engines/wintermute/base/scriptables/script.cpp
index 5b8b71fffa8..27822053cf7 100644
--- a/engines/wintermute/base/scriptables/script.cpp
+++ b/engines/wintermute/base/scriptables/script.cpp
@@ -258,10 +258,9 @@ bool ScScript::create(const char *filename, byte *buffer, uint32 size, BaseScrip
 	delete[] _threadEvent;
 	_threadEvent = nullptr;
 
-	_filename = new char[strlen(filename) + 1];
-	if (_filename) {
-		strcpy(_filename, filename);
-	}
+	size_t filenameSize = strlen(filename) + 1;
+	_filename = new char[filenameSize];
+	Common::strcpy_s(_filename, filenameSize, filename);
 
 	_buffer = new byte [size];
 	if (!_buffer) {
@@ -293,21 +292,15 @@ bool ScScript::createThread(ScScript *original, uint32 initIP, const Common::Str
 	_thread = true;
 	_methodThread = false;
 	_threadEvent = new char[eventName.size() + 1];
-	if (_threadEvent) {
-		strcpy(_threadEvent, eventName.c_str());
-	}
+	Common::strcpy_s(_threadEvent, eventName.size() + 1, eventName.c_str());
 
 	// copy filename
-	_filename = new char[strlen(original->_filename) + 1];
-	if (_filename) {
-		strcpy(_filename, original->_filename);
-	}
+	size_t filenameSize = strlen(original->_filename) + 1;
+	_filename = new char[filenameSize];
+	Common::strcpy_s(_filename, filenameSize, original->_filename);
 
 	// copy buffer
 	_buffer = new byte [original->_bufferSize];
-	if (!_buffer) {
-		return STATUS_FAILED;
-	}
 
 	memcpy(_buffer, original->_buffer, original->_bufferSize);
 	_bufferSize = original->_bufferSize;
@@ -350,21 +343,15 @@ bool ScScript::createMethodThread(ScScript *original, const Common::String &meth
 	_thread = true;
 	_methodThread = true;
 	_threadEvent = new char[methodName.size() + 1];
-	if (_threadEvent) {
-		strcpy(_threadEvent, methodName.c_str());
-	}
+	Common::strcpy_s(_threadEvent, methodName.size() + 1, methodName.c_str());
 
 	// copy filename
-	_filename = new char[strlen(original->_filename) + 1];
-	if (_filename) {
-		strcpy(_filename, original->_filename);
-	}
+	size_t filenameSize = strlen(original->_filename) + 1;
+	_filename = new char[filenameSize];
+	Common::strcpy_s(_filename, filenameSize, original->_filename);
 
 	// copy buffer
 	_buffer = new byte [original->_bufferSize];
-	if (!_buffer) {
-		return STATUS_FAILED;
-	}
 
 	memcpy(_buffer, original->_buffer, original->_bufferSize);
 	_bufferSize = original->_bufferSize;
@@ -640,8 +627,9 @@ bool ScScript::executeInstruction() {
 		// push var
 		// push string
 		str = _stack->pop()->getString();
-		char *methodName = new char[strlen(str) + 1];
-		strcpy(methodName, str);
+		size_t methodNameSize = strlen(str) + 1;
+		char *methodName = new char[methodNameSize];
+		Common::strcpy_s(methodName, methodNameSize, str);
 
 		ScValue *var = _stack->pop();
 		if (var->_type == VAL_VARIABLE_REF) {
@@ -893,9 +881,10 @@ bool ScScript::executeInstruction() {
 		if (op1->isNULL() || op2->isNULL()) {
 			_operand->setNULL();
 		} else if (op1->getType() == VAL_STRING || op2->getType() == VAL_STRING) {
-			char *tempStr = new char [strlen(op1->getString()) + strlen(op2->getString()) + 1];
-			strcpy(tempStr, op1->getString());
-			strcat(tempStr, op2->getString());
+			size_t tempStrSize = strlen(op1->getString()) + strlen(op2->getString()) + 1;
+			char *tempStr = new char [tempStrSize];
+			Common::strcpy_s(tempStr, tempStrSize, op1->getString());
+			Common::strcat_s(tempStr, tempStrSize, op2->getString());
 			_operand->setString(tempStr);
 			delete[] tempStr;
 		} else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) {
diff --git a/engines/wintermute/base/scriptables/script_ext_array.cpp b/engines/wintermute/base/scriptables/script_ext_array.cpp
index 75edbb4d4e6..7ebf44d4041 100644
--- a/engines/wintermute/base/scriptables/script_ext_array.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_array.cpp
@@ -75,19 +75,19 @@ SXArray::~SXArray() {
 //////////////////////////////////////////////////////////////////////////
 const char *SXArray::scToString() {
 	char dummy[32768];
-	strcpy(dummy, "");
+	dummy[0] = '\0';
 	char propName[20];
 	for (int i = 0; i < _length; i++) {
 		sprintf(propName, "%d", i);
 		ScValue *val = _values->getProp(propName);
 		if (val) {
 			if (strlen(dummy) + strlen(val->getString()) < 32768) {
-				strcat(dummy, val->getString());
+				Common::strcat_s(dummy, val->getString());
 			}
 		}
 
 		if (i < _length - 1 && strlen(dummy) + 1 < 32768) {
-			strcat(dummy, ",");
+			Common::strcat_s(dummy, ",");
 		}
 	}
 	_strRep = dummy;
diff --git a/engines/wintermute/base/scriptables/script_ext_string.cpp b/engines/wintermute/base/scriptables/script_ext_string.cpp
index ab7892685db..11b2197dc82 100644
--- a/engines/wintermute/base/scriptables/script_ext_string.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_string.cpp
@@ -83,7 +83,7 @@ void SXString::setStringVal(const char *val) {
 		_string = nullptr;
 		_string = new char[_capacity]();
 	}
-	strcpy(_string, val);
+	Common::strcpy_s(_string, _capacity, val);
 }
 
 
@@ -396,7 +396,7 @@ bool SXString::scSetProperty(const char *name, ScValue *value) {
 		} else if (newCap != _capacity) {
 			char *newStr = new char[newCap]();
 			if (newStr) {
-				strcpy(newStr, _string);
+				Common::strcpy_s(newStr, newCap, _string);
 				delete[] _string;
 				_string = newStr;
 				_capacity = newCap;
diff --git a/engines/wintermute/base/scriptables/script_value.cpp b/engines/wintermute/base/scriptables/script_value.cpp
index aae01f5210e..2cca3923bf6 100644
--- a/engines/wintermute/base/scriptables/script_value.cpp
+++ b/engines/wintermute/base/scriptables/script_value.cpp
@@ -448,20 +448,16 @@ void ScValue::setString(const Common::String &val) {
 
 //////////////////////////////////////////////////////////////////////////
 void ScValue::setStringVal(const char *val) {
-	if (_valString) {
-		delete[] _valString;
-		_valString = nullptr;
-	}
+	delete[] _valString;
+	_valString = nullptr;
 
 	if (val == nullptr) {
-		_valString = nullptr;
 		return;
 	}
 
-	_valString = new char [strlen(val) + 1];
-	if (_valString) {
-		strcpy(_valString, val);
-	}
+	size_t valSize = strlen(val) + 1;
+	_valString = new char[valSize];
+	Common::strcpy_s(_valString, valSize, val);
 }
 
 
diff --git a/engines/wintermute/ui/ui_edit.cpp b/engines/wintermute/ui/ui_edit.cpp
index 9e533d82d18..a3a142293fb 100644
--- a/engines/wintermute/ui/ui_edit.cpp
+++ b/engines/wintermute/ui/ui_edit.cpp
@@ -559,10 +559,9 @@ void UIEdit::setCursorChar(const char *character) {
 		return;
 	}
 	delete[] _cursorChar;
-	_cursorChar = new char [strlen(character) + 1];
-	if (_cursorChar) {
-		strcpy(_cursorChar, character);
-	}
+	size_t cursorCharSize = strlen(character) + 1;
+	_cursorChar = new char [cursorCharSize];
+	Common::strcpy_s(_cursorChar, cursorCharSize, character);
 }
 
 
diff --git a/engines/wintermute/ui/ui_object.cpp b/engines/wintermute/ui/ui_object.cpp
index c1aff162d7d..6a6defdbf39 100644
--- a/engines/wintermute/ui/ui_object.cpp
+++ b/engines/wintermute/ui/ui_object.cpp
@@ -99,13 +99,12 @@ void UIObject::setText(const char *text) {
 	if (_text) {
 		delete[] _text;
 	}
-	_text = new char [strlen(text) + 1];
-	if (_text) {
-		strcpy(_text, text);
-		for (uint32 i = 0; i < strlen(_text); i++) {
-			if (_text[i] == '|') {
-				_text[i] = '\n';
-			}
+	size_t textSize = strlen(text) + 1;
+	_text = new char [textSize];
+	Common::strcpy_s(_text, textSize, text);
+	for (uint32 i = 0; i < strlen(_text); i++) {
+		if (_text[i] == '|') {
+			_text[i] = '\n';
 		}
 	}
 }
diff --git a/engines/wintermute/utils/utils.cpp b/engines/wintermute/utils/utils.cpp
index ca641836204..0a1378b217b 100644
--- a/engines/wintermute/utils/utils.cpp
+++ b/engines/wintermute/utils/utils.cpp
@@ -92,10 +92,9 @@ void BaseUtils::debugMessage(const char *text) {
 //////////////////////////////////////////////////////////////////////////
 char *BaseUtils::setString(char **string, const char *value) {
 	delete[] *string;
-	*string = new char[strlen(value) + 1];
-	if (*string) {
-		strcpy(*string, value);
-	}
+	size_t stringSize = strlen(value) + 1;
+	*string = new char[stringSize];
+	Common::strcpy_s(*string, stringSize, value);
 	return *string;
 }
 


Commit: 1808493909ba0c0ba44e87d635f66af1e44f60cf
    https://github.com/scummvm/scummvm/commit/1808493909ba0c0ba44e87d635f66af1e44f60cf
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
XEEN: Don't use unsafe strcat and strcpy

Changed paths:
    engines/xeen/resources.h


diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index ab0bd81bd9d..6fe635a8aad 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -51,9 +51,10 @@ class Resources {
 
 		void syncString(const char *&str) {
 			str = _buffer;
-			strcpy(_buffer, readString().c_str());
-			_buffer += strlen(_buffer) + 1;
-			assert((_buffer - _buffStart) < STRING_BUFFER_SIZE);
+			size_t available = STRING_BUFFER_SIZE - (_buffer - _buffStart);
+			size_t ln = Common::strlcpy(_buffer, readString().c_str(), available);
+			assert(available > ln);
+			_buffer += ln + 1;
 		}
 		void syncStrings(const char **str, int count) {
 			uint tag = readUint32LE();


Commit: 523ed4a34d48a62caec019e1f05af718a6d821a6
    https://github.com/scummvm/scummvm/commit/523ed4a34d48a62caec019e1f05af718a6d821a6
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
ZVISION: Don't use unsafe strcat and strcpy

Changed paths:
    engines/zvision/scripting/actions.cpp


diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index c3a5570da27..ead33a0f37f 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -462,7 +462,7 @@ ActionMusic::ActionMusic(ZVision *engine, int32 slotKey, const Common::String &l
 	char volumeBuffer[15];
 
 	// Volume is optional. If it doesn't appear, assume full volume
-	strcpy(volumeBuffer, "100");
+	Common::strcpy_s(volumeBuffer, "100");
 
 	sscanf(line.c_str(), "%u %24s %u %14s", &type, fileNameBuffer, &loop, volumeBuffer);
 
@@ -485,7 +485,7 @@ ActionMusic::ActionMusic(ZVision *engine, int32 slotKey, const Common::String &l
 			// I thought I saw a case like this in Zork Nemesis, so
 			// let's guard against it.
 			warning("ActionMusic: Adjusting volume for %s from %s to 100", _fileName.c_str(), volumeBuffer);
-			strcpy(volumeBuffer, "100");
+			Common::strcpy_s(volumeBuffer, "100");
 		}
 		_volume = new ValueSlot(_scriptManager, volumeBuffer);
 	}


Commit: 5a0e4ced6712fe1c48adbc49cd47ca7f118ff21e
    https://github.com/scummvm/scummvm/commit/5a0e4ced6712fe1c48adbc49cd47ca7f118ff21e
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
AMIGAOS: Don't use unsafe strcat and strcpy

Changed paths:
    backends/dialogs/amigaos/amigaos-dialogs.cpp
    backends/fs/amigaos/amigaos-fs.cpp


diff --git a/backends/dialogs/amigaos/amigaos-dialogs.cpp b/backends/dialogs/amigaos/amigaos-dialogs.cpp
index 2680e247245..cf9d32fc5d0 100644
--- a/backends/dialogs/amigaos/amigaos-dialogs.cpp
+++ b/backends/dialogs/amigaos/amigaos-dialogs.cpp
@@ -41,7 +41,7 @@ struct Library *AslBase;
 Common::DialogManager::DialogResult AmigaOSDialogManager::showFileBrowser(const Common::U32String &title, Common::FSNode &choice, bool isDirBrowser) {
 
 	char pathBuffer[MAXPATHLEN];
-	strcpy(pathBuffer, "SYS:");
+	Common::strcpy_s(pathBuffer, "SYS:");
 
 	Common::String newTitle = title.encode(Common::kISO8859_1);
 
diff --git a/backends/fs/amigaos/amigaos-fs.cpp b/backends/fs/amigaos/amigaos-fs.cpp
index 5c11c9f9409..dfe87c008b9 100644
--- a/backends/fs/amigaos/amigaos-fs.cpp
+++ b/backends/fs/amigaos/amigaos-fs.cpp
@@ -314,9 +314,10 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const {
 			IDOS->CopyStringBSTRToC(dosList->dol_Name, buffer, MAXPATHLEN);
 
 			// Volume name + '\0'
-			char *volName = new char [strlen(buffer) + 1];
-			strcpy(volName, buffer);
-			strcat(buffer, ":");
+			size_t volNameSize = strlen(buffer) + 1;
+			char *volName = new char [volNameSize];
+			Common::strcpy_s(volName, volNameSize, buffer);
+			Common::strcat_s(buffer, ":");
 
 			BPTR volumeLock = IDOS->Lock((STRPTR)buffer, SHARED_LOCK);
 			if (volumeLock) {


Commit: 6f5ac54828965b5c3b1cf4337954c925c99f4494
    https://github.com/scummvm/scummvm/commit/6f5ac54828965b5c3b1cf4337954c925c99f4494
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
DC: Don't use unsafe strcat and strcpy

Changed paths:
    backends/platform/dc/dcloader.cpp
    backends/platform/dc/plugins.cpp
    backends/platform/dc/selector.cpp
    backends/platform/dc/vmsave.cpp


diff --git a/backends/platform/dc/dcloader.cpp b/backends/platform/dc/dcloader.cpp
index c2ab4edac44..f4ef0d1f487 100644
--- a/backends/platform/dc/dcloader.cpp
+++ b/backends/platform/dc/dcloader.cpp
@@ -415,7 +415,7 @@ int dlclose(void *handle)
 {
   DLObject *obj = (DLObject *)handle;
   if (obj == NULL) {
-	strcpy(dlerr, "Handle is NULL.");
+	Common::strcpy_s(dlerr, "Handle is NULL.");
 	return -1;
   }
   if (obj->close()) {
@@ -428,7 +428,7 @@ int dlclose(void *handle)
 void *dlsym(void *handle, const char *symbol)
 {
   if (handle == NULL) {
-	strcpy(dlerr, "Handle is NULL.");
+	Common::strcpy_s(dlerr, "Handle is NULL.");
 	return NULL;
   }
   return ((DLObject *)handle)->symbol(symbol);
diff --git a/backends/platform/dc/plugins.cpp b/backends/platform/dc/plugins.cpp
index c3f0550c401..38dbb6fc691 100644
--- a/backends/platform/dc/plugins.cpp
+++ b/backends/platform/dc/plugins.cpp
@@ -126,9 +126,9 @@ void OSystem_Dreamcast::DCPlugin::checkDisc(const DiscLabel &target)
 	return;
 
     char buf[32+24];
-    strcpy(buf, "Please insert disc '");
+    Common::strcpy_s(buf, "Please insert disc '");
     target.get(buf+strlen(buf));
-    strcat(buf, "'");
+    Common::strcat_s(buf, "'");
     DiscSwap(buf, 0xffffffff).run();
   }
 }
diff --git a/backends/platform/dc/selector.cpp b/backends/platform/dc/selector.cpp
index 73077941902..f8c3f2e3643 100644
--- a/backends/platform/dc/selector.cpp
+++ b/backends/platform/dc/selector.cpp
@@ -145,14 +145,14 @@ static int findGames(Game *games, int max, bool use_ini)
 	dirs[j = num_dirs++].node = Common::FSNode(path);
 	  }
 	  if (curr_game < max) {
-	strcpy(games[curr_game].filename_base, (*i)._key.c_str());
+	Common::strcpy_s(games[curr_game].filename_base, (*i)._key.c_str());
 	strncpy(games[curr_game].engine_id, (*i)._value["engineid"].c_str(), 256);
 	games[curr_game].engine_id[255] = '\0';
 	strncpy(games[curr_game].dir, dirs[j].node.getPath().c_str(), 256);
 	games[curr_game].dir[255] = '\0';
 	games[curr_game].language = Common::UNK_LANG;
 	games[curr_game].platform = Common::kPlatformUnknown;
-	strcpy(games[curr_game].text, (*i)._value["description"].c_str());
+	Common::strcpy_s(games[curr_game].text, (*i)._value["description"].c_str());
 	curr_game++;
 	  }
 	}
@@ -165,7 +165,7 @@ static int findGames(Game *games, int max, bool use_ini)
 	dirs[curr_dir].name[250] = '\0';
 	if (!dirs[curr_dir].name[0] ||
 	dirs[curr_dir].name[strlen(dirs[curr_dir].name)-1] != '/')
-	  strcat(dirs[curr_dir].name, "/");
+	  Common::strcat_s(dirs[curr_dir].name, "/");
 	dirs[curr_dir].deficon[0] = '\0';
 	Common::FSList files, fslist;
 	dirs[curr_dir++].node.getChildren(fslist, Common::FSNode::kListAll);
@@ -181,7 +181,7 @@ static int findGames(Game *games, int max, bool use_ini)
 	  files.push_back(*entry);
 	  } else
 	if (isIcon(*entry))
-	  strcpy(dirs[curr_dir-1].deficon, entry->getName().c_str());
+	  Common::strcpy_s(dirs[curr_dir-1].deficon, entry->getName().c_str());
 	else if(!use_ini)
 	  files.push_back(*entry);
 	}
@@ -193,9 +193,9 @@ static int findGames(Game *games, int max, bool use_ini)
 	  for (DetectedGames::const_iterator ge = candidates.begin();
 	   ge != candidates.end(); ++ge)
 	if (curr_game < max) {
-	  strcpy(games[curr_game].engine_id, ge->engineId.c_str());
-	  strcpy(games[curr_game].filename_base, ge->gameId.c_str());
-	  strcpy(games[curr_game].dir, dirs[curr_dir-1].name);
+	  Common::strcpy_s(games[curr_game].engine_id, ge->engineId.c_str());
+	  Common::strcpy_s(games[curr_game].filename_base, ge->gameId.c_str());
+	  Common::strcpy_s(games[curr_game].dir, dirs[curr_dir-1].name);
 	  games[curr_game].language = ge->language;
 	  games[curr_game].platform = ge->platform;
 	  if (uniqueGame(games[curr_game].filename_base,
@@ -203,7 +203,7 @@ static int findGames(Game *games, int max, bool use_ini)
 			 games[curr_game].language,
 			 games[curr_game].platform, games, curr_game)) {
 
-	    strcpy(games[curr_game].text, ge->description.c_str());
+	    Common::strcpy_s(games[curr_game].text, ge->description.c_str());
 #if 0
 	    printf("Registered game <%s> (l:%d p:%d) in <%s> <%s> because of <%s> <*>\n",
 		   games[curr_game].text,
diff --git a/backends/platform/dc/vmsave.cpp b/backends/platform/dc/vmsave.cpp
index 1a7538a50eb..458677b5265 100644
--- a/backends/platform/dc/vmsave.cpp
+++ b/backends/platform/dc/vmsave.cpp
@@ -54,16 +54,16 @@ static void displaySaveResult(vmsaveResult res)
 	sprintf(buf, "Game saved on unit %c%d", 'A'+(lastvm/6), lastvm%6);
 	break;
   case VMSAVE_NOVM:
-	strcpy(buf, "No memory card present!");
+	Common::strcpy_s(buf, "No memory card present!");
 	break;
   case VMSAVE_NOSPACE:
-	strcpy(buf, "Not enough space available!");
+	Common::strcpy_s(buf, "Not enough space available!");
 	break;
   case VMSAVE_WRITEERROR:
-	strcpy(buf, "Write error!!!");
+	Common::strcpy_s(buf, "Write error!!!");
 	break;
   default:
-	strcpy(buf, "Unknown error!!!");
+	Common::strcpy_s(buf, "Unknown error!!!");
 	break;
   }
 


Commit: 15e7346f1c53438efb62e403ee41710cf93eb2de
    https://github.com/scummvm/scummvm/commit/15e7346f1c53438efb62e403ee41710cf93eb2de
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
MORPHOS: Don't use unsafe strcat and strcpy

Changed paths:
    backends/fs/morphos/morphos-fs.cpp


diff --git a/backends/fs/morphos/morphos-fs.cpp b/backends/fs/morphos/morphos-fs.cpp
index 143559948d3..5ab22c7ad11 100644
--- a/backends/fs/morphos/morphos-fs.cpp
+++ b/backends/fs/morphos/morphos-fs.cpp
@@ -318,8 +318,8 @@ AbstractFSList MorphOSFilesystemNode::listVolumes() const {
 			CONST_STRPTR devName = (CONST_STRPTR)((struct Task *)dosList->dol_Task->mp_SigTask)->tc_Node.ln_Name;
 			BPTR volumeLock;
 
-			strcpy(buffer, volName);
-			strcat(buffer, ":");
+			Common::strcpy_s(buffer, volName);
+			Common::strcat_s(buffer, ":");
 
 			volumeLock = Lock(buffer, SHARED_LOCK);
 			if (volumeLock) {


Commit: 7c657796f488fb8555cc63e9653a61498b570888
    https://github.com/scummvm/scummvm/commit/7c657796f488fb8555cc63e9653a61498b570888
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
POSIX: Don't use unsafe strcat and strcpy

It was commented but still

Changed paths:
    backends/fs/posix/posix-fs.cpp


diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp
index 6d55fa3b71f..dae604bcf89 100644
--- a/backends/fs/posix/posix-fs.cpp
+++ b/backends/fs/posix/posix-fs.cpp
@@ -121,7 +121,7 @@ POSIXFilesystemNode::POSIXFilesystemNode(const Common::String &p) {
 	if (!_path.hasPrefix("/")) {
 		char buf[MAXPATHLEN+1];
 		getcwd(buf, MAXPATHLEN);
-		strcat(buf, "/");
+		Common::strcat_s(buf, "/");
 		_path = buf + _path;
 	}
 #endif


Commit: a3cc6b5218c54c5a670585ca6988cb1c48304c88
    https://github.com/scummvm/scummvm/commit/a3cc6b5218c54c5a670585ca6988cb1c48304c88
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
TIMIDITY: Don't use unsafe strcat and strcpy

Changed paths:
    backends/midi/timidity.cpp


diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp
index 11f75d7d581..2014e830cbb 100644
--- a/backends/midi/timidity.cpp
+++ b/backends/midi/timidity.cpp
@@ -331,7 +331,7 @@ char *MidiDriver_TIMIDITY::timidity_ctl_command(const char *fmt, ...) {
 	while (1) {
 		/* read reply */
 		if (fdgets(buff, sizeof(buff)) <= 0) {
-			strcpy(buff, "Read error\n");
+			Common::strcpy_s(buff, "Read error\n");
 			break;
 		}
 


Commit: 387da5b820f5263a98006e2127d33ae3734d180e
    https://github.com/scummvm/scummvm/commit/387da5b820f5263a98006e2127d33ae3734d180e
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
WII: Don't use unsafe strcat and strcpy

Changed paths:
    backends/platform/wii/osystem.cpp


diff --git a/backends/platform/wii/osystem.cpp b/backends/platform/wii/osystem.cpp
index ee3b07b0819..4ba843a8aa1 100644
--- a/backends/platform/wii/osystem.cpp
+++ b/backends/platform/wii/osystem.cpp
@@ -131,7 +131,7 @@ void OSystem_Wii::initBackend() {
 
 	char buf[MAXPATHLEN];
 	if (!getcwd(buf, MAXPATHLEN))
-		strcpy(buf, "/");
+		Common::strcpy_s(buf, "/");
 
 	_savefileManager = new DefaultSaveFileManager(buf);
 	_timerManager = new DefaultTimerManager();


Commit: 6293c2b3c25dc2197a8b049aa42a3dd0694fda27
    https://github.com/scummvm/scummvm/commit/6293c2b3c25dc2197a8b049aa42a3dd0694fda27
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
WIN32: Don't use unsafe strcat and strcpy

Changed paths:
    backends/platform/sdl/win32/win32_wrapper.cpp
    backends/saves/windows/windows-saves.cpp
    backends/taskbar/win32/win32-taskbar.cpp


diff --git a/backends/platform/sdl/win32/win32_wrapper.cpp b/backends/platform/sdl/win32/win32_wrapper.cpp
index 6d32f096de2..e89d25c0ca3 100644
--- a/backends/platform/sdl/win32/win32_wrapper.cpp
+++ b/backends/platform/sdl/win32/win32_wrapper.cpp
@@ -19,6 +19,9 @@
  *
  */
 
+// For _tcscat
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
+
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <shellapi.h> // for CommandLineToArgvW()
@@ -171,7 +174,7 @@ char *unicodeToAnsi(const wchar_t *s) {
 TCHAR *stringToTchar(const Common::String& s) {
 #ifndef UNICODE
 	char *t = (char *)malloc(s.size() + 1);
-	strcpy(t, s.c_str());
+	Common::strcpy_s(t, s.size() + 1, s.c_str());
 	return t;
 #else
 	return ansiToUnicode(s.c_str());
diff --git a/backends/saves/windows/windows-saves.cpp b/backends/saves/windows/windows-saves.cpp
index 50d666b7d46..752529bd2f3 100644
--- a/backends/saves/windows/windows-saves.cpp
+++ b/backends/saves/windows/windows-saves.cpp
@@ -21,6 +21,9 @@
 
 #if defined(WIN32) && !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
 
+// For _tcscat
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
+
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <tchar.h>
diff --git a/backends/taskbar/win32/win32-taskbar.cpp b/backends/taskbar/win32/win32-taskbar.cpp
index 648423d4db3..ad2f1891bdf 100644
--- a/backends/taskbar/win32/win32-taskbar.cpp
+++ b/backends/taskbar/win32/win32-taskbar.cpp
@@ -19,6 +19,9 @@
  *
  */
 
+// For _tcscpy
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+
 // We cannot use common/scummsys.h directly as it will include
 // windows.h and we need to do it by hand to allow excluded functions
 #if defined(HAVE_CONFIG_H)


Commit: 9c04d724717a13d7854eb9c88c532197442758f8
    https://github.com/scummvm/scummvm/commit/9c04d724717a13d7854eb9c88c532197442758f8
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
COMMON: Forbid use of unsafe strcat and strcpy

Changed paths:
    backends/platform/sdl/sdl-sys.h
    common/forbidden.h
    common/lua/lobject.cpp
    common/lua/lstrlib.cpp
    common/str.cpp
    common/textconsole.cpp


diff --git a/backends/platform/sdl/sdl-sys.h b/backends/platform/sdl/sdl-sys.h
index 73703658543..12cc0b8c8ac 100644
--- a/backends/platform/sdl/sdl-sys.h
+++ b/backends/platform/sdl/sdl-sys.h
@@ -64,6 +64,16 @@
 #define mkdir FAKE_mkdir
 #endif
 
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_strcpy)
+#undef strcpy
+#define strcpy FAKE_strcpy
+#endif
+
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_strcat)
+#undef strcat
+#define strcat FAKE_strcat
+#endif
+
 // Fix compilation with MacPorts SDL 2
 // It needs various (usually forbidden) symbols from time.h
 #ifndef FORBIDDEN_SYMBOL_EXCEPTION_time_h
@@ -255,6 +265,16 @@
 #define mkdir(a,b) FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
 #endif
 
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_strcpy)
+#undef strcpy
+#define strcpy(a,b)    FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
+#endif
+
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_strcat)
+#undef strcat
+#define strcat(a,b)    FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
+#endif
+
 // re-forbid all those time.h symbols again (if they were forbidden)
 #ifndef FORBIDDEN_SYMBOL_EXCEPTION_time_h
 
diff --git a/common/forbidden.h b/common/forbidden.h
index b3148a2a941..b9663681b67 100644
--- a/common/forbidden.h
+++ b/common/forbidden.h
@@ -527,6 +527,18 @@
 #define srandom(a)	FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
 #endif
 
+// Use Common::strcat_s or Common::strlcat in common/str.h
+#ifndef FORBIDDEN_SYMBOL_EXCEPTION_strcat
+#undef strcat
+#define strcat(a,b)	FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
+#endif
+
+// Use Common::strcpy_s or Common::strlcpy in common/str.h
+#ifndef FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+#undef strcpy
+#define strcpy(a,b)	FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
+#endif
+
 // Use Common:scumm_stricmp in common/str.h
 #ifndef FORBIDDEN_SYMBOL_EXCEPTION_stricmp
 #undef stricmp
diff --git a/common/lua/lobject.cpp b/common/lua/lobject.cpp
index 1ffee525562..d34a15af24d 100644
--- a/common/lua/lobject.cpp
+++ b/common/lua/lobject.cpp
@@ -4,6 +4,9 @@
 ** See Copyright Notice in lua.h
 */
 
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
+
 #include "common/util.h"
 
 #define lobject_c
diff --git a/common/lua/lstrlib.cpp b/common/lua/lstrlib.cpp
index cad9c841d4f..341a2a4850c 100644
--- a/common/lua/lstrlib.cpp
+++ b/common/lua/lstrlib.cpp
@@ -4,6 +4,8 @@
 ** See Copyright Notice in lua.h
 */
 
+#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+
 #include "common/util.h"
 
 #define lstrlib_c
diff --git a/common/str.cpp b/common/str.cpp
index 08d0c4b9d13..d9b2d9c456e 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -1000,7 +1000,7 @@ char *scumm_strdup(const char *in) {
 	const size_t len = strlen(in) + 1;
 	char *out = (char *)malloc(len);
 	if (out) {
-		strcpy(out, in);
+		Common::strcpy_s(out, len, in);
 	}
 	return out;
 }
diff --git a/common/textconsole.cpp b/common/textconsole.cpp
index 43e249862ec..eb74c505a66 100644
--- a/common/textconsole.cpp
+++ b/common/textconsole.cpp
@@ -87,7 +87,7 @@ void NORETURN_PRE error(const char *s, ...) {
 	buf_output[STRINGBUFLEN - 3] = '\0';
 	buf_output[STRINGBUFLEN - 2] = '\0';
 	buf_output[STRINGBUFLEN - 1] = '\0';
-	strcat(buf_output, "!\n");
+	Common::strcat_s(buf_output, "!\n");
 
 	if (g_system)
 		g_system->logMessage(LogMessageType::kError, buf_output);


Commit: cd785e2208beb10d569499a3babc13dbb15acef1
    https://github.com/scummvm/scummvm/commit/cd785e2208beb10d569499a3babc13dbb15acef1
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
COMMON: Add sprintf_s and vsprintf_s

These functions will issue warnings and truncate strings.
It's like snprintf and vsnprintf but noisier.
There are also versions automatically determining size based on the destination
array size.
This raises a compilation error when the size cannot be determined by
the compiler.

Changed paths:
    common/str.cpp
    common/str.h


diff --git a/common/str.cpp b/common/str.cpp
index d9b2d9c456e..cbd87bbdc9c 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -818,6 +818,46 @@ void strcat_s(char *dst, size_t size, const char *src) {
 	dst[-1] = '\0';
 }
 
+int vsprintf_s(char *dst, size_t size, const char *format, va_list ap) {
+	if (!dst) {
+		warning("%s: dst is nullptr", __func__);
+		return 0;
+	}
+	if (!size) {
+		warning("%s: size is zero", __func__);
+		return 0;
+	}
+	if (!format) {
+		warning("%s: format is nullptr", __func__);
+		dst[0] = '\0';
+		return 0;
+	}
+
+	int ret = vsnprintf(dst, size, format, ap);
+
+	if ((size_t)ret < size
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+		&& ret != -1
+#endif
+		) {
+		// Nominal case: no truncation
+		return ret;
+	}
+
+	warning("%s: truncating string", __func__);
+	dst[size - 1] = '\0';
+	return size - 1;
+}
+
+int sprintf_s(char *dst, size_t size, const char *format, ...) {
+	int ret;
+	va_list ap;
+	va_start(ap, format);
+	ret = vsprintf_s(dst, size, format, ap);
+	va_end(ap);
+	return ret;
+}
+
 size_t strlcpy(char *dst, const char *src, size_t size) {
 	// Our backup of the source's start, we need this
 	// to calculate the source's length.
diff --git a/common/str.h b/common/str.h
index 78ff663d443..f5bc29399f2 100644
--- a/common/str.h
+++ b/common/str.h
@@ -431,6 +431,55 @@ FORCEINLINE void strcat_s(T (&dst)[N], const char *src) {
 	strcat_s((char *)dst, N, src);
 }
 
+/**
+ * A sprintf shim which warns when the buffer overruns and null terminates in this case
+ *
+ * @param dst Where the resulting string will be storeyyd.
+ * @param size The (total) size of the destination buffer.
+ * @param format The format string.
+ */
+int vsprintf_s(char *dst, size_t size, const char *format, va_list ap) GCC_PRINTF(3, 0);
+
+/**
+ * A sprintf shim which warns when the buffer overruns and null terminates in this case
+ * The size of the buffer is automatically determined.
+ *
+ * @param dst Where the resulting string will be storeyyd.
+ * @param format The format string.
+ */
+template<typename T, size_t N>
+FORCEINLINE GCC_PRINTF(2, 0) int vsprintf_s(T (&dst)[N], const char *format, va_list ap) {
+	STATIC_ASSERT(sizeof(T) == sizeof(char), T_is_not_compatible_with_char);
+	return vsprintf_s((char *)dst, N, format, ap);
+}
+
+/**
+ * A sprintf shim which warns when the buffer overruns and null terminates in this case
+ *
+ * @param dst Where the resulting string will be storeyyd.
+ * @param size The (total) size of the destination buffer.
+ * @param format The format string.
+ */
+int sprintf_s(char *dst, size_t size, MSVC_PRINTF const char *format, ...) GCC_PRINTF(3, 4);
+
+/**
+ * A sprintf shim which warns when the buffer overruns and null terminates in this case
+ * The size of the buffer is automatically determined.
+ *
+ * @param dst Where the resulting string will be storeyyd.
+ * @param format The format string.
+ */
+template<typename T, size_t N>
+inline GCC_PRINTF(2, 3) int sprintf_s(T (&dst)[N], MSVC_PRINTF const char *format, ...) {
+	STATIC_ASSERT(sizeof(T) == sizeof(char), T_is_not_compatible_with_char);
+	int ret;
+	va_list ap;
+	va_start(ap, format);
+	ret = vsprintf_s((char *)dst, N, format, ap);
+	va_end(ap);
+	return ret;
+}
+
 /**
  * Copy up to size - 1 characters from src to dst and also zero terminate the
  * result. Note that src must be a zero terminated string.


Commit: 94b8f3430250d52a64a37867bea6be9e9185f98a
    https://github.com/scummvm/scummvm/commit/94b8f3430250d52a64a37867bea6be9e9185f98a
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GRAPHICS: Don't use unsafe sprintf and vsprintf

Changed paths:
    graphics/opengl/shader.cpp


diff --git a/graphics/opengl/shader.cpp b/graphics/opengl/shader.cpp
index d622ef35181..df8c99a5c92 100644
--- a/graphics/opengl/shader.cpp
+++ b/graphics/opengl/shader.cpp
@@ -173,7 +173,7 @@ GLuint Shader::createCompatShader(const char *shaderSource, GLenum shaderType, c
 		return 0;
 	}
 
-	sprintf(versionSource, "#version %d\n", compatGLSLVersion);
+	Common::sprintf_s(versionSource, "#version %d\n", compatGLSLVersion);
 
 	const GLchar *compatSource =
 			shaderType == GL_VERTEX_SHADER ? compatVertex : compatFragment;


Commit: a91558aefd96be5ff0e7e1047803f571cd24eafd
    https://github.com/scummvm/scummvm/commit/a91558aefd96be5ff0e7e1047803f571cd24eafd
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
AGI: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/agi/detection.cpp
    engines/agi/graphics.cpp
    engines/agi/op_cmd.cpp
    engines/agi/preagi/mickey.cpp
    engines/agi/preagi/troll.cpp
    engines/agi/systemui.cpp
    engines/agi/text.cpp


diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 5200d65356a..263adc8342e 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -238,7 +238,7 @@ ADDetectedGame AgiMetaEngineDetection::fallbackDetect(const FileMap &allFilesXXX
 		bool agipal = false;
 		char agipalFile[] = "pal.xxx";
 		for (uint i = 100; i <= 109; i++) {
-			sprintf(agipalFile, "pal.%d", i);
+			Common::sprintf_s(agipalFile, "pal.%d", i);
 			if (allFiles.contains(agipalFile)) {
 				agipal = true; // We found a file "pal.x" where 100 <= x <= 109 so it's AGIPAL
 				break;
diff --git a/engines/agi/graphics.cpp b/engines/agi/graphics.cpp
index 53ac394c2dc..d2e9564e7bb 100644
--- a/engines/agi/graphics.cpp
+++ b/engines/agi/graphics.cpp
@@ -1384,7 +1384,7 @@ void GfxMgr::setAGIPal(int p0) {
 		return;
 
 	char filename[15];
-	sprintf(filename, "pal.%d", p0);
+	Common::sprintf_s(filename, "pal.%d", p0);
 
 	Common::File agipal;
 	if (!agipal.open(filename)) {
diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp
index d82d3f9bc2b..9c383f70546 100644
--- a/engines/agi/op_cmd.cpp
+++ b/engines/agi/op_cmd.cpp
@@ -921,7 +921,7 @@ void cmdObjStatusF(AgiGame *state, AgiEngine *vm, uint8 *parameter) {
 		break;
 	}
 
-	sprintf(msg,
+	Common::sprintf_s(msg,
 	        "Object %d:\n" \
 	        "x: %d  xsize: %d\n" \
 	        "y: %d  ysize: %d\n" \
diff --git a/engines/agi/preagi/mickey.cpp b/engines/agi/preagi/mickey.cpp
index f00ed7677c4..4f12341d209 100644
--- a/engines/agi/preagi/mickey.cpp
+++ b/engines/agi/preagi/mickey.cpp
@@ -54,7 +54,7 @@ void MickeyEngine::readExe(int ofs, uint8 *buffer, long buflen) {
 }
 
 void MickeyEngine::getDatFileName(int iRoom, char *szFile) {
-	sprintf(szFile, IDS_MSA_PATH_DAT, IDS_MSA_NAME_DAT[getDat(iRoom)]);
+	Common::sprintf_s(szFile, 256, IDS_MSA_PATH_DAT, IDS_MSA_NAME_DAT[getDat(iRoom)]);
 }
 
 void MickeyEngine::readDatHdr(char *szFile, MSA_DAT_HEADER *hdr) {
@@ -189,7 +189,7 @@ void MickeyEngine::printDatString(int iStr) {
 	MSA_DAT_HEADER hdr;
 	char szFile[256] = {0};
 
-	sprintf(szFile, IDS_MSA_PATH_DAT, IDS_MSA_NAME_DAT[iDat]);
+	Common::sprintf_s(szFile, IDS_MSA_PATH_DAT, IDS_MSA_NAME_DAT[iDat]);
 	readDatHdr(szFile, &hdr);
 
 	Common::File infile;
@@ -724,7 +724,7 @@ void MickeyEngine::playSound(ENUM_MSA_SOUND iSound) {
 
 void MickeyEngine::drawObj(ENUM_MSA_OBJECT iObj, int x0, int y0) {
 	char szFile[255] = {0};
-	sprintf(szFile, IDS_MSA_PATH_OBJ, IDS_MSA_NAME_OBJ[iObj]);
+	Common::sprintf_s(szFile, IDS_MSA_PATH_OBJ, IDS_MSA_NAME_OBJ[iObj]);
 
 	Common::File file;
 	if (!file.open(szFile))
@@ -746,7 +746,7 @@ void MickeyEngine::drawObj(ENUM_MSA_OBJECT iObj, int x0, int y0) {
 
 void MickeyEngine::drawPic(int iPic) {
 	char szFile[255] = {0};
-	sprintf(szFile, IDS_MSA_PATH_PIC, iPic);
+	Common::sprintf_s(szFile, IDS_MSA_PATH_PIC, iPic);
 
 	Common::File file;
 	if (!file.open(szFile))
@@ -988,7 +988,7 @@ bool MickeyEngine::loadGame() {
 			return false;
 
 		// load game
-		sprintf(szFile, "%s.s%02d", getTargetName().c_str(), sel);
+		Common::sprintf_s(szFile, "%s.s%02d", getTargetName().c_str(), sel);
 		if (!(infile = getSaveFileMan()->openForLoading(szFile))) {
 			printLine("PLEASE CHECK THE DISK DRIVE");
 
@@ -1105,7 +1105,7 @@ void MickeyEngine::saveGame() {
 			return;
 
 		// save game
-		sprintf(szFile, "%s.s%02d", getTargetName().c_str(), sel);
+		Common::sprintf_s(szFile, "%s.s%02d", getTargetName().c_str(), sel);
 		if (!(outfile = getSaveFileMan()->openForSaving(szFile))) {
 			printLine("PLEASE CHECK THE DISK DRIVE");
 
@@ -1371,7 +1371,7 @@ void MickeyEngine::inventory() {
 	int iRow = IDI_MSA_ROW_INV_ITEMS;
 	char szCrystals[12] = {0};
 
-	sprintf(szCrystals, IDS_MSA_CRYSTALS, IDS_MSA_CRYSTAL_NO[_gameStateMickey.nXtals]);
+	Common::sprintf_s(szCrystals, IDS_MSA_CRYSTALS, IDS_MSA_CRYSTAL_NO[_gameStateMickey.nXtals]);
 
 	CursorMan.showMouse(false);
 
diff --git a/engines/agi/preagi/troll.cpp b/engines/agi/preagi/troll.cpp
index 6611f5f5f25..4b199536d15 100644
--- a/engines/agi/preagi/troll.cpp
+++ b/engines/agi/preagi/troll.cpp
@@ -401,7 +401,7 @@ void TrollEngine::gameOver() {
 
 	drawPic(46, true, true);
 
-	sprintf(szMoves, IDS_TRO_GAMEOVER_0, _moves);
+	Common::sprintf_s(szMoves, IDS_TRO_GAMEOVER_0, _moves);
 	drawStr(21, 1, kColorDefault, szMoves);
 	drawStr(22, 1, kColorDefault, IDS_TRO_GAMEOVER_1);
 	g_system->updateScreen();
diff --git a/engines/agi/systemui.cpp b/engines/agi/systemui.cpp
index cec23be0c32..376860dba07 100644
--- a/engines/agi/systemui.cpp
+++ b/engines/agi/systemui.cpp
@@ -587,7 +587,7 @@ void SystemUI::createSavedGameDisplayText(char *destDisplayText, const char *act
 	memset(destDisplayText, fillUpChar, SYSTEMUI_SAVEDGAME_DISPLAYTEXT_LEN);
 
 	// create fixed prefix (" 1:", "10:", etc.)
-	sprintf(slotIdChar, "%02d", slotId);
+	Common::sprintf_s(slotIdChar, "%02d", slotId);
 	memcpy(destDisplayText, slotIdChar, 2);
 	destDisplayText[2] = ':';
 
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index be7c3535627..26c4242c2c8 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -1217,7 +1217,7 @@ char *TextMgr::stringPrintf(const char *originalText) {
 				i = strtoul(originalText, nullptr, 10);
 				while (*originalText >= '0' && *originalText <= '9')
 					originalText++;
-				sprintf(z, "%015i", _vm->getVar(i));
+				Common::sprintf_s(z, "%015i", _vm->getVar(i));
 
 				i = 99;
 				if (*originalText == '|') {


Commit: 429afa3a34241d173c8e3841296a39fc2a657d17
    https://github.com/scummvm/scummvm/commit/429afa3a34241d173c8e3841296a39fc2a657d17
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
AGOS: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/agos/animation.cpp
    engines/agos/debug.cpp
    engines/agos/event.cpp
    engines/agos/feeble.cpp
    engines/agos/res.cpp
    engines/agos/res_snd.cpp
    engines/agos/script_ff.cpp
    engines/agos/script_pn.cpp
    engines/agos/script_s1.cpp
    engines/agos/script_s2.cpp
    engines/agos/sound.cpp
    engines/agos/string.cpp
    engines/agos/verb_pn.cpp


diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index 34fc60bf654..cec332388c6 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -545,25 +545,25 @@ MoviePlayer *makeMoviePlayer(AGOSEngine_Feeble *vm, const char *name) {
 		memset(shortName, 0, sizeof(shortName));
 		memcpy(shortName, baseName, 6);
 
-		sprintf(filename, "%s~1.dxa", shortName);
+		Common::sprintf_s(filename, "%s~1.dxa", shortName);
 		if (Common::File::exists(filename)) {
 			memset(baseName, 0, sizeof(baseName));
 			memcpy(baseName, filename, 8);
 		}
 
-		sprintf(filename, "%s~1.smk", shortName);
+		Common::sprintf_s(filename, "%s~1.smk", shortName);
 		if (Common::File::exists(filename)) {
 			memset(baseName, 0, sizeof(baseName));
 			memcpy(baseName, filename, 8);
 		}
 	}
 
-	sprintf(filename, "%s.dxa", baseName);
+	Common::sprintf_s(filename, "%s.dxa", baseName);
 	if (Common::File::exists(filename)) {
 		return new MoviePlayerDXA(vm, baseName);
 	}
 
-	sprintf(filename, "%s.smk", baseName);
+	Common::sprintf_s(filename, "%s.smk", baseName);
 	if (Common::File::exists(filename)) {
 		return new MoviePlayerSMK(vm, baseName);
 	}
diff --git a/engines/agos/debug.cpp b/engines/agos/debug.cpp
index 8431de78644..2e8071dfa19 100644
--- a/engines/agos/debug.cpp
+++ b/engines/agos/debug.cpp
@@ -588,7 +588,7 @@ void AGOSEngine::dumpBitmap(const char *filename, const byte *offs, uint16 w, ui
 void AGOSEngine::dumpSingleBitmap(int file, int image, const byte *offs, int w, int h, byte base) {
 	char buf[40];
 
-	sprintf(buf, "dumps/File%d_Image%d.bmp", file, image);
+	Common::sprintf_s(buf, "dumps/File%d_Image%d.bmp", file, image);
 
 	if (Common::File::exists(buf))
 		return;
@@ -678,7 +678,7 @@ void AGOSEngine::dumpVgaBitmaps(uint16 zoneNum) {
 
 		/* dump bitmap */
 		char buf[40];
-		sprintf(buf, "dumps/Res%d_Image%d.bmp", zoneNum, i);
+		Common::sprintf_s(buf, "dumps/Res%d_Image%d.bmp", zoneNum, i);
 
 		dumpBitmap(buf, vga2 + offs, width, height, flags, pal, 0);
 	}
diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp
index ca6908476fc..d83bf7794fb 100644
--- a/engines/agos/event.cpp
+++ b/engines/agos/event.cpp
@@ -464,7 +464,7 @@ void AGOSEngine::delay(uint amount) {
 						_saveLoadSlot = 10;
 
 					memset(_saveLoadName, 0, sizeof(_saveLoadName));
-					sprintf(_saveLoadName, "Quick %d", _saveLoadSlot);
+					Common::sprintf_s(_saveLoadName, "Quick %d", _saveLoadSlot);
 					_saveLoadType = (event.kbd.hasFlags(Common::KBD_ALT)) ? 1 : 2;
 					quickLoadOrSave();
 				} else if (event.kbd.hasFlags(Common::KBD_ALT)) {
diff --git a/engines/agos/feeble.cpp b/engines/agos/feeble.cpp
index 8336eda6829..ded8282d9c0 100644
--- a/engines/agos/feeble.cpp
+++ b/engines/agos/feeble.cpp
@@ -268,7 +268,7 @@ void AGOSEngine_FeebleDemo::handleWobble() {
 
 	if (_currentBox && (_currentBox->id >= 11 && _currentBox->id <= 19)) {
 		char filename[15];
-		sprintf(filename, "wobble%d.smk", _currentBox->id - 10);
+		Common::sprintf_s(filename, "wobble%d.smk", _currentBox->id - 10);
 
 		startInteractiveVideo(filename);
 	}
diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp
index 97429ba2315..35719d46100 100644
--- a/engines/agos/res.cpp
+++ b/engines/agos/res.cpp
@@ -777,11 +777,11 @@ void AGOSEngine::loadVGABeardFile(uint16 id) {
 
 		if (getPlatform() == Common::kPlatformAmiga) {
 			if (getFeatures() & GF_TALKIE)
-				sprintf(filename, "0%d.out", id);
+				Common::sprintf_s(filename, "0%d.out", id);
 			else
-				sprintf(filename, "0%d.pkd", id);
+				Common::sprintf_s(filename, "0%d.pkd", id);
 		} else {
-			sprintf(filename, "0%d.VGA", id);
+			Common::sprintf_s(filename, "0%d.VGA", id);
 		}
 
 		if (!in.open(filename))
@@ -924,39 +924,39 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) {
 		loadOffsets(getFileName(GAME_GFXIDXFILE), id * 3 + type, file, offs, srcSize, dstSize);
 
 		if (getPlatform() == Common::kPlatformAmiga)
-			sprintf(filename, "GFX%d.VGA", file);
+			Common::sprintf_s(filename, "GFX%d.VGA", file);
 		else
-			sprintf(filename, "graphics.vga");
+			Common::sprintf_s(filename, "graphics.vga");
 
 		dst = allocBlock(dstSize + extraBuffer);
 		decompressData(filename, dst, offs, srcSize, dstSize);
 	} else if (getFeatures() & GF_OLD_BUNDLE) {
 		if (getPlatform() == Common::kPlatformAcorn) {
-			sprintf(filename, "%.3d%d.DAT", id, type);
+			Common::sprintf_s(filename, "%.3d%d.DAT", id, type);
 		} else if (getPlatform() == Common::kPlatformAmiga || getPlatform() == Common::kPlatformAtariST) {
 			if (getFeatures() & GF_TALKIE) {
-				sprintf(filename, "%.3d%d.out", id, type);
+				Common::sprintf_s(filename, "%.3d%d.out", id, type);
 			} else if (getGameType() == GType_ELVIRA1 && getFeatures() & GF_DEMO) {
 				if (getPlatform() == Common::kPlatformAtariST)
-					sprintf(filename, "%.2d%d.out", id, type);
+					Common::sprintf_s(filename, "%.2d%d.out", id, type);
 				else
-					sprintf(filename, "%c%d.out", 48 + id, type);
+					Common::sprintf_s(filename, "%c%d.out", 48 + id, type);
 			} else if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) {
-				sprintf(filename, "%.2d%d.pkd", id, type);
+				Common::sprintf_s(filename, "%.2d%d.pkd", id, type);
 			} else if (getGameType() == GType_PN) {
-				sprintf(filename, "%c%d.in", id + 48, type);
+				Common::sprintf_s(filename, "%c%d.in", id + 48, type);
 			} else {
-				sprintf(filename, "%.3d%d.pkd", id, type);
+				Common::sprintf_s(filename, "%.3d%d.pkd", id, type);
 			}
 		} else {
 			if (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformPC98) {
-				sprintf(filename, "%.2d.GR2", id);
+				Common::sprintf_s(filename, "%.2d.GR2", id);
 			} else if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
-				sprintf(filename, "%.2d%d.VGA", id, type);
+				Common::sprintf_s(filename, "%.2d%d.VGA", id, type);
 			} else if (getGameType() == GType_PN) {
-				sprintf(filename, "%c%d.out", id + 48, type);
+				Common::sprintf_s(filename, "%c%d.out", id + 48, type);
 			} else {
-				sprintf(filename, "%.3d%d.VGA", id, type);
+				Common::sprintf_s(filename, "%.3d%d.VGA", id, type);
 			}
 		}
 
diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp
index af16ab4c41e..5e6831ad1ce 100644
--- a/engines/agos/res_snd.cpp
+++ b/engines/agos/res_snd.cpp
@@ -199,11 +199,11 @@ void AGOSEngine::playModule(uint16 music) {
 	}
 
 	if (getGameType() == GType_ELVIRA1 && getFeatures() & GF_DEMO)
-		sprintf(filename, "elvira2");
+		Common::sprintf_s(filename, "elvira2");
 	else if (getPlatform() == Common::kPlatformAcorn)
-		sprintf(filename, "%dtune.DAT", music);
+		Common::sprintf_s(filename, "%dtune.DAT", music);
 	else
-		sprintf(filename, "%dtune", music);
+		Common::sprintf_s(filename, "%dtune", music);
 
 	f.open(filename);
 	if (f.isOpen() == false) {
@@ -287,7 +287,7 @@ void AGOSEngine_Simon1::playMusic(uint16 music, uint16 track) {
 		// GMF music data is in separate MODxx.MUS files.
 		char filename[15];
 		Common::File f;
-		sprintf(filename, "MOD%d.MUS", music);
+		Common::sprintf_s(filename, "MOD%d.MUS", music);
 		f.open(filename);
 		if (f.isOpen() == false)
 			error("playMusic: Can't load music from '%s'", filename);
@@ -325,7 +325,7 @@ void AGOSEngine_Simon1::playMidiSfx(uint16 sound) {
 	char filename[16];
 	Common::File mus_file;
 
-	sprintf(filename, "STINGS%i.MUS", _soundFileId);
+	Common::sprintf_s(filename, "STINGS%i.MUS", _soundFileId);
 	mus_file.open(filename);
 	if (!mus_file.isOpen())
 		error("playSting: Can't load sound effect from '%s'", filename);
@@ -413,26 +413,26 @@ bool AGOSEngine::loadVGASoundFile(uint16 id, uint8 type) {
 	if (getPlatform() == Common::kPlatformAmiga || getPlatform() == Common::kPlatformAtariST) {
 		if (getGameType() == GType_ELVIRA1 && (getFeatures() & GF_DEMO) &&
 			getPlatform() == Common::kPlatformAmiga) {
-			sprintf(filename, "%c%d.out", 48 + id, type);
+			Common::sprintf_s(filename, "%c%d.out", 48 + id, type);
 		} else if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) {
-			sprintf(filename, "%.2d%d.out", id, type);
+			Common::sprintf_s(filename, "%.2d%d.out", id, type);
 		} else if (getGameType() == GType_PN) {
-			sprintf(filename, "%c%d.in", id + 48, type);
+			Common::sprintf_s(filename, "%c%d.in", id + 48, type);
 		} else {
-			sprintf(filename, "%.3d%d.out", id, type);
+			Common::sprintf_s(filename, "%.3d%d.out", id, type);
 		}
 	} else {
 		if (getGameType() == GType_ELVIRA1) {
 			if (elvira1_soundTable[id] == 0)
 				return false;
 
-			sprintf(filename, "%.2d.SND", elvira1_soundTable[id]);
+			Common::sprintf_s(filename, "%.2d.SND", elvira1_soundTable[id]);
 		} else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
-			sprintf(filename, "%.2d%d.VGA", id, type);
+			Common::sprintf_s(filename, "%.2d%d.VGA", id, type);
 		} else if (getGameType() == GType_PN) {
-			sprintf(filename, "%c%d.out", id + 48, type);
+			Common::sprintf_s(filename, "%c%d.out", id + 48, type);
 		} else {
-			sprintf(filename, "%.3d%d.VGA", id, type);
+			Common::sprintf_s(filename, "%.3d%d.VGA", id, type);
 		}
 	}
 
@@ -530,7 +530,7 @@ void AGOSEngine::loadSound(uint16 sound, int16 pan, int16 vol, uint16 type) {
 		char filename[15];
 
 		assert(sound >= 1 && sound <= 32);
-		sprintf(filename, "%s.wav", dimpSoundList[sound - 1]);
+		Common::sprintf_s(filename, "%s.wav", dimpSoundList[sound - 1]);
 
 		if (!in.open(filename))
 			error("loadSound: Can't load %s", filename);
@@ -550,9 +550,9 @@ void AGOSEngine::loadSound(uint16 sound, int16 pan, int16 vol, uint16 type) {
 		}
 
 		if (getPlatform() == Common::kPlatformAmiga)
-			sprintf(filename, "sfx%u.wav", file);
+			Common::sprintf_s(filename, "sfx%u.wav", file);
 		else
-			sprintf(filename, "effects.wav");
+			Common::sprintf_s(filename, "effects.wav");
 
 		dst = (byte *)malloc(dstSize);
 		decompressData(filename, dst, offset, srcSize, dstSize);
@@ -691,9 +691,9 @@ void AGOSEngine::loadVoice(uint speechId) {
 		}
 
 		if (getPlatform() == Common::kPlatformAmiga)
-			sprintf(filename, "sp%u.wav", file);
+			Common::sprintf_s(filename, "sp%u.wav", file);
 		else
-			sprintf(filename, "speech.wav");
+			Common::sprintf_s(filename, "speech.wav");
 
 		byte *dst = (byte *)malloc(dstSize);
 		decompressData(filename, dst, offset, srcSize, dstSize);
diff --git a/engines/agos/script_ff.cpp b/engines/agos/script_ff.cpp
index fcc77eea7b9..80a7970dd9d 100644
--- a/engines/agos/script_ff.cpp
+++ b/engines/agos/script_ff.cpp
@@ -598,7 +598,7 @@ void AGOSEngine_Feeble::off_screenTextPObj() {
 
 	if (subObject != NULL && (subObject->objectFlags & kOFText) && _subtitles) {
 		if (subObject->objectFlags & kOFNumber) {
-			sprintf(buf, "%d%s", subObject->objectFlagValue[getOffsetOfChild2Param(subObject, kOFNumber)], string_ptr);
+			Common::sprintf_s(buf, "%d%s", subObject->objectFlagValue[getOffsetOfChild2Param(subObject, kOFNumber)], string_ptr);
 			string_ptr = buf;
 		}
 		if (string_ptr != NULL)
diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp
index 4632204adbd..3711202c0b1 100644
--- a/engines/agos/script_pn.cpp
+++ b/engines/agos/script_pn.cpp
@@ -236,7 +236,7 @@ void AGOSEngine_PN::opn_opcode11() {
 void AGOSEngine_PN::opn_opcode12() {
 	char bf[8];
 	int a = 0;
-	sprintf(bf,"%d", varval());
+	Common::sprintf_s(bf,"%d", varval());
 	while (bf[a])
 		pcf(bf[a++]);
 	setScriptReturn(true);
@@ -245,7 +245,7 @@ void AGOSEngine_PN::opn_opcode12() {
 void AGOSEngine_PN::opn_opcode13() {
 	char bf[8];
 	int a = 0;
-	sprintf(bf,"%d", varval());
+	Common::sprintf_s(bf,"%d", varval());
 	while (bf[a])
 		pcf(bf[a++]);
 	pcf((uint8)'\n');
diff --git a/engines/agos/script_s1.cpp b/engines/agos/script_s1.cpp
index a7372e3b79a..aacfb565c53 100644
--- a/engines/agos/script_s1.cpp
+++ b/engines/agos/script_s1.cpp
@@ -411,11 +411,11 @@ void AGOSEngine_Simon1::os1_screenTextPObj() {
 				k = (j % 10) * 10;
 				k += j / 10;
 				if (!(j % 10))
-					sprintf(buf,"0%d%s", k, stringPtr);
+					Common::sprintf_s(buf,"0%d%s", k, stringPtr);
 				else
-					sprintf(buf,"%d%s", k, stringPtr);
+					Common::sprintf_s(buf,"%d%s", k, stringPtr);
 			} else {
-				sprintf(buf,"%d%s", subObject->objectFlagValue[getOffsetOfChild2Param(subObject, kOFNumber)], stringPtr);
+				Common::sprintf_s(buf,"%d%s", subObject->objectFlagValue[getOffsetOfChild2Param(subObject, kOFNumber)], stringPtr);
 			}
 			stringPtr = buf;
 		}
@@ -540,9 +540,9 @@ void AGOSEngine_Simon1::os1_loadStrings() {
 	_soundFileId = getVarOrWord();
 	if (getPlatform() == Common::kPlatformAmiga && (getFeatures() & GF_TALKIE)) {
 		char buf[13];
-		sprintf(buf, "%d%s", _soundFileId, "Effects");
+		Common::sprintf_s(buf, "%d%s", _soundFileId, "Effects");
 		_sound->readSfxFile(buf);
-		sprintf(buf, "%d%s", _soundFileId, "simon");
+		Common::sprintf_s(buf, "%d%s", _soundFileId, "simon");
 		_sound->readVoiceFile(buf);
 	}
 }
diff --git a/engines/agos/script_s2.cpp b/engines/agos/script_s2.cpp
index 4e2104978b8..056c87409f0 100644
--- a/engines/agos/script_s2.cpp
+++ b/engines/agos/script_s2.cpp
@@ -422,11 +422,11 @@ void AGOSEngine_Simon2::os2_screenTextPObj() {
 				k = (j % 10) * 10;
 				k += j / 10;
 				if (!(j % 10))
-					sprintf(buf,"0%d%s", k, stringPtr);
+					Common::sprintf_s(buf,"0%d%s", k, stringPtr);
 				else
-					sprintf(buf,"%d%s", k, stringPtr);
+					Common::sprintf_s(buf,"%d%s", k, stringPtr);
 			} else {
-				sprintf(buf,"%d%s", subObject->objectFlagValue[getOffsetOfChild2Param(subObject, kOFNumber)], stringPtr);
+				Common::sprintf_s(buf,"%d%s", subObject->objectFlagValue[getOffsetOfChild2Param(subObject, kOFNumber)], stringPtr);
 			}
 			stringPtr = buf;
 		}
diff --git a/engines/agos/sound.cpp b/engines/agos/sound.cpp
index 641890936be..488e6e781ad 100644
--- a/engines/agos/sound.cpp
+++ b/engines/agos/sound.cpp
@@ -540,7 +540,7 @@ void Sound::playVoice(uint sound) {
 
 			char filename[16];
 			_lastVoiceFile = _filenums[sound];
-			sprintf(filename, "voices%d.dat", _filenums[sound]);
+			Common::sprintf_s(filename, "voices%d.dat", _filenums[sound]);
 			if (!Common::File::exists(filename))
 				error("playVoice: Can't load voice file %s", filename);
 
@@ -718,7 +718,7 @@ void Sound::switchVoiceFile(const GameSpecificSettings *gss, uint disc) {
 
 	char filename[16];
 
-	sprintf(filename, "%s%u", gss->speech_filename, disc);
+	Common::sprintf_s(filename, "%s%u", gss->speech_filename, disc);
 	_voice = makeSound(_mixer, filename);
 	_hasVoiceFile = (_voice != nullptr);
 
diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp
index ec1f6925d0f..49f7681f383 100644
--- a/engines/agos/string.cpp
+++ b/engines/agos/string.cpp
@@ -1034,7 +1034,7 @@ uint16 AGOSEngine_Waxworks::checkFit(char *ptr, int width, int lines) {
 }
 
 void AGOSEngine_Waxworks::boxTextMessage(const char *x) {
-	sprintf(_boxBufferPtr, "%s\n", x);
+	Common::sprintf_s(_boxBufferPtr, sizeof(_boxBuffer) - (_boxBufferPtr - _boxBuffer), "%s\n", x);
 	_lineCounts[_boxLineCount] += strlen(x);
 	_boxBufferPtr += strlen(x) + 1;
 	_boxLineCount++;
@@ -1043,7 +1043,7 @@ void AGOSEngine_Waxworks::boxTextMessage(const char *x) {
 }
 
 void AGOSEngine_Waxworks::boxTextMsg(const char *x) {
-	sprintf(_boxBufferPtr, "%s", x);
+	Common::sprintf_s(_boxBufferPtr, sizeof(_boxBuffer) - (_boxBufferPtr - _boxBuffer), "%s", x);
 	_lineCounts[_boxLineCount] += strlen(x);
 	_boxBufferPtr += strlen(x);
 	_boxCR = 0;
diff --git a/engines/agos/verb_pn.cpp b/engines/agos/verb_pn.cpp
index a3b567b0c0d..6a9fc1687b5 100644
--- a/engines/agos/verb_pn.cpp
+++ b/engines/agos/verb_pn.cpp
@@ -241,12 +241,12 @@ void AGOSEngine_PN::hitBox8(HitArea *ha) {
 		return;
 
 	msgPtr = getMessage(_objectName1, ha->msg1);
-	sprintf(_inMessage, " in %s", msgPtr);
+	Common::sprintf_s(_inMessage, " in %s", msgPtr);
 	_mouseString1 = _inMessage;
 
 	msgPtr = getMessage(_objectName1, _dragStore->msg1);
 	*(tmpPtr = strchr(msgPtr, 13)) = 0;
-	sprintf(_placeMessage, "put %s", msgPtr);
+	Common::sprintf_s(_placeMessage, "put %s", msgPtr);
 	_mouseString = _placeMessage;
 }
 


Commit: ab0854d81a9bfb5b26814e1f6f57dd690d099e3b
    https://github.com/scummvm/scummvm/commit/ab0854d81a9bfb5b26814e1f6f57dd690d099e3b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
AGS: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/ags/engine/ac/string.cpp
    engines/ags/engine/main/game_run.cpp
    engines/ags/shared/util/string.cpp


diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp
index baf6b904b75..1ac538c2271 100644
--- a/engines/ags/engine/ac/string.cpp
+++ b/engines/ags/engine/ac/string.cpp
@@ -67,8 +67,9 @@ const char *String_AppendChar(const char *thisString, int extraOne) {
 		chw = Utf8::SetChar(extraOne, chr, sizeof(chr));
 	else
 		chr[0] = extraOne;
-	char *buffer = (char *)malloc(strlen(thisString) + chw + 1);
-	sprintf(buffer, "%s%s", thisString, chr);
+	size_t ln = strlen(thisString) + chw + 1;
+	char *buffer = (char *)malloc(ln);
+	Common::sprintf_s(buffer, ln, "%s%s", thisString, chr);
 	return CreateNewScriptString(buffer, false);
 }
 
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index b321fcc7309..dd9df877d0d 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -344,7 +344,8 @@ bool run_service_key_controls(KeyInput &out_key) {
 	if ((agskey == eAGSKeyCodeCtrlD) && (_GP(play).debug_mode > 0)) {
 		// ctrl+D - show info
 		char infobuf[900];
-		sprintf(infobuf, "In room %d %s[Player at %d, %d (view %d, loop %d, frame %d)%s%s%s",
+		size_t ln = 0;
+		ln += Common::sprintf_s(infobuf, "In room %d %s[Player at %d, %d (view %d, loop %d, frame %d)%s%s%s",
 		        _G(displayed_room), (_G(noWalkBehindsAtAll) ? "(has no walk-behinds)" : ""), _G(playerchar)->x, _G(playerchar)->y,
 		        _G(playerchar)->view + 1, _G(playerchar)->loop, _G(playerchar)->frame,
 		        (IsGamePaused() == 0) ? "" : "[Game paused.",
@@ -352,7 +353,7 @@ bool run_service_key_controls(KeyInput &out_key) {
 		        (IsInterfaceEnabled() == 0) ? "[Game in Wait state" : "");
 		for (uint32_t ff = 0; ff < _G(croom)->numobj; ff++) {
 			if (ff >= 8) break; // buffer not big enough for more than 7
-			sprintf(&infobuf[strlen(infobuf)],
+			ln += Common::sprintf_s(&infobuf[ln], sizeof(infobuf) - ln,
 			        "[Object %d: (%d,%d) size (%d x %d) on:%d moving:%s animating:%d slot:%d trnsp:%d clkble:%d",
 			        ff, _G(objs)[ff].x, _G(objs)[ff].y,
 			        (_GP(spriteset)[_G(objs)[ff].num] != nullptr) ? _GP(game).SpriteInfos[_G(objs)[ff].num].Width : 0,
@@ -373,7 +374,8 @@ bool run_service_key_controls(KeyInput &out_key) {
 				Common::strcpy_s(bigbuffer, "CHARACTERS IN THIS ROOM (cont'd):[");
 			}
 			chd = ff;
-			sprintf(&bigbuffer[strlen(bigbuffer)],
+			ln = strlen(bigbuffer);
+			Common::sprintf_s(&bigbuffer[ln], sizeof(bigbuffer) - ln,
 			        "%s (view/loop/frm:%d,%d,%d  x/y/z:%d,%d,%d  idleview:%d,time:%d,left:%d walk:%d anim:%d follow:%d flags:%X wait:%d zoom:%d)[",
 			        _GP(game).chars[chd].scrname, _GP(game).chars[chd].view + 1, _GP(game).chars[chd].loop, _GP(game).chars[chd].frame,
 			        _GP(game).chars[chd].x, _GP(game).chars[chd].y, _GP(game).chars[chd].z,
diff --git a/engines/ags/shared/util/string.cpp b/engines/ags/shared/util/string.cpp
index d3387806ed8..481b98a2abe 100644
--- a/engines/ags/shared/util/string.cpp
+++ b/engines/ags/shared/util/string.cpp
@@ -461,7 +461,7 @@ void String::AppendFmtv(const char *fcstr, va_list argptr) {
 	va_copy(argptr_cpy, argptr);
 	size_t length = vsnprintf(nullptr, 0u, fcstr, argptr);
 	ReserveAndShift(false, length);
-	vsprintf(_cstr + _len, fcstr, argptr_cpy);
+	vsnprintf(_cstr + _len, length + 1, fcstr, argptr_cpy);
 	va_end(argptr_cpy);
 	_len += length;
 	_cstr[_len] = 0;
@@ -572,7 +572,7 @@ void String::FormatV(const char *fcstr, va_list argptr) {
 	va_copy(argptr_cpy, argptr);
 	size_t length = vsnprintf(nullptr, 0u, fcstr, argptr);
 	ReserveAndShift(false, Math::Surplus(length, _len));
-	vsprintf(_cstr, fcstr, argptr_cpy);
+	vsnprintf(_cstr, length + 1, fcstr, argptr_cpy);
 	va_end(argptr_cpy);
 	_len = length;
 	_cstr[_len] = 0;


Commit: 14e3d1f343f035fc9ec9eafc746de5cffffd4d81
    https://github.com/scummvm/scummvm/commit/14e3d1f343f035fc9ec9eafc746de5cffffd4d81
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CGE: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/cge/cge_main.cpp
    engines/cge/sound.cpp
    engines/cge/text.cpp


diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp
index 1463afd8bcd..5e4dc3559ec 100644
--- a/engines/cge/cge_main.cpp
+++ b/engines/cge/cge_main.cpp
@@ -547,7 +547,7 @@ void CGEEngine::setMapBrick(int x, int z) {
 	Square *s = new Square(this);
 	char n[6];
 	s->gotoxy(x * kMapGridX, kMapTop + z * kMapGridZ);
-	sprintf(n, "%02d:%02d", x, z);
+	Common::sprintf_s(n, "%02d:%02d", x, z);
 	_clusterMap[z][x] = 1;
 	s->setName(n);
 	_vga->_showQ->insert(s, _vga->_showQ->first());
@@ -1448,7 +1448,7 @@ void CGEEngine::movie(const char *ext) {
 		return;
 
 	char fn[12];
-	sprintf(fn, "CGE.%s", (*ext == '.') ? ext +1 : ext);
+	Common::sprintf_s(fn, "CGE.%s", (*ext == '.') ? ext +1 : ext);
 
 	if (_resman->exist(fn)) {
 		loadScript(fn);
diff --git a/engines/cge/sound.cpp b/engines/cge/sound.cpp
index 866ab8d86f3..4a17b40c033 100644
--- a/engines/cge/sound.cpp
+++ b/engines/cge/sound.cpp
@@ -151,7 +151,7 @@ void Fx::preload(int ref0) {
 	char filename[12];
 
 	for (int ref = ref0; ref < ref0 + 10; ref++) {
-		sprintf(filename, "FX%05d.WAV", ref);
+		Common::sprintf_s(filename, "FX%05d.WAV", ref);
 		EncryptedStream file(_vm->_resman, filename);
 		DataCk *wav = loadWave(&file);
 		if (wav) {
@@ -171,7 +171,7 @@ void Fx::preload(int ref0) {
 
 DataCk *Fx::load(int idx, int ref) {
 	char filename[12];
-	sprintf(filename, "FX%05d.WAV", ref);
+	Common::sprintf_s(filename, "FX%05d.WAV", ref);
 
 	EncryptedStream file(_vm->_resman, filename);
 	DataCk *wav = loadWave(&file);
diff --git a/engines/cge/text.cpp b/engines/cge/text.cpp
index fe4d534fe22..f40912a0e96 100644
--- a/engines/cge/text.cpp
+++ b/engines/cge/text.cpp
@@ -209,7 +209,7 @@ void Text::sayTime(Sprite *spr) {
 	_vm->_system->getTimeAndDate(curTime);
 
 	char t[6];
-	sprintf(t, "%d:%02d", curTime.tm_hour, curTime.tm_min);
+	Common::sprintf_s(t, "%d:%02d", curTime.tm_hour, curTime.tm_min);
 	say(t, spr);
 }
 


Commit: 1ae18bc6507ab69afd7d7dd81f8feb3da00284f9
    https://github.com/scummvm/scummvm/commit/1ae18bc6507ab69afd7d7dd81f8feb3da00284f9
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CHEWY: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/chewy/mcga_graphics.cpp


diff --git a/engines/chewy/mcga_graphics.cpp b/engines/chewy/mcga_graphics.cpp
index 5001c1a5d4c..0dc167b6c86 100644
--- a/engines/chewy/mcga_graphics.cpp
+++ b/engines/chewy/mcga_graphics.cpp
@@ -392,7 +392,7 @@ int16 McgaGraphics::scanxy(int16 x, int16 y, int16 fcol, int16 bcol, int16 cur_c
 						luzahl = intzahl[0];
 					}
 					if (luzahl != 0)
-						sprintf(zstring, "%u", luzahl);
+						Common::sprintf_s(zstring, "%u", luzahl);
 					else {
 						zstring[0] = '0';
 						zstring[1] = 0 ;
@@ -412,7 +412,7 @@ int16 McgaGraphics::scanxy(int16 x, int16 y, int16 fcol, int16 bcol, int16 cur_c
 					longzahl = va_arg(parptr, uint32 *);
 					luzahl = longzahl[0];
 					if (luzahl != 0)
-						sprintf(zstring, "%u", luzahl);
+						Common::sprintf_s(zstring, "%u", luzahl);
 					else {
 						zstring[0] = '0';
 						zstring[1] = 0 ;


Commit: b75ecadf567510bb99b9bcc4e6d2e7b20299ee63
    https://github.com/scummvm/scummvm/commit/b75ecadf567510bb99b9bcc4e6d2e7b20299ee63
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CINE: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/cine/prc.cpp
    engines/cine/rel.cpp
    engines/cine/script_fw.cpp
    engines/cine/various.cpp


diff --git a/engines/cine/prc.cpp b/engines/cine/prc.cpp
index 6c33df66301..db97ec96b6b 100644
--- a/engines/cine/prc.cpp
+++ b/engines/cine/prc.cpp
@@ -99,7 +99,7 @@ bool loadPrc(const char *pPrcName) {
 
 		for (s = 0; s < numScripts; s++) {
 			if (g_cine->_scriptTable[s]->_size) {
-				sprintf(buffer, "%s_%03d.txt", pPrcName, s);
+				Common::sprintf_s(buffer, "%s_%03d.txt", pPrcName, s);
 
 				decompileScript((const byte *)g_cine->_scriptTable[s]->getString(0), g_cine->_scriptTable[s]->_size, s);
 				dumpScript(buffer);
diff --git a/engines/cine/rel.cpp b/engines/cine/rel.cpp
index a09367b4633..84cc840d418 100644
--- a/engines/cine/rel.cpp
+++ b/engines/cine/rel.cpp
@@ -77,7 +77,7 @@ void loadRel(char *pRelName) {
 
 		for (s = 0; s < numEntry; s++) {
 			if (g_cine->_relTable[s]->_size) {
-				sprintf(buffer, "%s_%03d.txt", pRelName, s);
+				Common::sprintf_s(buffer, "%s_%03d.txt", pRelName, s);
 
 				decompileScript((const byte *)g_cine->_relTable[s]->getString(0), g_cine->_relTable[s]->_size, s);
 				dumpScript(buffer);
diff --git a/engines/cine/script_fw.cpp b/engines/cine/script_fw.cpp
index 617c0e7ec36..5fd606ffc2e 100644
--- a/engines/cine/script_fw.cpp
+++ b/engines/cine/script_fw.cpp
@@ -2187,7 +2187,7 @@ const char *getObjPramName(byte paramIdx) {
 	case 6:
 		return ".costume";
 	default:
-		sprintf(bufferDec, ".param%d", paramIdx);
+		Common::sprintf_s(bufferDec, ".param%d", paramIdx);
 		return bufferDec;
 	}
 }
@@ -2202,7 +2202,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 
 	exitScript = 0;
 
-	sprintf(decompileBuffer[decompileBufferPosition++], "--------- SCRIPT %d ---------\n", scriptIdx);
+	Common::sprintf_s(decompileBuffer[decompileBufferPosition++], "--------- SCRIPT %d ---------\n", scriptIdx);
 
 	do {
 		uint16 opcode = *(localScriptPtr + position);
@@ -2232,7 +2232,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param3 = READ_BE_UINT16(localScriptPtr + position);
 			position += 2;
 
-			sprintf(lineBuffer, "obj[%d]%s = %d\n", param1, getObjPramName(param2), param3);
+			Common::sprintf_s(lineBuffer, "obj[%d]%s = %d\n", param1, getObjPramName(param2), param3);
 
 			break;
 		}
@@ -2250,7 +2250,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param3 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "var[%d]=obj[%d]%s\n", param3, param1, getObjPramName(param2));
+			Common::sprintf_s(lineBuffer, "var[%d]=obj[%d]%s\n", param3, param1, getObjPramName(param2));
 			break;
 		}
 		case 0x2:
@@ -2272,16 +2272,16 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			position += 2;
 
 			if (opcode - 1 == 0x2) {
-				sprintf(lineBuffer, "obj[%d]%s+=%d\n", param1, getObjPramName(param2), param3);
+				Common::sprintf_s(lineBuffer, "obj[%d]%s+=%d\n", param1, getObjPramName(param2), param3);
 			} else if (opcode - 1 == 0x3) {
-				sprintf(lineBuffer, "obj[%d]%s-=%d\n", param1, getObjPramName(param2), param3);
+				Common::sprintf_s(lineBuffer, "obj[%d]%s-=%d\n", param1, getObjPramName(param2), param3);
 			} else if (opcode - 1 == 0x4) {
-				sprintf(lineBuffer, "obj[%d]%s+=obj[%d]%s\n", param1, getObjPramName(param2), param3, getObjPramName(param2));
+				Common::sprintf_s(lineBuffer, "obj[%d]%s+=obj[%d]%s\n", param1, getObjPramName(param2), param3, getObjPramName(param2));
 			} else if (opcode - 1 == 0x5) {
-				sprintf(lineBuffer, "obj[%d]%s-=obj[%d]%s\n", param1, getObjPramName(param2), param3, getObjPramName(param2));
+				Common::sprintf_s(lineBuffer, "obj[%d]%s-=obj[%d]%s\n", param1, getObjPramName(param2), param3, getObjPramName(param2));
 			} else if (opcode - 1 == 0x6) {
-				sprintf(compareString1, "obj[%d]%s", param1, getObjPramName(param2));
-				sprintf(compareString2, "%d", param3);
+				Common::sprintf_s(compareString1, "obj[%d]%s", param1, getObjPramName(param2));
+				Common::sprintf_s(compareString2, "%d", param3);
 			}
 			break;
 		}
@@ -2309,9 +2309,9 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			position += 2;
 
 			if (opcode - 1 == 0x7) {
-				sprintf(lineBuffer, "setupObject(Idx:%d,X:%d,Y:%d,mask:%d,frame:%d)\n", param1, param2, param3, param4, param5);
+				Common::sprintf_s(lineBuffer, "setupObject(Idx:%d,X:%d,Y:%d,mask:%d,frame:%d)\n", param1, param2, param3, param4, param5);
 			} else if (opcode - 1 == 0x8) {
-				sprintf(lineBuffer, "checkCollision(%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5);
+				Common::sprintf_s(lineBuffer, "checkCollision(%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5);
 			}
 			break;
 		}
@@ -2332,19 +2332,19 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 				position++;
 
 				if (param2 == 1) {
-					sprintf(lineBuffer, "var[%d]=var[%d]\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]=var[%d]\n", param1, param3);
 				} else if (param2 == 2) {
-					sprintf(lineBuffer, "var[%d]=globalVar[%d]\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]=globalVar[%d]\n", param1, param3);
 				} else if (param2 == 3) {
-					sprintf(lineBuffer, "var[%d]=mouse.X\n", param1);
+					Common::sprintf_s(lineBuffer, "var[%d]=mouse.X\n", param1);
 				} else if (param2 == 4) {
-					sprintf(lineBuffer, "var[%d]=mouse.Y\n", param1);
+					Common::sprintf_s(lineBuffer, "var[%d]=mouse.Y\n", param1);
 				} else if (param2 == 5) {
-					sprintf(lineBuffer, "var[%d]=rand() mod %d\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]=rand() mod %d\n", param1, param3);
 				} else if (param2 == 8) {
-					sprintf(lineBuffer, "var[%d]=file[%d].packedSize\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]=file[%d].packedSize\n", param1, param3);
 				} else if (param2 == 9) {
-					sprintf(lineBuffer, "var[%d]=file[%d].unpackedSize\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]=file[%d].unpackedSize\n", param1, param3);
 				} else {
 					error("decompileScript: 0x09: param2 = %d", param2);
 				}
@@ -2354,7 +2354,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 				param3 = READ_BE_UINT16(localScriptPtr + position);
 				position += 2;
 
-				sprintf(lineBuffer, "var[%d]=%d\n", param1, param3);
+				Common::sprintf_s(lineBuffer, "var[%d]=%d\n", param1, param3);
 			}
 
 			break;
@@ -2379,13 +2379,13 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 				position++;
 
 				if (opcode - 1 == 0xA) {
-					sprintf(lineBuffer, "var[%d]+=var[%d]\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]+=var[%d]\n", param1, param3);
 				} else if (opcode - 1 == 0xB) {
-					sprintf(lineBuffer, "var[%d]-=var[%d]\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]-=var[%d]\n", param1, param3);
 				} else if (opcode - 1 == 0xC) {
-					sprintf(lineBuffer, "var[%d]*=var[%d]\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]*=var[%d]\n", param1, param3);
 				} else if (opcode - 1 == 0xD) {
-					sprintf(lineBuffer, "var[%d]/=var[%d]\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]/=var[%d]\n", param1, param3);
 				}
 			} else {
 				int16 param3;
@@ -2394,13 +2394,13 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 				position += 2;
 
 				if (opcode - 1 == 0xA) {
-					sprintf(lineBuffer, "var[%d]+=%d\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]+=%d\n", param1, param3);
 				} else if (opcode - 1 == 0xB) {
-					sprintf(lineBuffer, "var[%d]-=%d\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]-=%d\n", param1, param3);
 				} else if (opcode - 1 == 0xC) {
-					sprintf(lineBuffer, "var[%d]*=%d\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]*=%d\n", param1, param3);
 				} else if (opcode - 1 == 0xD) {
-					sprintf(lineBuffer, "var[%d]/=%d\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "var[%d]/=%d\n", param1, param3);
 				}
 			}
 			break;
@@ -2422,12 +2422,12 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 				position++;
 
 				if (param2 == 1) {
-					sprintf(compareString1, "var[%d]", param1);
-					sprintf(compareString2, "var[%d]", param3);
+					Common::sprintf_s(compareString1, "var[%d]", param1);
+					Common::sprintf_s(compareString2, "var[%d]", param3);
 
 				} else if (param2 == 2) {
-					sprintf(compareString1, "var[%d]", param1);
-					sprintf(compareString2, "globalVar[%d]", param3);
+					Common::sprintf_s(compareString1, "var[%d]", param1);
+					Common::sprintf_s(compareString2, "globalVar[%d]", param3);
 				} else {
 					error("decompileScript: 0x0E: param2 = %d", param2);
 				}
@@ -2437,8 +2437,8 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 				param3 = READ_BE_UINT16(localScriptPtr + position);
 				position += 2;
 
-				sprintf(compareString1, "var[%d]", param1);
-				sprintf(compareString2, "%d", param3);
+				Common::sprintf_s(compareString1, "var[%d]", param1);
+				Common::sprintf_s(compareString2, "%d", param3);
 			}
 			break;
 		}
@@ -2456,7 +2456,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param3 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "obj[%d]%s=var[%d]\n", param1, getObjPramName(param2), param3);
+			Common::sprintf_s(lineBuffer, "obj[%d]%s=var[%d]\n", param1, getObjPramName(param2), param3);
 
 			break;
 		}
@@ -2473,19 +2473,19 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			position++;
 
 			if (opcode - 1 == 0x13) {
-				sprintf(lineBuffer, "loadMask0(%d)\n", param);
+				Common::sprintf_s(lineBuffer, "loadMask0(%d)\n", param);
 			} else if (opcode - 1 == 0x14) {
-				sprintf(lineBuffer, "unloadMask0(%d)\n", param);
+				Common::sprintf_s(lineBuffer, "unloadMask0(%d)\n", param);
 			} else if (opcode - 1 == 0x15) {
-				sprintf(lineBuffer, "OP_15(%d)\n", param);
+				Common::sprintf_s(lineBuffer, "OP_15(%d)\n", param);
 			} else if (opcode - 1 == 0x16) {
-				sprintf(lineBuffer, "loadMask1(%d)\n", param);
+				Common::sprintf_s(lineBuffer, "loadMask1(%d)\n", param);
 			} else if (opcode - 1 == 0x17) {
-				sprintf(lineBuffer, "unloadMask0(%d)\n", param);
+				Common::sprintf_s(lineBuffer, "unloadMask0(%d)\n", param);
 			} else if (opcode - 1 == 0x18) {
-				sprintf(lineBuffer, "loadMask4(%d)\n", param);
+				Common::sprintf_s(lineBuffer, "loadMask4(%d)\n", param);
 			} else if (opcode - 1 == 0x19) {
-				sprintf(lineBuffer, "unloadMask4(%d)\n", param);
+				Common::sprintf_s(lineBuffer, "unloadMask4(%d)\n", param);
 			}
 			break;
 		}
@@ -2495,12 +2495,12 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_1A(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "OP_1A(%d)\n", param);
 
 			break;
 		}
 		case 0x1B: {
-			sprintf(lineBuffer, "bgIncrustList.clear()\n");
+			Common::sprintf_s(lineBuffer, "bgIncrustList.clear()\n");
 			break;
 		}
 		case 0x1D: {
@@ -2509,7 +2509,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "label(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "label(%d)\n", param);
 
 			break;
 		}
@@ -2519,7 +2519,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "goto(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "goto(%d)\n", param);
 
 			break;
 		}
@@ -2536,17 +2536,17 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			position++;
 
 			if (opcode - 1 == 0x1F) {
-				sprintf(lineBuffer, "if(%s>%s) goto(%d)\n", compareString1, compareString2, param);
+				Common::sprintf_s(lineBuffer, "if(%s>%s) goto(%d)\n", compareString1, compareString2, param);
 			} else if (opcode - 1 == 0x20) {
-				sprintf(lineBuffer, "if(%s>=%s) goto(%d)\n", compareString1, compareString2, param);
+				Common::sprintf_s(lineBuffer, "if(%s>=%s) goto(%d)\n", compareString1, compareString2, param);
 			} else if (opcode - 1 == 0x21) {
-				sprintf(lineBuffer, "if(%s<%s) goto(%d)\n", compareString1, compareString2, param);
+				Common::sprintf_s(lineBuffer, "if(%s<%s) goto(%d)\n", compareString1, compareString2, param);
 			} else if (opcode - 1 == 0x22) {
-				sprintf(lineBuffer, "if(%s<=%s) goto(%d)\n", compareString1, compareString2, param);
+				Common::sprintf_s(lineBuffer, "if(%s<=%s) goto(%d)\n", compareString1, compareString2, param);
 			} else if (opcode - 1 == 0x23) {
-				sprintf(lineBuffer, "if(%s==%s) goto(%d)\n", compareString1, compareString2, param);
+				Common::sprintf_s(lineBuffer, "if(%s==%s) goto(%d)\n", compareString1, compareString2, param);
 			} else if (opcode - 1 == 0x24) {
-				sprintf(lineBuffer, "if(%s!=%s) goto(%d)\n", compareString1, compareString2, param);
+				Common::sprintf_s(lineBuffer, "if(%s!=%s) goto(%d)\n", compareString1, compareString2, param);
 			}
 			break;
 		}
@@ -2556,7 +2556,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "removeLabel(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "removeLabel(%d)\n", param);
 
 			break;
 		}
@@ -2569,7 +2569,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param2 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "loop(--var[%d]) -> label(%d)\n", param1, param2);
+			Common::sprintf_s(lineBuffer, "loop(--var[%d]) -> label(%d)\n", param1, param2);
 
 			break;
 		}
@@ -2581,9 +2581,9 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			position++;
 
 			if (opcode - 1 == 0x31) {
-				sprintf(lineBuffer, "startGlobalScript(%d)\n", param);
+				Common::sprintf_s(lineBuffer, "startGlobalScript(%d)\n", param);
 			} else if (opcode - 1 == 0x32) {
-				sprintf(lineBuffer, "endGlobalScript(%d)\n", param);
+				Common::sprintf_s(lineBuffer, "endGlobalScript(%d)\n", param);
 			}
 			break;
 		}
@@ -2592,20 +2592,20 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 		case 0x3D:
 		case OP_loadPart: {
 			if (opcode - 1 == 0x3B) {
-				sprintf(lineBuffer, "loadResource(%s)\n", localScriptPtr + position);
+				Common::sprintf_s(lineBuffer, "loadResource(%s)\n", localScriptPtr + position);
 			} else if (opcode - 1 == 0x3C) {
-				sprintf(lineBuffer, "loadBg(%s)\n", localScriptPtr + position);
+				Common::sprintf_s(lineBuffer, "loadBg(%s)\n", localScriptPtr + position);
 			} else if (opcode - 1 == 0x3D) {
-				sprintf(lineBuffer, "loadCt(%s)\n", localScriptPtr + position);
+				Common::sprintf_s(lineBuffer, "loadCt(%s)\n", localScriptPtr + position);
 			} else if (opcode - 1 == OP_loadPart) {
-				sprintf(lineBuffer, "loadPart(%s)\n", localScriptPtr + position);
+				Common::sprintf_s(lineBuffer, "loadPart(%s)\n", localScriptPtr + position);
 			}
 
 			position += strlen((const char *)localScriptPtr + position) + 1;
 			break;
 		}
 		case 0x40: {
-			sprintf(lineBuffer, "closePart()\n");
+			Common::sprintf_s(lineBuffer, "closePart()\n");
 			break;
 		}
 		case OP_loadNewPrcName: {
@@ -2614,21 +2614,21 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "loadPrc(%d,%s)\n", param, localScriptPtr + position);
+			Common::sprintf_s(lineBuffer, "loadPrc(%d,%s)\n", param, localScriptPtr + position);
 
 			position += strlen((const char *)localScriptPtr + position) + 1;
 			break;
 		}
 		case OP_requestCheckPendingDataLoad: {  // nop
-			sprintf(lineBuffer, "requestCheckPendingDataLoad()\n");
+			Common::sprintf_s(lineBuffer, "requestCheckPendingDataLoad()\n");
 			break;
 		}
 		case 0x45: {
-			sprintf(lineBuffer, "blitAndFade()\n");
+			Common::sprintf_s(lineBuffer, "blitAndFade()\n");
 			break;
 		}
 		case 0x46: {
-			sprintf(lineBuffer, "fadeToBlack()\n");
+			Common::sprintf_s(lineBuffer, "fadeToBlack()\n");
 			break;
 		}
 		case 0x47: {
@@ -2653,7 +2653,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param5 = READ_BE_UINT16(localScriptPtr + position);
 			position += 2;
 
-			sprintf(lineBuffer, "transformPaletteRange(%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5);
+			Common::sprintf_s(lineBuffer, "transformPaletteRange(%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5);
 
 			break;
 		}
@@ -2663,7 +2663,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "setDefaultMenuBgColor(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "setDefaultMenuBgColor(%d)\n", param);
 
 			break;
 		}
@@ -2680,17 +2680,17 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param3 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "palRotate(%d,%d,%d)\n", param1, param2, param3);
+			Common::sprintf_s(lineBuffer, "palRotate(%d,%d,%d)\n", param1, param2, param3);
 			break;
 		}
 
 		case 0x4F: {
-			sprintf(lineBuffer, "break()\n");
+			Common::sprintf_s(lineBuffer, "break()\n");
 			exitScript = 1;
 			break;
 		}
 		case 0x50: {
-			sprintf(lineBuffer, "endScript()\n\n");
+			Common::sprintf_s(lineBuffer, "endScript()\n\n");
 			break;
 		}
 		case 0x51: {
@@ -2715,7 +2715,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param5 = READ_BE_UINT16(localScriptPtr + position);
 			position += 2;
 
-			sprintf(lineBuffer, "message(%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5);
+			Common::sprintf_s(lineBuffer, "message(%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5);
 
 			break;
 		}
@@ -2738,17 +2738,17 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 
 				if (param2 == 1) {
 					if (opcode - 1 == 0x52) {
-						sprintf(lineBuffer, "globalVar[%d] = var[%d]\n", param1, param3);
+						Common::sprintf_s(lineBuffer, "globalVar[%d] = var[%d]\n", param1, param3);
 					} else if (opcode - 1 == 0x53) {
-						sprintf(compareString1, "globalVar[%d]", param1);
-						sprintf(compareString2, "var[%d]", param3);
+						Common::sprintf_s(compareString1, "globalVar[%d]", param1);
+						Common::sprintf_s(compareString2, "var[%d]", param3);
 					}
 				} else if (param2 == 2) {
 					if (opcode - 1 == 0x52) {
-						sprintf(lineBuffer, "globalVar[%d] = globalVar[%d]\n", param1, param3);
+						Common::sprintf_s(lineBuffer, "globalVar[%d] = globalVar[%d]\n", param1, param3);
 					} else if (opcode - 1 == 0x53) {
-						sprintf(compareString1, "globalVar[%d]", param1);
-						sprintf(compareString2, "globalVar[%d]", param3);
+						Common::sprintf_s(compareString1, "globalVar[%d]", param1);
+						Common::sprintf_s(compareString2, "globalVar[%d]", param3);
 					}
 				} else {
 					if (opcode - 1 == 0x52) {
@@ -2764,16 +2764,16 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 				position += 2;
 
 				if (opcode - 1 == 0x52) {
-					sprintf(lineBuffer, "globalVar[%d] = %d\n", param1, param3);
+					Common::sprintf_s(lineBuffer, "globalVar[%d] = %d\n", param1, param3);
 				} else if (opcode - 1 == 0x53) {
-					sprintf(compareString1, "globalVar[%d]", param1);
-					sprintf(compareString2, "%d", param3);
+					Common::sprintf_s(compareString1, "globalVar[%d]", param1);
+					Common::sprintf_s(compareString2, "%d", param3);
 				}
 			}
 			break;
 		}
 		case 0x59: {
-			sprintf(lineBuffer, "comment: %s\n", localScriptPtr + position);
+			Common::sprintf_s(lineBuffer, "comment: %s\n", localScriptPtr + position);
 
 			position += strlen((const char *)localScriptPtr + position);
 			break;
@@ -2788,16 +2788,16 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param2 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "freePartRang(%d,%d)\n", param1, param2);
+			Common::sprintf_s(lineBuffer, "freePartRang(%d,%d)\n", param1, param2);
 
 			break;
 		}
 		case 0x5B: {
-			sprintf(lineBuffer, "unloadAllMasks()\n");
+			Common::sprintf_s(lineBuffer, "unloadAllMasks()\n");
 			break;
 		}
 		case 0x65: {
-			sprintf(lineBuffer, "setupTableUnk1()\n");
+			Common::sprintf_s(lineBuffer, "setupTableUnk1()\n");
 			break;
 		}
 		case 0x66: {
@@ -2810,7 +2810,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param2 = READ_BE_UINT16(localScriptPtr + position);
 			position += 2;
 
-			sprintf(lineBuffer, "tableUnk1[%d] = %d\n", param1, param2);
+			Common::sprintf_s(lineBuffer, "tableUnk1[%d] = %d\n", param1, param2);
 
 			break;
 		}
@@ -2820,16 +2820,16 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "setPlayerCommandPosY(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "setPlayerCommandPosY(%d)\n", param);
 
 			break;
 		}
 		case 0x69: {
-			sprintf(lineBuffer, "allowPlayerInput()\n");
+			Common::sprintf_s(lineBuffer, "allowPlayerInput()\n");
 			break;
 		}
 		case 0x6A: {
-			sprintf(lineBuffer, "disallowPlayerInput()\n");
+			Common::sprintf_s(lineBuffer, "disallowPlayerInput()\n");
 			break;
 		}
 		case 0x6B: {
@@ -2838,26 +2838,26 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			newDisk = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "changeDataDisk(%d)\n", newDisk);
+			Common::sprintf_s(lineBuffer, "changeDataDisk(%d)\n", newDisk);
 
 			break;
 		}
 		case 0x6D: {
-			sprintf(lineBuffer, "loadDat(%s)\n", localScriptPtr + position);
+			Common::sprintf_s(lineBuffer, "loadDat(%s)\n", localScriptPtr + position);
 
 			position += strlen((const char *)localScriptPtr + position) + 1;
 			break;
 		}
 		case 0x6E: { // nop
-			sprintf(lineBuffer, "updateDat()\n");
+			Common::sprintf_s(lineBuffer, "updateDat()\n");
 			break;
 		}
 		case 0x6F: {
-			sprintf(lineBuffer, "OP_6F() -> dat related\n");
+			Common::sprintf_s(lineBuffer, "OP_6F() -> dat related\n");
 			break;
 		}
 		case 0x70: {
-			sprintf(lineBuffer, "stopSample()\n");
+			Common::sprintf_s(lineBuffer, "stopSample()\n");
 			break;
 		}
 		case 0x79: {
@@ -2866,7 +2866,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "disableSystemMenu(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "disableSystemMenu(%d)\n", param);
 
 			break;
 		}
@@ -2898,9 +2898,9 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			position += 2;
 
 			if (opcode - 1 == 0x77) {
-				sprintf(lineBuffer, "playSample(%d,%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5, param6);
+				Common::sprintf_s(lineBuffer, "playSample(%d,%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5, param6);
 			} else if (opcode - 1 == 0x78) {
-				sprintf(lineBuffer, "playSampleSwapped(%d,%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5, param6);
+				Common::sprintf_s(lineBuffer, "playSampleSwapped(%d,%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5, param6);
 			}
 
 			break;
@@ -2911,7 +2911,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_7A(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "OP_7A(%d)\n", param);
 
 			break;
 		}
@@ -2921,7 +2921,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_7B(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "OP_7B(%d)\n", param);
 
 			break;
 		}
@@ -2955,7 +2955,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param7 = READ_BE_UINT16(localScriptPtr + position);
 			position += 2;
 
-			sprintf(lineBuffer, "OP_7F(%d,%d,%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5, param6, param7);
+			Common::sprintf_s(lineBuffer, "OP_7F(%d,%d,%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5, param6, param7);
 
 			break;
 		}
@@ -2969,7 +2969,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param2 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_80(%d,%d)\n", param1, param2);
+			Common::sprintf_s(lineBuffer, "OP_80(%d,%d)\n", param1, param2);
 
 			break;
 		}
@@ -2995,7 +2995,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param5 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_82(%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5);
+			Common::sprintf_s(lineBuffer, "OP_82(%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5);
 
 			break;
 		}
@@ -3009,7 +3009,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param2 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_83(%d,%d)\n", param1, param2);
+			Common::sprintf_s(lineBuffer, "OP_83(%d,%d)\n", param1, param2);
 
 			break;
 		}
@@ -3019,7 +3019,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "if(%s!=%s) goto next label(%d)\n", compareString1, compareString2, param);
+			Common::sprintf_s(lineBuffer, "if(%s!=%s) goto next label(%d)\n", compareString1, compareString2, param);
 
 			break;
 		}
@@ -3029,7 +3029,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_8B(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "OP_8B(%d)\n", param);
 
 			break;
 		}
@@ -3039,7 +3039,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_8C(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "OP_8C(%d)\n", param);
 
 			break;
 		}
@@ -3077,8 +3077,8 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param8 = READ_BE_UINT16(localScriptPtr + position);
 			position += 2;
 
-			sprintf(compareString1, "obj[%d]", param1);
-			sprintf(compareString2, "{%d,%d,%d,%d,%d,%d,%d}", param2, param3, param4, param5, param6, param7, param8);
+			Common::sprintf_s(compareString1, "obj[%d]", param1);
+			Common::sprintf_s(compareString2, "{%d,%d,%d,%d,%d,%d,%d}", param2, param3, param4, param5, param6, param7, param8);
 
 			break;
 		}
@@ -3088,7 +3088,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param1 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "ADDBG(%d,%s)\n", param1, localScriptPtr + position);
+			Common::sprintf_s(lineBuffer, "ADDBG(%d,%s)\n", param1, localScriptPtr + position);
 
 			position += strlen((const char *)localScriptPtr + position);
 
@@ -3100,7 +3100,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_8F(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "OP_8F(%d)\n", param);
 
 			break;
 		}
@@ -3110,7 +3110,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param1 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "loadABS(%d,%s)\n", param1, localScriptPtr + position);
+			Common::sprintf_s(lineBuffer, "loadABS(%d,%s)\n", param1, localScriptPtr + position);
 
 			position += strlen((const char *)localScriptPtr + position);
 
@@ -3122,7 +3122,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_91(%d)\n", param);
+			Common::sprintf_s(lineBuffer, "OP_91(%d)\n", param);
 
 			break;
 		}
@@ -3132,7 +3132,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "OP_9D(%d) -> flip img idx\n", param);
+			Common::sprintf_s(lineBuffer, "OP_9D(%d) -> flip img idx\n", param);
 
 			break;
 		}
@@ -3148,14 +3148,14 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 				param2 = *(localScriptPtr + position);
 				position++;
 
-				sprintf(lineBuffer, "OP_9E(%d,%d)\n", param, param2);
+				Common::sprintf_s(lineBuffer, "OP_9E(%d,%d)\n", param, param2);
 			} else {
 				int16 param2;
 
 				param2 = READ_BE_UINT16(localScriptPtr + position);
 				position += 2;
 
-				sprintf(lineBuffer, "OP_9E(%d,%d)\n", param, param2);
+				Common::sprintf_s(lineBuffer, "OP_9E(%d,%d)\n", param, param2);
 			}
 
 			break;
@@ -3170,7 +3170,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param2 = READ_BE_UINT16(localScriptPtr + position);
 			position += 2;
 
-			sprintf(lineBuffer, "OP_A0(%d,%d)\n", param1, param2);
+			Common::sprintf_s(lineBuffer, "OP_A0(%d,%d)\n", param1, param2);
 
 			break;
 		}
@@ -3184,7 +3184,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param2 = READ_BE_UINT16(localScriptPtr + position);
 			position += 2;
 
-			sprintf(lineBuffer, "OP_A1(%d,%d)\n", param1, param2);
+			Common::sprintf_s(lineBuffer, "OP_A1(%d,%d)\n", param1, param2);
 
 			break;
 		}
@@ -3198,7 +3198,7 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param2 = READ_BE_UINT16(localScriptPtr + position);
 			position += 2;
 
-			sprintf(lineBuffer, "OP_A2(%d,%d)\n", param1, param2);
+			Common::sprintf_s(lineBuffer, "OP_A2(%d,%d)\n", param1, param2);
 
 			break;
 		}
@@ -3209,13 +3209,13 @@ void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx)
 			param1 = *(localScriptPtr + position);
 			position++;
 
-			sprintf(lineBuffer, "o2_wasZoneChecked(%d)\n", param1);
+			Common::sprintf_s(lineBuffer, "o2_wasZoneChecked(%d)\n", param1);
 
 			break;
 		}
 
 		default: {
-			sprintf(lineBuffer, "Unsupported opcode %X in decompileScript\n\n", opcode - 1);
+			Common::sprintf_s(lineBuffer, "Unsupported opcode %X in decompileScript\n\n", opcode - 1);
 			position = scriptSize;
 			break;
 		}
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index a1b0e0c3225..375e6379793 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -462,7 +462,7 @@ void CineEngine::makeSystemMenu() {
 					if (!makeMenuChoice(confirmMenu, 2, mouseX, mouseY + 8, 100)) {
 						char loadString[256];
 
-						sprintf(loadString, otherMessages[3], currentSaveName[selectedSave]);
+						Common::sprintf_s(loadString, otherMessages[3], currentSaveName[selectedSave]);
 						renderer->drawString(loadString, 0);
 
 						loadGameState(selectedSave);
@@ -530,7 +530,7 @@ void CineEngine::makeSystemMenu() {
 					fHandle->write(currentSaveName, sizeof(currentSaveName));
 					delete fHandle;
 
-					sprintf(saveString, otherMessages[3], currentSaveName[selectedSave]);
+					Common::sprintf_s(saveString, otherMessages[3], currentSaveName[selectedSave]);
 					renderer->drawString(saveString, 0);
 
 					makeSave(saveFileName, getTotalPlayTime() / 1000, Common::String((const char *)currentSaveName), false);


Commit: fe5eb4dbcd02de34b1de5c30b3e50214778f52e5
    https://github.com/scummvm/scummvm/commit/fe5eb4dbcd02de34b1de5c30b3e50214778f52e5
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
CRUISE: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/cruise/cruise.cpp
    engines/cruise/decompiler.cpp
    engines/cruise/function.cpp
    engines/cruise/overlay.cpp
    engines/cruise/volume.cpp


diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp
index 294a66e4f5e..44ee391e421 100644
--- a/engines/cruise/cruise.cpp
+++ b/engines/cruise/cruise.cpp
@@ -214,7 +214,7 @@ bool CruiseEngine::canSaveGameStateCurrently() {
 
 const char *CruiseEngine::getSavegameFile(int saveGameIdx) {
 	static char buffer[20];
-	sprintf(buffer, "cruise.s%02d", saveGameIdx);
+	Common::sprintf_s(buffer, "cruise.s%02d", saveGameIdx);
 	return buffer;
 }
 
diff --git a/engines/cruise/decompiler.cpp b/engines/cruise/decompiler.cpp
index e6caa2eed63..6c91ddf25c0 100644
--- a/engines/cruise/decompiler.cpp
+++ b/engines/cruise/decompiler.cpp
@@ -81,17 +81,17 @@ char decompSaveOpcodeVar[256];
 uint8 *getStringNameFromIdx(uint16 stringTypeIdx, char *offset) {
 	switch (stringTypeIdx & 7) {
 	case 2: {
-		sprintf(stringName, "\"%s\"",
+		Common::sprintf_s(stringName, "\"%s\"",
 		        currentScript->dataPtr +
 		        currentScript->offsetToSubData3 + atoi(offset));
 		break;
 	}
 	case 5: {
-		sprintf(stringName, "vars[%s]", offset);
+		Common::sprintf_s(stringName, "vars[%s]", offset);
 		break;
 	}
 	default: {
-		sprintf(stringName, "string[%d][%s]",
+		Common::sprintf_s(stringName, "string[%d][%s]",
 		        stringTypeIdx & 7, offset);
 		break;
 	}
@@ -105,7 +105,7 @@ char *resolveMessage(char *messageIdxString) {
 	int variable;
 
 	variable = atoi(messageIdxString);
-	sprintf(buffer, "%d", variable);
+	Common::sprintf_s(buffer, "%d", variable);
 
 	if (strcmp(buffer, messageIdxString)) {
 		return messageIdxString;
@@ -119,7 +119,7 @@ void pushDecomp(char *string, ...) {
 	va_list va;
 
 	va_start(va, string);
-	vsprintf(decompileStack[decompileStackPosition], string, va);
+	Common::vsprintf_s(decompileStack[decompileStackPosition], string, va);
 	va_end(va);
 
 	// fprintf(fHandle, "----> %s\n",decompileStack[decompileStackPosition]);
@@ -141,7 +141,7 @@ void resolveDecompShort(char *buffer) {
 		case 40:
 		case 50: {
 			if (importEntry->offset == currentDecompScriptPtr->var4 - 3) {	// param1
-				sprintf(buffer,
+				Common::sprintf_s(buffer,
 				        data3Ptr->dataPtr +
 				        data3Ptr->
 				        offsetToImportName +
@@ -149,7 +149,7 @@ void resolveDecompShort(char *buffer) {
 				return;
 			}
 			if (importEntry->offset == currentDecompScriptPtr->var4 - 6) {	// param2
-				sprintf(buffer, "linkedIdx");
+				Common::sprintf_s(buffer, "linkedIdx");
 				return;
 			}
 			break;
@@ -157,7 +157,7 @@ void resolveDecompShort(char *buffer) {
 		default: {
 			if (importEntry->offset ==
 			        currentDecompScriptPtr->var4 - 4) {
-				sprintf(buffer,
+				Common::sprintf_s(buffer,
 				        data3Ptr->dataPtr +
 				        data3Ptr->
 				        offsetToImportName +
@@ -185,7 +185,7 @@ void resolveDecompChar(char *buffer) {
 		default: {
 			if (importEntry->offset ==
 			        currentDecompScriptPtr->var4 - 2) {
-				sprintf(buffer,
+				Common::sprintf_s(buffer,
 				        data3Ptr->dataPtr +
 				        data3Ptr->
 				        offsetToImportName +
@@ -225,7 +225,7 @@ void getByteFromDecompScript(char *buffer) {
 			return;
 	}
 
-	sprintf(buffer, "%d", var);
+	Common::sprintf_s(buffer, "%d", var);
 }
 
 char getByteFromDecompScriptReal() {
@@ -248,7 +248,7 @@ void getShortFromDecompScript(char *buffer) {
 			return;
 	}
 
-	sprintf(buffer, "%d", var);
+	Common::sprintf_s(buffer, "%d", var);
 }
 
 int16 getShortFromDecompScriptReal() {
@@ -280,7 +280,7 @@ void addDecomp(char *string, ...) {
 	pLineStruct->pendingElse = 0;
 
 	va_start(va, string);
-	vsprintf(pLineStruct->line, string, va);
+	Common::vsprintf_s(pLineStruct->line, string, va);
 	va_end(va);
 
 	currentLineIdx = currentDecompScriptPtr->var4;
@@ -308,7 +308,7 @@ void resolveVarName(char *ovlIdxString, int varType, char *varIdxString,
 		return;
 	}
 	if (varType == 1) {
-		sprintf(outputName, "localVar_%s", varIdxString);
+		Common::sprintf_s(outputName, "localVar_%s", varIdxString);
 		return;
 	}
 
@@ -331,7 +331,7 @@ void resolveVarName(char *ovlIdxString, int varType, char *varIdxString,
 				}
 			}
 		}
-		sprintf(outputName, "ovl(%s).[%d][%s]", ovlIdxString, varType,
+		Common::sprintf_s(outputName, "ovl(%s).[%d][%s]", ovlIdxString, varType,
 		        varIdxString);
 	} else {
 		Common::strcpy_s(outputName, 256,  ovlIdxString);
@@ -535,44 +535,44 @@ int decompMath() {
 
 	switch (currentScriptOpcodeType) {
 	case 0: {
-		sprintf(tempbuffer, "%s+%s", param1, param2);
+		Common::sprintf_s(tempbuffer, "%s+%s", param1, param2);
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 1: {
-		sprintf(tempbuffer, "%s/%s", param1, param2);
+		Common::sprintf_s(tempbuffer, "%s/%s", param1, param2);
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 2: {
-		sprintf(tempbuffer, "%s-%s", param1, param2);
+		Common::sprintf_s(tempbuffer, "%s-%s", param1, param2);
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 3: {
-		sprintf(tempbuffer, "%s*%s", param1, param2);
+		Common::sprintf_s(tempbuffer, "%s*%s", param1, param2);
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 4: {
-		sprintf(tempbuffer, "%s % %s", param1, param2);
+		Common::sprintf_s(tempbuffer, "%s % %s", param1, param2);
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 5:
 	case 7: {
-		sprintf(tempbuffer, "%s|%s", param1, param2);
+		Common::sprintf_s(tempbuffer, "%s|%s", param1, param2);
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 6: {
-		sprintf(tempbuffer, "%s&%s", param1, param2);
+		Common::sprintf_s(tempbuffer, "%s&%s", param1, param2);
 		pushDecomp(tempbuffer);
 		break;
 	}
 
 	default: {
-		sprintf(tempbuffer, "decompMath(%d,%s,%s)",
+		Common::sprintf_s(tempbuffer, "decompMath(%d,%s,%s)",
 		        currentScriptOpcodeType, param1, param2);
 		pushDecomp(tempbuffer);
 		break;
@@ -588,7 +588,7 @@ int decompBoolCompare() {
 	param1 = popDecomp();
 	param2 = popDecomp();
 
-	sprintf(tempbuffer, "compare(%s,%s)", param1, param2);
+	Common::sprintf_s(tempbuffer, "compare(%s,%s)", param1, param2);
 	pushDecomp(tempbuffer);
 
 	return 0;
@@ -707,17 +707,17 @@ int decompFunction() {
 		break;
 
 	case 0x3:
-		sprintf(tempbuffer, "Op_loadBackground(%s,%s)", popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_loadBackground(%s,%s)", popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x4:
-		sprintf(tempbuffer, "Op_LoadAbs(%s,%s)", popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_LoadAbs(%s,%s)", popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x5:
-		sprintf(tempbuffer, "Op_AddCell(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_AddCell(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
@@ -729,7 +729,7 @@ int decompFunction() {
 		char *ovlStr = popDecomp();
 
 		resolveVarName(ovlStr, 0x20, idxStr, functionName);
-		sprintf(tempbuffer, "Op_AddProc(%s", functionName);
+		Common::sprintf_s(tempbuffer, "Op_AddProc(%s", functionName);
 
 		for (int i = 0; i < numArg; i++) {
 			strcatuint8(tempbuffer, ",");
@@ -747,13 +747,13 @@ int decompFunction() {
 		char *objIdxStr = popDecomp();
 		char *ovlStr = popDecomp();
 
-		sprintf(tempbuffer, "Op_InitializeState(ovl:%s,dataIdx:%s,%s)", ovlStr, objIdxStr, var1);
+		Common::sprintf_s(tempbuffer, "Op_InitializeState(ovl:%s,dataIdx:%s,%s)", ovlStr, objIdxStr, var1);
 		pushDecomp(tempbuffer);
 		break;
 		}
 
 	case 0x8:
-		sprintf(tempbuffer, "Op_RemoveCell(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_RemoveCell(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
@@ -762,48 +762,48 @@ int decompFunction() {
 		break;
 
 	case 0xA:
-		sprintf(tempbuffer, "Op_RemoveProc(ovl(%s),%s)", popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_RemoveProc(ovl(%s),%s)", popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0xB:
-		sprintf(tempbuffer, "Op_RemoveFrame(%s,%s)", popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_RemoveFrame(%s,%s)", popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0xC:
-		sprintf(tempbuffer, "Op_LoadOverlay(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_LoadOverlay(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0xD:
-		sprintf(tempbuffer, "Op_SetColor(%s,%s,%s,%s,%s)", popDecomp(), popDecomp(), popDecomp(), popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_SetColor(%s,%s,%s,%s,%s)", popDecomp(), popDecomp(), popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0xE:
-		sprintf(tempbuffer, "Op_PlayFX(%s,%s,%s,%s)", popDecomp(), popDecomp(), popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_PlayFX(%s,%s,%s,%s)", popDecomp(), popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x10:
-		sprintf(tempbuffer, "Op_FreeOverlay(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_FreeOverlay(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x11:
-		sprintf(tempbuffer, "Op_FindOverlay(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_FindOverlay(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x13:
-		sprintf(tempbuffer, "Op_AddMessage(%s,\"%s\",%s,%s,%s,%s)", popDecomp(),
+		Common::sprintf_s(tempbuffer, "Op_AddMessage(%s,\"%s\",%s,%s,%s,%s)", popDecomp(),
 			resolveMessage(popDecomp()), popDecomp(),  popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x14:
-		sprintf(tempbuffer, "Op_RemoveMessage(ovl(%s),%s)", popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_RemoveMessage(ovl(%s),%s)", popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
@@ -812,66 +812,66 @@ int decompFunction() {
 		break;
 
 	case 0x16:
-		sprintf(tempbuffer, "Op_FreezeCell(%s,%s,%s,%s,%s,%s)", popDecomp(), popDecomp(),
+		Common::sprintf_s(tempbuffer, "Op_FreezeCell(%s,%s,%s,%s,%s,%s)", popDecomp(), popDecomp(),
 			popDecomp(), popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x17:
-		sprintf(tempbuffer, "Op_LoadCt(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_LoadCt(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x18:
-		sprintf(tempbuffer, "Op_AddAnimation(%s,%s,%s,%s,%s,%s,%s)", popDecomp(), popDecomp(),
+		Common::sprintf_s(tempbuffer, "Op_AddAnimation(%s,%s,%s,%s,%s,%s,%s)", popDecomp(), popDecomp(),
 			popDecomp(), popDecomp(), popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x19:
-		sprintf(tempbuffer, "Op_RemoveAnimation(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_RemoveAnimation(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x1A:
-		sprintf(tempbuffer, "Op_SetZoom(%s,%s,%s,%s)", popDecomp(), popDecomp(), popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_SetZoom(%s,%s,%s,%s)", popDecomp(), popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x1E:
-		sprintf(tempbuffer, "Op_TrackAnim(%s,%s,%s,%s,%s,%s)", popDecomp(), popDecomp(),
+		Common::sprintf_s(tempbuffer, "Op_TrackAnim(%s,%s,%s,%s,%s,%s)", popDecomp(), popDecomp(),
 			popDecomp(), popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x21:
-		sprintf(tempbuffer, "Op_EndAnim(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_EndAnim(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x22:
-		sprintf(tempbuffer, "Op_GetZoom(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_GetZoom(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x23:
-		sprintf(tempbuffer, "Op_GetStep(%s,%s)", popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_GetStep(%s,%s)", popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x24:
-		sprintf(tempbuffer, "Op_SetStringColors(%s,%s,%s,%s)", popDecomp(), popDecomp(),
+		Common::sprintf_s(tempbuffer, "Op_SetStringColors(%s,%s,%s,%s)", popDecomp(), popDecomp(),
 			popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x27:
-		sprintf(tempbuffer, "Op_getPixel(%s,%s)", popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_getPixel(%s,%s)", popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x28:
-		sprintf(tempbuffer, "Op_UserOn(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_UserOn(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
@@ -880,33 +880,33 @@ int decompFunction() {
 		break;
 
 	case 0x2B:
-		sprintf(tempbuffer, "Op_FindProc(%s,%s)", popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_FindProc(%s,%s)", popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x2C:
-		sprintf(tempbuffer, "Op_WriteObject(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_WriteObject(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x2E:
-		sprintf(tempbuffer, "Op_RemoveOverlay(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_RemoveOverlay(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x2F:
-		sprintf(tempbuffer, "Op_AddBackgroundIncrust(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
+		Common::sprintf_s(tempbuffer, "Op_AddBackgroundIncrust(%s,%s,%s)", popDecomp(), popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 
 	case 0x30: {
-		sprintf(tempbuffer, "_removeBackgroundIncrust(%s,%s)",
+		Common::sprintf_s(tempbuffer, "_removeBackgroundIncrust(%s,%s)",
 		        popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x31: {
-		sprintf(tempbuffer, "_op_31(%s,%s)", popDecomp(),
+		Common::sprintf_s(tempbuffer, "_op_31(%s,%s)", popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
@@ -916,30 +916,30 @@ int decompFunction() {
 		break;
 	}
 	case 0x35: {
-		sprintf(tempbuffer, "_op35(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_op35(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x37: {
-		sprintf(tempbuffer, "_op37(%s,%s)", popDecomp(),
+		Common::sprintf_s(tempbuffer, "_op37(%s,%s)", popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x38: {
-		sprintf(tempbuffer, "_removeBackground(%s)",
+		Common::sprintf_s(tempbuffer, "_removeBackground(%s)",
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x39: {
-		sprintf(tempbuffer, "_SetActiveBackgroundPlane(%s)",
+		Common::sprintf_s(tempbuffer, "_SetActiveBackgroundPlane(%s)",
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x3A: {
-		sprintf(tempbuffer, "_setVar49(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_setVar49(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
@@ -948,12 +948,12 @@ int decompFunction() {
 		break;
 	}
 	case 0x3C: {
-		sprintf(tempbuffer, "_rand(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_rand(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x3D: {
-		sprintf(tempbuffer, "_loadMusic(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_loadMusic(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
@@ -970,7 +970,7 @@ int decompFunction() {
 		break;
 	}
 	case 0x41: {
-		sprintf(tempbuffer, "_isFileLoaded2(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_isFileLoaded2(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
@@ -979,17 +979,17 @@ int decompFunction() {
 		break;
 	}
 	case 0x49: {
-		sprintf(tempbuffer, "_op49(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_op49(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x54: {
-		sprintf(tempbuffer, "_setFontVar(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_setFontVar(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x56: {
-		sprintf(tempbuffer, "_changeCutSceneState(%s)",
+		Common::sprintf_s(tempbuffer, "_changeCutSceneState(%s)",
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
@@ -1007,7 +1007,7 @@ int decompFunction() {
 		break;
 	}
 	case 0x5A: {
-		sprintf(tempbuffer, "_isFileLoaded(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_isFileLoaded(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
@@ -1016,25 +1016,25 @@ int decompFunction() {
 		break;
 	}
 	case 0x5C: {
-		sprintf(tempbuffer, "_Op_AddCellC(%s,%s)", popDecomp(),
+		Common::sprintf_s(tempbuffer, "_Op_AddCellC(%s,%s)", popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x5E: {
-		sprintf(tempbuffer, "_Op_AddCellE(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_Op_AddCellE(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x60: {
-		sprintf(tempbuffer, "_op_60(%s,%s,%s,%s,%s)",
+		Common::sprintf_s(tempbuffer, "_op_60(%s,%s,%s,%s,%s)",
 		        popDecomp(), popDecomp(), popDecomp(), popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x61: {
-		sprintf(tempbuffer, "_op61(%s,%s)", popDecomp(),
+		Common::sprintf_s(tempbuffer, "_op61(%s,%s)", popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
@@ -1058,7 +1058,7 @@ int decompFunction() {
 
 		resolveVarName(ovlStr, 0x20, idxStr, functionName);
 
-		sprintf(tempbuffer, "%s(", functionName);
+		Common::sprintf_s(tempbuffer, "%s(", functionName);
 
 		for (int i = 0; i < numArg; i++) {
 			if (i)
@@ -1072,7 +1072,7 @@ int decompFunction() {
 		break;
 	}
 	case 0x65: {
-		sprintf(tempbuffer,
+		Common::sprintf_s(tempbuffer,
 		        "_addWaitObject(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
 		        popDecomp(), popDecomp(), popDecomp(), popDecomp(),
 		        popDecomp(), popDecomp(), popDecomp(), popDecomp(),
@@ -1081,13 +1081,13 @@ int decompFunction() {
 		break;
 	}
 	case 0x66: {
-		sprintf(tempbuffer, "_op_66(%s,%s)", popDecomp(),
+		Common::sprintf_s(tempbuffer, "_op_66(%s,%s)", popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x67: {
-		sprintf(tempbuffer, "_loadAudioResource(%s,%s)",
+		Common::sprintf_s(tempbuffer, "_loadAudioResource(%s,%s)",
 		        popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
@@ -1097,31 +1097,31 @@ int decompFunction() {
 		break;
 	}
 	case 0x6A: {
-		sprintf(tempbuffer, "_op_6A(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_op_6A(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x6B: {
-		sprintf(tempbuffer, "_loadData(%s,%s,%s,%s)",
+		Common::sprintf_s(tempbuffer, "_loadData(%s,%s,%s,%s)",
 		        popDecomp(), popDecomp(), popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x6C: {
-		sprintf(tempbuffer, "_op_6C(%s,%s)", popDecomp(),
+		Common::sprintf_s(tempbuffer, "_op_6C(%s,%s)", popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x6D: {
-		sprintf(tempbuffer, "_strcpy(%s,%s)", popDecomp(),
+		Common::sprintf_s(tempbuffer, "_strcpy(%s,%s)", popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x6E: {
-		sprintf(tempbuffer, "_op_6E(%s,%s)", popDecomp(),
+		Common::sprintf_s(tempbuffer, "_op_6E(%s,%s)", popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
@@ -1134,7 +1134,7 @@ int decompFunction() {
 		idxStr = popDecomp();
 		ovlStr = popDecomp();
 
-		sprintf(tempbuffer, "_op_6F(%s,%s", idxStr, ovlStr);
+		Common::sprintf_s(tempbuffer, "_op_6F(%s,%s", idxStr, ovlStr);
 
 		for (int i = 0; i < numArg; i++) {
 			strcatuint8(tempbuffer, ",");
@@ -1147,65 +1147,65 @@ int decompFunction() {
 		break;
 	}
 	case 0x70: {
-		sprintf(tempbuffer, "_comment(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_comment(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x71: {
-		sprintf(tempbuffer, "_op71(%s,%s,%s,%s,%s)",
+		Common::sprintf_s(tempbuffer, "_op71(%s,%s,%s,%s,%s)",
 		        popDecomp(), popDecomp(), popDecomp(), popDecomp(),
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x72: {
-		sprintf(tempbuffer, "_op72(%s,%s)", popDecomp(),
+		Common::sprintf_s(tempbuffer, "_op72(%s,%s)", popDecomp(),
 		        popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x73: {
-		sprintf(tempbuffer, "_op73(%s)", popDecomp());
+		Common::sprintf_s(tempbuffer, "_op73(%s)", popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x74: {
-		sprintf(tempbuffer, "_getlowMemory()");
+		Common::sprintf_s(tempbuffer, "_getlowMemory()");
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x76: {
-		sprintf(tempbuffer, "_Op_InitializeState6(%s,%s)",
+		Common::sprintf_s(tempbuffer, "_Op_InitializeState6(%s,%s)",
 		        popDecomp(), popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x77: {
-		sprintf(tempbuffer, "_Op_InitializeState7(%s)",
+		Common::sprintf_s(tempbuffer, "_Op_InitializeState7(%s)",
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x78: {
-		sprintf(tempbuffer, "_Op_InitializeState8(%s)",
+		Common::sprintf_s(tempbuffer, "_Op_InitializeState8(%s)",
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x79: {
-		sprintf(tempbuffer, "_EnterPlayerMenu(%s)",
+		Common::sprintf_s(tempbuffer, "_EnterPlayerMenu(%s)",
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x7B: {
-		sprintf(tempbuffer, "_Op_InitializeStateB(%s)",
+		Common::sprintf_s(tempbuffer, "_Op_InitializeStateB(%s)",
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
 	}
 	case 0x7C: {
-		sprintf(tempbuffer, "_Op_InitializeStateC(%s)",
+		Common::sprintf_s(tempbuffer, "_Op_InitializeStateC(%s)",
 		        popDecomp());
 		pushDecomp(tempbuffer);
 		break;
@@ -1285,7 +1285,7 @@ void dumpScript(uint8 *ovlName, ovlDataStruct *ovlData, int idx) {
 	char temp[256];
 	char scriptName[256];
 
-	sprintf(temp, "%d", idx);
+	Common::sprintf_s(temp, "%d", idx);
 
 	failed = 0;
 
@@ -1314,7 +1314,7 @@ void dumpScript(uint8 *ovlName, ovlDataStruct *ovlData, int idx) {
 
 	stop = 0;
 
-	sprintf(buffer, "%s-%02d-%s.txt", ovlName, idx, scriptName);
+	Common::sprintf_s(buffer, "%s-%02d-%s.txt", ovlName, idx, scriptName);
 	fHandle = fopen(buffer, "w+");
 
 	decompileStackPosition = 0;
diff --git a/engines/cruise/function.cpp b/engines/cruise/function.cpp
index a5d04bdb512..48d6d087d57 100644
--- a/engines/cruise/function.cpp
+++ b/engines/cruise/function.cpp
@@ -1524,13 +1524,13 @@ int16 Op_Itoa() {
 	char* pDest = (char *)popPtr();
 
 	if (!nbp)
-		sprintf(txt, "%d", val);
+		Common::sprintf_s(txt, "%d", val);
 	else {
 		char format[30];
 		format[0] = '%';
-		sprintf(&format[1], "%d", param[0]);
+		Common::sprintf_s(&format[1], sizeof(format) - 1, "%d", param[0]);
 		Common::strcat_s(format, "d");
-		sprintf(txt, format, val);
+		Common::sprintf_s(txt, format, val);
 	}
 
 	for (int i = 0; txt[i]; i++)
diff --git a/engines/cruise/overlay.cpp b/engines/cruise/overlay.cpp
index f8dcd6eb2d9..016b6d7c26c 100644
--- a/engines/cruise/overlay.cpp
+++ b/engines/cruise/overlay.cpp
@@ -622,7 +622,7 @@ int loadOverlay(const char *scriptName) {
 		// TODO: Rewrite this to use Common::DumpFile
 		FILE *fHandle;
 		char nameBundle[100];
-		sprintf(nameBundle, "%s-objs.txt", scriptName);
+		Common::sprintf_s(nameBundle, "%s-objs.txt", scriptName);
 
 		fHandle = fopen(nameBundle, "w+");
 		assert(fHandle);
diff --git a/engines/cruise/volume.cpp b/engines/cruise/volume.cpp
index 0724e2dd2af..eef3ab2941e 100644
--- a/engines/cruise/volume.cpp
+++ b/engines/cruise/volume.cpp
@@ -206,8 +206,8 @@ void askDisk(int16 discNumber) {
 		currentDiskNumber = discNumber;
 	}
 
-	sprintf(fileName, "VOL.%d", currentDiskNumber);
-	sprintf(string, "INSERER LE DISQUE %d EN ", currentDiskNumber);
+	Common::sprintf_s(fileName, "VOL.%d", currentDiskNumber);
+	Common::sprintf_s(string, "INSERER LE DISQUE %d EN ", currentDiskNumber);
 
 #if 0 // skip drive selection stuff
 	bool messageDrawn = false;
@@ -371,7 +371,7 @@ int16 readVolCnf() {
 		char nameBuffer[256];
 		fileEntry *buffer;
 
-		sprintf(nameBuffer, "D%d.", i + 1);
+		Common::sprintf_s(nameBuffer, "D%d.", i + 1);
 
 		fileHandle.open(nameBuffer);
 
@@ -400,7 +400,7 @@ int16 readVolCnf() {
 
 			char nameBuffer[256];
 
-			sprintf(nameBuffer, "%s", buffer[j].name);
+			Common::sprintf_s(nameBuffer, "%s", buffer[j].name);
 
 			if (buffer[j].size == buffer[j].extSize) {
 				Common::DumpFile fout;


Commit: 29dea747a81f88643cf5131e29c824bc2c541aa1
    https://github.com/scummvm/scummvm/commit/29dea747a81f88643cf5131e29c824bc2c541aa1
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
DIRECTOR: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/director/archive.cpp


diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
index 285c28bef21..348180d1a7a 100644
--- a/engines/director/archive.cpp
+++ b/engines/director/archive.cpp
@@ -568,7 +568,7 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
 		Common::DumpFile out;
 
 		char buf[256];
-		sprintf(buf, "./dumps/%s-%08x", encodePathForDump(g_director->getEXEName()).c_str(), startOffset);
+		Common::sprintf_s(buf, "./dumps/%s-%08x", encodePathForDump(g_director->getEXEName()).c_str(), startOffset);
 
 		if (out.open(buf, true)) {
 			out.write(dumpData, sz);
@@ -753,7 +753,7 @@ bool RIFXArchive::readAfterburnerMap(Common::SeekableReadStreamEndian &stream, u
 		Common::DumpFile out;
 
 		char buf[256];
-		sprintf(buf, "./dumps/%s-%s", encodePathForDump(g_director->getEXEName()).c_str(), "ABMP");
+		Common::sprintf_s(buf, "./dumps/%s-%s", encodePathForDump(g_director->getEXEName()).c_str(), "ABMP");
 
 		if (out.open(buf, true)) {
 			byte *data = (byte *)malloc(abmpStream->size());


Commit: fcda5809b827a5ee862ba5ec023a86f67eb05e31
    https://github.com/scummvm/scummvm/commit/fcda5809b827a5ee862ba5ec023a86f67eb05e31
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
DRAGONS: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/dragons/scene.cpp
    engines/dragons/talk.cpp


diff --git a/engines/dragons/scene.cpp b/engines/dragons/scene.cpp
index e362ea2fea8..6289cef8b8b 100644
--- a/engines/dragons/scene.cpp
+++ b/engines/dragons/scene.cpp
@@ -487,7 +487,7 @@ void Scene::drawActorNumber(int16 x, int16 y, uint16 actorId) {
 	uint16 text[30];
 	char text8[15];
 
-	sprintf(text8, "%d", actorId);
+	Common::sprintf_s(text8, "%d", actorId);
 
 	for (uint i = 0; i < strlen(text8); i++) {
 		text[i] = text8[i];
diff --git a/engines/dragons/talk.cpp b/engines/dragons/talk.cpp
index 8adbd7da69c..68c4bbbdb5d 100644
--- a/engines/dragons/talk.cpp
+++ b/engines/dragons/talk.cpp
@@ -58,7 +58,7 @@ bool Talk::loadText(uint32 textIndex, uint16 *textBuffer, uint16 bufferLength) {
 	uint32 fileNo = (textIndex >> 0xc) & 0xffff;
 	uint32 fileOffset = textIndex & 0xfff;
 
-	sprintf(filename, "drag%04d.txt", fileNo);
+	Common::sprintf_s(filename, "drag%04d.txt", fileNo);
 	uint32 size;
 	byte *data = _bigfileArchive->load(filename, size);
 	debug(1, "DIALOG: %s, %s, %d", filename, data, fileOffset);


Commit: 8373886eb9bd8b761c46ea7f2aaaafd90ec586d0
    https://github.com/scummvm/scummvm/commit/8373886eb9bd8b761c46ea7f2aaaafd90ec586d0
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
DRASCULA: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/drascula/animation.cpp
    engines/drascula/converse.cpp
    engines/drascula/drascula.h
    engines/drascula/rooms.cpp
    engines/drascula/sound.cpp
    engines/drascula/talk.cpp


diff --git a/engines/drascula/animation.cpp b/engines/drascula/animation.cpp
index 67998babea7..facb897f2dc 100644
--- a/engines/drascula/animation.cpp
+++ b/engines/drascula/animation.cpp
@@ -761,7 +761,7 @@ void DrasculaEngine::animation_16_2() {
 
 	for (int i = 1; i <= 4; i++) {
 		if (i < 4)
-			sprintf(curPic, "his%i.alg", i);
+			Common::sprintf_s(curPic, "his%i.alg", i);
 		else
 			Common::strcpy_s(curPic, "his4_2.alg");
 
diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp
index 016b5e05f15..9712864da1f 100644
--- a/engines/drascula/converse.cpp
+++ b/engines/drascula/converse.cpp
@@ -132,7 +132,7 @@ void DrasculaEngine::converse(int index) {
 	debug(4, "converse(%d)", index);
 
 	char fileName[20];
-	sprintf(fileName, "op_%d.cal", index);
+	Common::sprintf_s(fileName, "op_%d.cal", index);
 	Common::SeekableReadStream *stream = _archives.open(fileName);
 	if (!stream)
 		error("missing data file %s", fileName);
diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h
index 00e96c5026a..1fa63685661 100644
--- a/engines/drascula/drascula.h
+++ b/engines/drascula/drascula.h
@@ -345,7 +345,7 @@ public:
 
 	void loadPic(int roomNum, byte *targetSurface, int colorCount = 1) {
 		char rm[20];
-		sprintf(rm, "%i.alg", roomNum);
+		Common::sprintf_s(rm, "%i.alg", roomNum);
 		loadPic(rm, targetSurface, colorCount);
 	}
 
diff --git a/engines/drascula/rooms.cpp b/engines/drascula/rooms.cpp
index 32415202d25..a5c08094895 100644
--- a/engines/drascula/rooms.cpp
+++ b/engines/drascula/rooms.cpp
@@ -1106,7 +1106,7 @@ void DrasculaEngine::updateRefresh() {
 
 	// Call room-specific updater
 	char rm[20];
-	sprintf(rm, "update_%d", _roomNumber);
+	Common::sprintf_s(rm, "update_%d", _roomNumber);
 	for (uint i = 0; i < _roomHandlers->roomUpdaters.size(); i++) {
 		if (!strcmp(rm, _roomHandlers->roomUpdaters[i]->desc)) {
 			debug(8, "Calling room updater %d", _roomNumber);
@@ -1144,7 +1144,7 @@ void DrasculaEngine::updateRefresh_pre() {
 
 	// Call room-specific preupdater
 	char rm[20];
-	sprintf(rm, "update_%d_pre", _roomNumber);
+	Common::sprintf_s(rm, "update_%d_pre", _roomNumber);
 	for (uint i = 0; i < _roomHandlers->roomPreupdaters.size(); i++) {
 		if (!strcmp(rm, _roomHandlers->roomPreupdaters[i]->desc)) {
 			debug(8, "Calling room preupdater %d", _roomNumber);
@@ -1642,7 +1642,7 @@ bool DrasculaEngine::room(int rN, int fl) {
 	if (!roomParse(rN, fl)) {
 		// Call room-specific parser
 		char rm[20];
-		sprintf(rm, "room_%d", rN);
+		Common::sprintf_s(rm, "room_%d", rN);
 		for (uint i = 0; i < _roomHandlers->roomParsers.size(); i++) {
 			if (!strcmp(rm, _roomHandlers->roomParsers[i]->desc)) {
 				debug(4, "Calling room parser %d", rN);
@@ -1663,7 +1663,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
 	showCursor();
 
 	char fileName[20];
-	sprintf(fileName, "%d.ald", roomIndex);
+	Common::sprintf_s(fileName, "%d.ald", roomIndex);
 	int soc, l, overridenWidth = 0, objIsExit = 0;
 	float chiquez = 0, pequegnez = 0;
 	char surfaceName[20];
diff --git a/engines/drascula/sound.cpp b/engines/drascula/sound.cpp
index 4e1c7823b7a..5234181a7ba 100644
--- a/engines/drascula/sound.cpp
+++ b/engines/drascula/sound.cpp
@@ -166,7 +166,7 @@ void DrasculaEngine::volumeControls() {
 
 void DrasculaEngine::playSound(int soundNum) {
 	char file[20];
-	sprintf(file, "s%i.als", soundNum);
+	Common::sprintf_s(file, "s%i.als", soundNum);
 
 	playFile(file);
 }
diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp
index ad0e918e158..73309044e46 100644
--- a/engines/drascula/talk.cpp
+++ b/engines/drascula/talk.cpp
@@ -62,7 +62,7 @@ bool DrasculaEngine::isTalkFinished() {
 // 4: talk_igor_wig
 void DrasculaEngine::talk_igor(int index, int talkerType) {
 	char filename[20];
-	sprintf(filename, "I%i.als", index);
+	Common::sprintf_s(filename, "I%i.als", index);
 	const char *said = _texti[index];
 	static const int x_talk0[8] = {  56,  82, 108, 134, 160, 186, 212, 238 };
 	static const int x_talk1[8] = {  56,  86, 116, 146, 176, 206, 236, 266 };
@@ -145,7 +145,7 @@ void DrasculaEngine::talk_igor(int index, int talkerType) {
 void DrasculaEngine::talk_drascula(int index, int talkerType) {
 	const char *said = _textd[index];
 	char filename[20];
-	sprintf(filename, "d%i.als", index);
+	Common::sprintf_s(filename, "d%i.als", index);
 	int x_talk[8] = { 1, 40, 79, 118, 157, 196, 235, 274 };
 	int face;
 	int offset = (talkerType == 0) ? 0 : 7;
@@ -202,7 +202,7 @@ void DrasculaEngine::talk_drascula(int index, int talkerType) {
 
 void DrasculaEngine::talk_drascula_big(int index) {
 	char filename[20];
-	sprintf(filename, "d%i.als", index);
+	Common::sprintf_s(filename, "d%i.als", index);
 	const char *said = _textd[index];
 	int x_talk[4] = {47, 93, 139, 185};
 	int face;
@@ -269,14 +269,14 @@ void DrasculaEngine::talk_solo(const char *said, const char *filename) {
 
 void DrasculaEngine::talk_bartender(int index, int talkerType) {
 	char filename[20];
-	sprintf(filename, "t%i.als", index);
+	Common::sprintf_s(filename, "t%i.als", index);
 	const char *said;
 
 	// Line 82 is a special case
 	if (index != 82)
 		said = _textt[index];
 	else {
-		sprintf(filename, "d%i.als", index);
+		Common::sprintf_s(filename, "d%i.als", index);
 		said = _textd[index];
 	}
 
@@ -328,7 +328,7 @@ void DrasculaEngine::talk_bartender(int index, int talkerType) {
 
 void DrasculaEngine::talk_bj(int index) {
 	char filename[20];
-	sprintf(filename, "BJ%i.als", index);
+	Common::sprintf_s(filename, "BJ%i.als", index);
 	const char *said = _textbj[index];
 	int x_talk[5] = { 64, 92, 120, 148, 176 };
 	int face;
@@ -374,7 +374,7 @@ void DrasculaEngine::talk_bj(int index) {
 
 void DrasculaEngine::talk(int index) {
 	char name[20];
-	sprintf(name, "%i.als", index);
+	Common::sprintf_s(name, "%i.als", index);
 	talk(_text[index], name);
 }
 
@@ -514,7 +514,7 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
 
 void DrasculaEngine::talk_pianist(int index) {
 	char filename[20];
-	sprintf(filename, "P%i.als", index);
+	Common::sprintf_s(filename, "P%i.als", index);
 	const char* said = _textp[index];
 	int x_talk[4] = { 97, 145, 193, 241 };
 	int coords[7] = { 139, 228, 112, 47, 60, 221, 128 };
@@ -525,7 +525,7 @@ void DrasculaEngine::talk_pianist(int index) {
 
 void DrasculaEngine::talk_drunk(int index) {
 	char filename[20];
-	sprintf(filename, "B%i.als", index);
+	Common::sprintf_s(filename, "B%i.als", index);
 	const char *said = _textb[index];
 	int x_talk[8] = { 1, 21, 41, 61, 81, 101, 121, 141 };
 	int coords[7] = { 29, 177, 50, 19, 19, 181, 54 };
@@ -562,7 +562,7 @@ void DrasculaEngine::talk_drunk(int index) {
 // 1: KVonBraunDoor
 void DrasculaEngine::talk_vonBraun(int index, int talkerType) {
 	char filename[20];
-	sprintf(filename, "VB%i.als", index);
+	Common::sprintf_s(filename, "VB%i.als", index);
 	const char *said = _textvb[index];
 	int x_talk[6] = {1, 27, 53, 79, 105, 131};
 	int face;
@@ -612,7 +612,7 @@ void DrasculaEngine::talk_blind(int index) {
 	// Also, the blind man's texts in the first array and his
 	// voice files start from 58, not 1
 	char filename[20];
-	sprintf(filename, "d%i.als", index + TEXTD_START - 1);
+	Common::sprintf_s(filename, "d%i.als", index + TEXTD_START - 1);
 	const char *said = _textd[index + TEXTD_START - 1];
 	const char *syncChar = _textd1[index - 1];
 
@@ -660,7 +660,7 @@ void DrasculaEngine::talk_blind(int index) {
 
 void DrasculaEngine::talk_hacker(int index) {
 	char filename[20];
-	sprintf(filename, "d%i.als", index);
+	Common::sprintf_s(filename, "d%i.als", index);
 	const char *said = _textd[index];
 
 	copyBackground();
@@ -681,7 +681,7 @@ void DrasculaEngine::talk_hacker(int index) {
 
 void DrasculaEngine::talk_werewolf(int index) {
 	char filename[20];
-	sprintf(filename, "L%i.als", index);
+	Common::sprintf_s(filename, "L%i.als", index);
 	const char *said = _textl[index];
 	int x_talk[9] = {52, 79, 106, 133, 160, 187, 214, 241, 268};
 	int coords[7] = { 136, 198, 81, 26, 24, 203, 78 };
@@ -692,7 +692,7 @@ void DrasculaEngine::talk_werewolf(int index) {
 
 void DrasculaEngine::talk_mus(int index) {
 	char filename[20];
-	sprintf(filename, "E%i.als", index);
+	Common::sprintf_s(filename, "E%i.als", index);
 	const char *said = _texte[index];
 	int x_talk[8] = { 16, 35, 54, 73, 92, 111, 130, 149};
 	int coords[7] = { 156, 190, 64, 18, 24, 197, 64 };
@@ -755,7 +755,7 @@ void DrasculaEngine::talk_pen(const char *said, const char *filename, int talker
 
 void DrasculaEngine::talk_bj_bed(int index) {
 	char filename[20];
-	sprintf(filename, "BJ%i.als", index);
+	Common::sprintf_s(filename, "BJ%i.als", index);
 	const char *said = _textbj[index];
 	int x_talk[5] = {51, 101, 151, 201, 251};
 	int face;
@@ -791,7 +791,7 @@ void DrasculaEngine::talk_bj_bed(int index) {
 
 void DrasculaEngine::talk_htel(int index) {
 	char filename[20];
-	sprintf(filename, "%i.als", index);
+	Common::sprintf_s(filename, "%i.als", index);
 	const char *said = _text[index];
 	int x_talk[3] = {1, 94, 187};
 	int face, curScreen;
@@ -913,7 +913,7 @@ void DrasculaEngine::talk_sync(const char *said, const char *filename, const cha
 
 void DrasculaEngine::talk_trunk(int index) {
 	char filename[20];
-	sprintf(filename, "d%i.als", index);
+	Common::sprintf_s(filename, "d%i.als", index);
 	const char *said = _text[index];
 	int face = 0, cara_antes;
 


Commit: 4282dec6f68b6e97423b3133c186f8dd5d30afa8
    https://github.com/scummvm/scummvm/commit/4282dec6f68b6e97423b3133c186f8dd5d30afa8
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
DREAMWEB: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/dreamweb/use.cpp


diff --git a/engines/dreamweb/use.cpp b/engines/dreamweb/use.cpp
index da7c9109efa..72094d978c7 100644
--- a/engines/dreamweb/use.cpp
+++ b/engines/dreamweb/use.cpp
@@ -1520,10 +1520,10 @@ void DreamWebEngine::useCashCard() {
 	y = 98;
 	printDirect(&obText, 36, &y, 36, 36 & 1);
 	char amountStr[10];
-	sprintf(amountStr, "%04d", _vars._card1Money / 10);
+	Common::sprintf_s(amountStr, "%04d", _vars._card1Money / 10);
 	_charShift = 91 * 2 + 75;
 	printDirect((const uint8 *)amountStr, 160, 155, 240, 240 & 1);
-	sprintf(amountStr, "%02d", (_vars._card1Money % 10) * 10);
+	Common::sprintf_s(amountStr, "%02d", (_vars._card1Money % 10) * 10);
 	_charShift = 91 * 2 + 85;
 	printDirect((const uint8 *)amountStr, 187, 155, 240, 240 & 1);
 	_charShift = 0;


Commit: 6d3a10c631b8c58bc56e24154932a2691d8ca040
    https://github.com/scummvm/scummvm/commit/6d3a10c631b8c58bc56e24154932a2691d8ca040
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GLK: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/glk/adrift/os_glk.cpp
    engines/glk/adrift/scdebug.cpp
    engines/glk/adrift/scexpr.cpp
    engines/glk/adrift/sclibrar.cpp
    engines/glk/adrift/scparser.cpp
    engines/glk/adrift/scprintf.cpp
    engines/glk/adrift/scrunner.cpp
    engines/glk/adrift/scvars.cpp
    engines/glk/adrift/sxstubs.cpp
    engines/glk/agt/agil.cpp
    engines/glk/agt/debugcmd.cpp
    engines/glk/agt/disassemble.cpp
    engines/glk/agt/exec.cpp
    engines/glk/agt/gamedata.cpp
    engines/glk/agt/interface.cpp
    engines/glk/agt/metacommand.cpp
    engines/glk/agt/os_glk.cpp
    engines/glk/agt/parser.cpp
    engines/glk/agt/runverb.cpp
    engines/glk/agt/token.cpp
    engines/glk/agt/util.cpp
    engines/glk/alan2/debug.cpp
    engines/glk/alan2/exe.cpp
    engines/glk/alan2/glkio.cpp
    engines/glk/alan2/main.cpp
    engines/glk/alan2/parse.cpp
    engines/glk/alan3/act.cpp
    engines/glk/alan3/debug.cpp
    engines/glk/alan3/exe.cpp
    engines/glk/alan3/glkio.cpp
    engines/glk/alan3/instance.cpp
    engines/glk/alan3/inter.cpp
    engines/glk/alan3/main.cpp
    engines/glk/alan3/parse.cpp
    engines/glk/hugo/heexpr.cpp
    engines/glk/hugo/hemedia.cpp
    engines/glk/hugo/hemisc.cpp
    engines/glk/hugo/heobject.cpp
    engines/glk/hugo/heparse.cpp
    engines/glk/hugo/heres.cpp
    engines/glk/hugo/herun.cpp
    engines/glk/hugo/heset.cpp
    engines/glk/hugo/hugo.h
    engines/glk/jacl/errors.cpp
    engines/glk/jacl/glk_saver.cpp
    engines/glk/jacl/interpreter.cpp
    engines/glk/jacl/jacl_main.cpp
    engines/glk/jacl/jpp.cpp
    engines/glk/jacl/loader.cpp
    engines/glk/jacl/logging.cpp
    engines/glk/jacl/parser.cpp
    engines/glk/jacl/resolvers.cpp
    engines/glk/jacl/utils.cpp
    engines/glk/level9/bitmap.cpp
    engines/glk/level9/level9_main.cpp
    engines/glk/level9/os_glk.cpp
    engines/glk/magnetic/glk.cpp
    engines/glk/quest/quest.cpp
    engines/glk/scott/unp64/unp64.cpp
    engines/glk/tads/os_glk.cpp
    engines/glk/tads/os_glk.h
    engines/glk/tads/tads2/built_in.cpp
    engines/glk/tads/tads2/debug.cpp
    engines/glk/tads/tads2/error.cpp
    engines/glk/tads/tads2/error_handling.cpp
    engines/glk/tads/tads2/error_message.cpp
    engines/glk/tads/tads2/line_source_file.cpp
    engines/glk/tads/tads2/ltk.cpp
    engines/glk/tads/tads2/play.cpp
    engines/glk/tads/tads2/runtime_driver.cpp
    engines/glk/tads/tads2/tokenizer.cpp
    engines/glk/tads/tads2/vocabulary_parser.cpp


diff --git a/engines/glk/adrift/os_glk.cpp b/engines/glk/adrift/os_glk.cpp
index 599f401c435..af593b57395 100644
--- a/engines/glk/adrift/os_glk.cpp
+++ b/engines/glk/adrift/os_glk.cpp
@@ -865,7 +865,7 @@ static void gsc_status_update() {
 			/* Get the game's status line, or if none, format score. */
 			status = sc_get_game_status_line(gsc_game);
 			if (!gsc_is_string_usable(status)) {
-				sprintf(score, "Score: %ld", sc_get_game_score(gsc_game));
+				Common::sprintf_s(score, "Score: %ld", sc_get_game_score(gsc_game));
 				status = score;
 			}
 
@@ -927,7 +927,7 @@ static void gsc_status_print() {
 		/* Get the game's status line, or if none, format score. */
 		status = sc_get_game_status_line(gsc_game);
 		if (!gsc_is_string_usable(status)) {
-			sprintf(score, "Score: %ld", sc_get_game_score(gsc_game));
+			Common::sprintf_s(score, "Score: %ld", sc_get_game_score(gsc_game));
 			status = score;
 		}
 
@@ -1631,7 +1631,7 @@ void os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
 		 */
 		assert(gsclinux_game_file);
 		buffer = gsc_malloc(strlen(gsclinux_game_file) + 128);
-		sprintf(buffer, "dd if=%s ibs=1c skip=%ld count=%ld obs=100k"
+		Common::sprintf_s(buffer, "dd if=%s ibs=1c skip=%ld count=%ld obs=100k"
 		        " of=/tmp/scare.jpg 2>/dev/null",
 		        gsclinux_game_file, offset, length);
 		system(buffer);
@@ -1908,7 +1908,7 @@ static void gsc_command_abbreviations(const char *argument) {
 static void gsc_command_print_version_number(glui32 version) {
 	char buffer[64];
 
-	sprintf(buffer, "%lu.%lu.%lu",
+	Common::sprintf_s(buffer, "%lu.%lu.%lu",
 	        (unsigned long) version >> 16,
 	        (unsigned long)(version >> 8) & 0xff,
 	        (unsigned long) version & 0xff);
diff --git a/engines/glk/adrift/scdebug.cpp b/engines/glk/adrift/scdebug.cpp
index 1d1be7278ab..7ecd6f59042 100644
--- a/engines/glk/adrift/scdebug.cpp
+++ b/engines/glk/adrift/scdebug.cpp
@@ -556,7 +556,7 @@ static void debug_print_room(sc_gameref_t game, sc_int room) {
 
 	if_print_debug("Room ");
 	if (room < 0 || room >= gs_room_count(game)) {
-		sprintf(buffer, "%ld ", room);
+		Common::sprintf_s(buffer, "%ld ", room);
 		if_print_debug(buffer);
 		if_print_debug("[Out of range]");
 		return;
@@ -566,7 +566,7 @@ static void debug_print_room(sc_gameref_t game, sc_int room) {
 	vt_key[1].integer = room;
 	vt_key[2].string = "Short";
 	name = prop_get_string(bundle, "S<-sis", vt_key);
-	sprintf(buffer, "%ld ", room);
+	Common::sprintf_s(buffer, "%ld ", room);
 	if_print_debug(buffer);
 	debug_print_quoted(name);
 }
@@ -580,7 +580,7 @@ static void debug_print_object(sc_gameref_t game, sc_int object) {
 
 	if (object < 0 || object >= gs_object_count(game)) {
 		if_print_debug("Object ");
-		sprintf(buffer, "%ld ", object);
+		Common::sprintf_s(buffer, "%ld ", object);
 		if_print_debug(buffer);
 		if_print_debug("[Out of range]");
 		return;
@@ -598,7 +598,7 @@ static void debug_print_object(sc_gameref_t game, sc_int object) {
 		if_print_debug("Static ");
 	else
 		if_print_debug("Dynamic ");
-	sprintf(buffer, "%ld ", object);
+	Common::sprintf_s(buffer, "%ld ", object);
 	if_print_debug(buffer);
 	debug_print_quoted(prefix);
 	if_print_debug_character(' ');
@@ -613,7 +613,7 @@ static void debug_print_npc(sc_gameref_t game, sc_int npc) {
 
 	if_print_debug("NPC ");
 	if (npc < 0 || npc >= gs_npc_count(game)) {
-		sprintf(buffer, "%ld ", npc);
+		Common::sprintf_s(buffer, "%ld ", npc);
 		if_print_debug(buffer);
 		if_print_debug("[Out of range]");
 		return;
@@ -625,7 +625,7 @@ static void debug_print_npc(sc_gameref_t game, sc_int npc) {
 	prefix = prop_get_string(bundle, "S<-sis", vt_key);
 	vt_key[2].string = "Name";
 	name = prop_get_string(bundle, "S<-sis", vt_key);
-	sprintf(buffer, "%ld ", npc);
+	Common::sprintf_s(buffer, "%ld ", npc);
 	if_print_debug(buffer);
 	debug_print_quoted(prefix);
 	if_print_debug_character(' ');
@@ -640,7 +640,7 @@ static void debug_print_event(sc_gameref_t game, sc_int event) {
 
 	if_print_debug("Event ");
 	if (event < 0 || event >= gs_event_count(game)) {
-		sprintf(buffer, "%ld ", event);
+		Common::sprintf_s(buffer, "%ld ", event);
 		if_print_debug(buffer);
 		if_print_debug("[Out of range]");
 		return;
@@ -650,7 +650,7 @@ static void debug_print_event(sc_gameref_t game, sc_int event) {
 	vt_key[1].integer = event;
 	vt_key[2].string = "Short";
 	name = prop_get_string(bundle, "S<-sis", vt_key);
-	sprintf(buffer, "%ld ", event);
+	Common::sprintf_s(buffer, "%ld ", event);
 	if_print_debug(buffer);
 	debug_print_quoted(name);
 }
@@ -663,7 +663,7 @@ static void debug_print_task(sc_gameref_t game, sc_int task) {
 
 	if_print_debug("Task ");
 	if (task < 0 || task >= gs_task_count(game)) {
-		sprintf(buffer, "%ld ", task);
+		Common::sprintf_s(buffer, "%ld ", task);
 		if_print_debug(buffer);
 		if_print_debug("[Out of range]");
 		return;
@@ -674,7 +674,7 @@ static void debug_print_task(sc_gameref_t game, sc_int task) {
 	vt_key[2].string = "Command";
 	vt_key[3].integer = 0;
 	command = prop_get_string(bundle, "S<-sisi", vt_key);
-	sprintf(buffer, "%ld ", task);
+	Common::sprintf_s(buffer, "%ld ", task);
 	if_print_debug(buffer);
 	debug_print_quoted(command);
 }
@@ -689,7 +689,7 @@ static void debug_print_variable(sc_gameref_t game, sc_int variable) {
 
 	if (variable < 0 || variable >= debug_variable_count(game)) {
 		if_print_debug("Variable ");
-		sprintf(buffer, "%ld ", variable);
+		Common::sprintf_s(buffer, "%ld ", variable);
 		if_print_debug(buffer);
 		if_print_debug("[Out of range]");
 		return;
@@ -714,7 +714,7 @@ static void debug_print_variable(sc_gameref_t game, sc_int variable) {
 		}
 	} else
 		if_print_debug("[Invalid variable] ");
-	sprintf(buffer, "%ld ", variable);
+	Common::sprintf_s(buffer, "%ld ", variable);
 	if_print_debug(buffer);
 	debug_print_quoted(name);
 }
@@ -786,7 +786,7 @@ static void debug_game(sc_gameref_t game, sc_command_type_t type) {
 	vt_key[1].string = "WaitTurns";
 	waitturns = prop_get_integer(bundle, "I<-ss", vt_key);
 	if_print_debug(", Waitturns ");
-	sprintf(buffer, "%ld", waitturns);
+	Common::sprintf_s(buffer, "%ld", waitturns);
 	if_print_debug(buffer);
 
 	vt_key[0].string = "Globals";
@@ -807,28 +807,28 @@ static void debug_game(sc_gameref_t game, sc_command_type_t type) {
 		if_print_debug("    Battle system\n");
 
 	if_print_debug("    Room count ");
-	sprintf(buffer, "%ld", gs_room_count(game));
+	Common::sprintf_s(buffer, "%ld", gs_room_count(game));
 	if_print_debug(buffer);
 
 	if_print_debug(", Object count ");
-	sprintf(buffer, "%ld", gs_object_count(game));
+	Common::sprintf_s(buffer, "%ld", gs_object_count(game));
 	if_print_debug(buffer);
 
 	if_print_debug(", NPC count ");
-	sprintf(buffer, "%ld", gs_npc_count(game));
+	Common::sprintf_s(buffer, "%ld", gs_npc_count(game));
 	if_print_debug(buffer);
 	if_print_debug_character('\n');
 
 	if_print_debug("    Event count ");
-	sprintf(buffer, "%ld", gs_event_count(game));
+	Common::sprintf_s(buffer, "%ld", gs_event_count(game));
 	if_print_debug(buffer);
 
 	if_print_debug(", Task count ");
-	sprintf(buffer, "%ld", gs_task_count(game));
+	Common::sprintf_s(buffer, "%ld", gs_task_count(game));
 	if_print_debug(buffer);
 
 	if_print_debug(", Variable count ");
-	sprintf(buffer, "%ld", debug_variable_count(game));
+	Common::sprintf_s(buffer, "%ld", debug_variable_count(game));
 	if_print_debug(buffer);
 	if_print_debug_character('\n');
 
@@ -855,13 +855,13 @@ static void debug_game(sc_gameref_t game, sc_command_type_t type) {
 	if_print_debug_character('\n');
 
 	if_print_debug("    Score ");
-	sprintf(buffer, "%ld", game->score);
+	Common::sprintf_s(buffer, "%ld", game->score);
 	if_print_debug(buffer);
 	if_print_debug(", Turns ");
-	sprintf(buffer, "%ld", game->turns);
+	Common::sprintf_s(buffer, "%ld", game->turns);
 	if_print_debug(buffer);
 	if_print_debug(", Seconds ");
-	sprintf(buffer, "%lu", debug->elapsed_seconds);
+	Common::sprintf_s(buffer, "%lu", debug->elapsed_seconds);
 	if_print_debug(buffer);
 	if_print_debug_character('\n');
 }
@@ -1130,7 +1130,7 @@ static void debug_dump_object(sc_gameref_t game, sc_int object) {
 		const sc_char *states;
 
 		if_print_debug("    State ");
-		sprintf(buffer, "%ld", gs_object_state(game, object));
+		Common::sprintf_s(buffer, "%ld", gs_object_state(game, object));
 		if_print_debug(buffer);
 
 		vt_key[2].string = "States";
@@ -1195,11 +1195,11 @@ static void debug_dump_npc(sc_gameref_t game, sc_int npc) {
 		sc_int walk;
 
 		if_print_debug("    Walkstep count ");
-		sprintf(buffer, "%ld", gs_npc_walkstep_count(game, npc));
+		Common::sprintf_s(buffer, "%ld", gs_npc_walkstep_count(game, npc));
 		if_print_debug(buffer);
 		if_print_debug(", Walks { ");
 		for (walk = 0; walk < gs_npc_walkstep_count(game, npc); walk++) {
-			sprintf(buffer, "%ld", gs_npc_walkstep(game, npc, walk));
+			Common::sprintf_s(buffer, "%ld", gs_npc_walkstep(game, npc, walk));
 			if_print_debug(buffer);
 			if_print_debug_character(' ');
 		}
@@ -1246,7 +1246,7 @@ static void debug_dump_event(sc_gameref_t game, sc_int event) {
 	}
 
 	if_print_debug("    Time ");
-	sprintf(buffer, "%ld\n", gs_event_time(game, event));
+	Common::sprintf_s(buffer, "%ld\n", gs_event_time(game, event));
 	if_print_debug(buffer);
 }
 
@@ -1306,7 +1306,7 @@ static void debug_dump_variable(sc_gameref_t game, sc_int variable) {
 		case VAR_INTEGER: {
 			sc_char buffer[32];
 
-			sprintf(buffer, "%ld", vt_rvalue.integer);
+			Common::sprintf_s(buffer, "%ld", vt_rvalue.integer);
 			if_print_debug(buffer);
 			break;
 		}
@@ -1427,7 +1427,7 @@ static void debug_dump_common(sc_gameref_t game, sc_command_t command,
 				sc_char buffer[32];
 
 				if_print_debug("; valid values are 0 to ");
-				sprintf(buffer, "%ld", limit - 1);
+				Common::sprintf_s(buffer, "%ld", limit - 1);
 				if_print_debug(buffer);
 				if_print_debug(".\n");
 			}
@@ -1488,10 +1488,10 @@ static void debug_print_resource(const sc_resource_t *resource) {
 
 	debug_print_quoted(resource->name);
 	if_print_debug(", offset ");
-	sprintf(buffer, "%ld", resource->offset);
+	Common::sprintf_s(buffer, "%ld", resource->offset);
 	if_print_debug(buffer);
 	if_print_debug(", length ");
-	sprintf(buffer, "%ld", resource->length);
+	Common::sprintf_s(buffer, "%ld", resource->length);
 	if_print_debug(buffer);
 }
 
@@ -1585,7 +1585,7 @@ static void debug_random(sc_command_type_t type, sc_int new_seed) {
 	sc_seed_random(new_seed);
 
 	if_print_debug("Set seed ");
-	sprintf(buffer, "%ld", new_seed);
+	Common::sprintf_s(buffer, "%ld", new_seed);
 	if_print_debug(buffer);
 	if_print_debug(" for the ");
 	if_print_debug(random_type);
@@ -1703,7 +1703,7 @@ static void debug_watchpoint_common(sc_gameref_t game, sc_command_t command,
 				if_print_debug("; only 0 is valid.\n");
 			else {
 				if_print_debug("; valid values are 0 to ");
-				sprintf(buffer, "%ld", limit - 1);
+				Common::sprintf_s(buffer, "%ld", limit - 1);
 				if_print_debug(buffer);
 				if_print_debug(".\n");
 			}
@@ -1723,7 +1723,7 @@ static void debug_watchpoint_common(sc_gameref_t game, sc_command_t command,
 					if_print_debug(class_);
 					if_print_debug(" { ");
 				}
-				sprintf(buffer, "%ld", index_);
+				Common::sprintf_s(buffer, "%ld", index_);
 				if_print_debug(buffer);
 				if_print_debug_character(' ');
 				printed = TRUE;
@@ -1750,7 +1750,7 @@ static void debug_watchpoint_common(sc_gameref_t game, sc_command_t command,
 		if_print_debug("Set ");
 	else
 		if_print_debug("Cleared ");
-	sprintf(buffer, "%ld ", high - low + 1);
+	Common::sprintf_s(buffer, "%ld ", high - low + 1);
 	if_print_debug(buffer);
 	if_print_debug(class_);
 	if (high == low)
@@ -1955,7 +1955,7 @@ static sc_bool debug_check_class(sc_gameref_t from, sc_gameref_t with, const sc_
 				if_print_debug(class_);
 				if_print_debug(" watchpoint triggered { ");
 			}
-			sprintf(buffer, "%ld ", index_);
+			Common::sprintf_s(buffer, "%ld ", index_);
 			if_print_debug(buffer);
 			triggered = TRUE;
 		}
diff --git a/engines/glk/adrift/scexpr.cpp b/engines/glk/adrift/scexpr.cpp
index 3f037858025..6072d47b077 100644
--- a/engines/glk/adrift/scexpr.cpp
+++ b/engines/glk/adrift/scexpr.cpp
@@ -968,7 +968,7 @@ static void expr_eval_action(CONTEXT, sc_int token) {
 		 * The leading space on positive values matches the Runner.
 		 */
 		val = expr_eval_pop_integer();
-		sprintf(buffer, "% ld", val);
+		Common::sprintf_s(buffer, "% ld", val);
 		expr_eval_push_string(buffer);
 		break;
 	}
diff --git a/engines/glk/adrift/sclibrar.cpp b/engines/glk/adrift/sclibrar.cpp
index 639bbe23832..7c79cc66424 100644
--- a/engines/glk/adrift/sclibrar.cpp
+++ b/engines/glk/adrift/sclibrar.cpp
@@ -1267,7 +1267,7 @@ static sc_bool lib_cmd_history_common(sc_gameref_t game, sc_int limit) {
 			sc_char buffer[64];
 
 			/* Write the history entry sequence. */
-			sprintf(buffer, "%4ld -- Time ", sequence);
+			Common::sprintf_s(buffer, "%4ld -- Time ", sequence);
 			if_print_string(buffer);
 
 			/* Separate the timestamp out into components. */
@@ -1277,13 +1277,13 @@ static sc_bool lib_cmd_history_common(sc_gameref_t game, sc_int limit) {
 
 			/* Print playing time as "[HHh ][M]Mm SSs". */
 			if (hr > 0)
-				sprintf(buffer, "%ldh %02ldm %02lds", hr, min, sec);
+				Common::sprintf_s(buffer, "%ldh %02ldm %02lds", hr, min, sec);
 			else
-				sprintf(buffer, "%ldm %02lds", min, sec);
+				Common::sprintf_s(buffer, "%ldm %02lds", min, sec);
 			if_print_string(buffer);
 
 			/* Follow up with the turns count, and the command string itself. */
-			sprintf(buffer, ", turn %ld : ", turns);
+			Common::sprintf_s(buffer, ", turn %ld : ", turns);
 			if_print_string(buffer);
 			if_print_string(command);
 			if_print_character('\n');
@@ -1728,7 +1728,7 @@ sc_bool lib_cmd_statusline(sc_gameref_t game) {
 			sc_char buffer[32];
 
 			if_print_string("Score: ");
-			sprintf(buffer, "%ld", score);
+			Common::sprintf_s(buffer, "%ld", score);
 			if_print_string(buffer);
 		}
 	}
@@ -1758,7 +1758,7 @@ sc_bool lib_cmd_version(sc_gameref_t game) {
 	major = SCARE_EMULATION / 1000;
 	minor = (SCARE_EMULATION % 1000) / 100;
 	point = SCARE_EMULATION % 100;
-	sprintf(buffer, "%ld.%02ld.%02ld", major, minor, point);
+	Common::sprintf_s(buffer, "%ld.%02ld.%02ld", major, minor, point);
 	if_print_string(buffer);
 	if_print_string(" compatible], ");
 
@@ -1798,7 +1798,7 @@ sc_bool lib_cmd_wait(sc_gameref_t game) {
 		sc_char buffer[32];
 
 		pf_buffer_string(filter, "(");
-		sprintf(buffer, "%ld", game->waitturns);
+		Common::sprintf_s(buffer, "%ld", game->waitturns);
 		pf_buffer_string(filter, buffer);
 		pf_buffer_string(filter,
 		                 game->waitturns == 1 ? " turn)\n" : " turns)\n");
@@ -1828,7 +1828,7 @@ sc_bool lib_cmd_wait_number(sc_gameref_t game) {
 	game->waitturns = waitturns;
 
 	if_print_string("The game will now wait ");
-	sprintf(buffer, "%ld", waitturns);
+	Common::sprintf_s(buffer, "%ld", waitturns);
 	if_print_string(buffer);
 	if_print_string(waitturns == 1 ? " turn" : " turns");
 	if_print_string(" for each 'wait' command you enter.\n");
@@ -1954,9 +1954,9 @@ sc_bool lib_cmd_time(sc_gameref_t game) {
 	min = (timestamp % SECS_PER_HOUR) / MINS_PER_HOUR;
 	sec = timestamp % SECS_PER_MINUTE;
 	if (hr > 0)
-		sprintf(buffer, "%ldh %02ldm %02lds", hr, min, sec);
+		Common::sprintf_s(buffer, "%ldh %02ldm %02lds", hr, min, sec);
 	else
-		sprintf(buffer, "%ldm %02lds", min, sec);
+		Common::sprintf_s(buffer, "%ldm %02lds", min, sec);
 
 	/* Print the game's elapsed time. */
 	if_print_string("You have been running the game for ");
@@ -3307,21 +3307,21 @@ static sc_bool lib_try_game_command_common(sc_gameref_t game, const sc_char *ver
 		 * Try the command with and without prefixes on both the target object
 		 * and the associate.
 		 */
-		sprintf(command, "%s %s %s %s %s %s", verb,
+		Common::sprintf_s(command, required, "%s %s %s %s %s %s", verb,
 		        prefix, name, preposition, associate_prefix, associate_name);
 		status = run_game_task_commands(game, command);
 		if (!status) {
-			sprintf(command, "%s %s %s %s %s",
+			Common::sprintf_s(command, required, "%s %s %s %s %s",
 			        verb, prefix, name, preposition, associate_name);
 			status = run_game_task_commands(game, command);
 		}
 		if (!status) {
-			sprintf(command, "%s %s %s %s %s",
+			Common::sprintf_s(command, required, "%s %s %s %s %s",
 			        verb, name, preposition, associate_prefix, associate_name);
 			status = run_game_task_commands(game, command);
 		}
 		if (!status) {
-			sprintf(command, "%s %s %s %s",
+			Common::sprintf_s(command, required, "%s %s %s %s",
 			        verb, name, preposition, associate_name);
 			status = run_game_task_commands(game, command);
 		}
@@ -3333,10 +3333,10 @@ static sc_bool lib_try_game_command_common(sc_gameref_t game, const sc_char *ver
 		          ? (sc_char *)sc_malloc(required) : buffer;
 
 		/* Try the command with and without prefixes on the addressed object. */
-		sprintf(command, "%s %s %s", verb, prefix, name);
+		Common::sprintf_s(command, required, "%s %s %s", verb, prefix, name);
 		status = run_game_task_commands(game, command);
 		if (!status) {
-			sprintf(command, "%s %s", verb, name);
+			Common::sprintf_s(command, required, "%s %s", verb, name);
 			status = run_game_task_commands(game, command);
 		}
 	}
@@ -3606,18 +3606,18 @@ sc_bool lib_cmd_count(sc_gameref_t game) {
 
 	/* Print the player limits and amounts used. */
 	pf_buffer_string(filter, "Size:    You have ");
-	sprintf(buffer, "%ld", size);
+	Common::sprintf_s(buffer, "%ld", size);
 	pf_buffer_string(filter, buffer);
 	pf_buffer_string(filter, ".  The most you can hold is ");
-	sprintf(buffer, "%ld", obj_get_player_size_limit(game));
+	Common::sprintf_s(buffer, "%ld", obj_get_player_size_limit(game));
 	pf_buffer_string(filter, buffer);
 	pf_buffer_string(filter, ".\n");
 
 	pf_buffer_string(filter, "Weight:  You have ");
-	sprintf(buffer, "%ld", weight);
+	Common::sprintf_s(buffer, "%ld", weight);
 	pf_buffer_string(filter, buffer);
 	pf_buffer_string(filter, ".  The most you can hold is ");
-	sprintf(buffer, "%ld", obj_get_player_weight_limit(game));
+	Common::sprintf_s(buffer, "%ld", obj_get_player_weight_limit(game));
 	pf_buffer_string(filter, buffer);
 	pf_buffer_string(filter, ".\n");
 
@@ -8520,7 +8520,7 @@ sc_bool lib_cmd_turns(sc_gameref_t game) {
 	sc_char buffer[32];
 
 	pf_buffer_string(filter, "You have taken ");
-	sprintf(buffer, "%ld", game->turns);
+	Common::sprintf_s(buffer, "%ld", game->turns);
 	pf_buffer_string(filter, buffer);
 	if (game->turns == 1)
 		pf_buffer_string(filter, " turn so far.\n");
@@ -8553,13 +8553,13 @@ sc_bool lib_cmd_score(sc_gameref_t game) {
 	                                     "Your score is ",
 	                                     "My score is ",
 	                                     "%player%'s score is "));
-	sprintf(buffer, "%ld", game->score);
+	Common::sprintf_s(buffer, "%ld", game->score);
 	pf_buffer_string(filter, buffer);
 	pf_buffer_string(filter, " out of a maximum of ");
-	sprintf(buffer, "%ld", max_score);
+	Common::sprintf_s(buffer, "%ld", max_score);
 	pf_buffer_string(filter, buffer);
 	pf_buffer_string(filter, ".  (");
-	sprintf(buffer, "%ld", percent);
+	Common::sprintf_s(buffer, "%ld", percent);
 	pf_buffer_string(filter, buffer);
 	pf_buffer_string(filter, "%)\n");
 
diff --git a/engines/glk/adrift/scparser.cpp b/engines/glk/adrift/scparser.cpp
index f9670e7b6b3..320d4b3afa7 100644
--- a/engines/glk/adrift/scparser.cpp
+++ b/engines/glk/adrift/scparser.cpp
@@ -848,7 +848,7 @@ static sc_bool uip_match_variable(sc_ptnoderef_t node) {
 			sc_char value[32];
 
 			/* Compare numeric against the current string position. */
-			sprintf(value, "%ld", vt_rvalue.integer);
+			Common::sprintf_s(value, "%ld", vt_rvalue.integer);
 			length = strlen(value);
 			if (strncmp(uip_string + uip_posn, value, length) == 0) {
 				/* Integer match, advance position and return. */
@@ -1257,7 +1257,7 @@ static sc_int uip_compare_prefixed_name(const sc_char *prefix, const sc_char *na
 	/* Create a prefixed string, using the local buffer if possible. */
 	required = strlen(prefix) + strlen(name) + 2;
 	string = required > (sc_int) sizeof(buffer) ? (sc_char *)sc_malloc(required) : buffer;
-	sprintf(string, "%s %s", prefix, name);
+	Common::sprintf_s(string, required, "%s %s", prefix, name);
 
 	/* Check against the prefixed name first, free string if required. */
 	extent = uip_compare_reference(string);
diff --git a/engines/glk/adrift/scprintf.cpp b/engines/glk/adrift/scprintf.cpp
index d7a4027606f..7420babe7dc 100644
--- a/engines/glk/adrift/scprintf.cpp
+++ b/engines/glk/adrift/scprintf.cpp
@@ -237,7 +237,7 @@ static sc_char *pf_interpolate_vars(const sc_char *string, sc_var_setref_t vars)
 		case VAR_INTEGER: {
 			sc_char value[32];
 
-			sprintf(value, "%ld", vt_rvalue.integer);
+			Common::sprintf_s(value, "%ld", vt_rvalue.integer);
 			size_t ln = strlen(buffer) + strlen(value) + 1;
 			buffer = (sc_char *)sc_realloc(buffer, ln);
 			Common::strcat_s(buffer, ln, value);
diff --git a/engines/glk/adrift/scrunner.cpp b/engines/glk/adrift/scrunner.cpp
index c919b484203..244f77ef773 100644
--- a/engines/glk/adrift/scrunner.cpp
+++ b/engines/glk/adrift/scrunner.cpp
@@ -602,12 +602,12 @@ static void run_notify_score_change(sc_gameref_t game) {
 	/* Note any change in the score. */
 	if (game->score > undo->score) {
 		if_print_string("(Your score has increased by ");
-		sprintf(buffer, "%ld", game->score - undo->score);
+		Common::sprintf_s(buffer, "%ld", game->score - undo->score);
 		if_print_string(buffer);
 		if_print_string(")\n");
 	} else if (game->score < undo->score) {
 		if_print_string("(Your score has decreased by ");
-		sprintf(buffer, "%ld", undo->score - game->score);
+		Common::sprintf_s(buffer, "%ld", undo->score - game->score);
 		if_print_string(buffer);
 		if_print_string(")\n");
 	}
diff --git a/engines/glk/adrift/scvars.cpp b/engines/glk/adrift/scvars.cpp
index 17800839d52..661db4dacec 100644
--- a/engines/glk/adrift/scvars.cpp
+++ b/engines/glk/adrift/scvars.cpp
@@ -1137,7 +1137,7 @@ static sc_bool var_get_system(sc_var_setref_t vars, const sc_char *name,
 				retval = VAR_NUMBERS[number];
 			else {
 				vars->temporary = (sc_char *)sc_realloc(vars->temporary, 32);
-				sprintf(vars->temporary, "%ld", number);
+				Common::sprintf_s(vars->temporary, 32, "%ld", number);
 				retval = vars->temporary;
 			}
 
@@ -1171,7 +1171,7 @@ static sc_bool var_get_system(sc_var_setref_t vars, const sc_char *name,
 				retval = VAR_NUMBERS[number];
 			else {
 				vars->temporary = (sc_char *)sc_realloc(vars->temporary, 32);
-				sprintf(vars->temporary, "%ld", number);
+				Common::sprintf_s(vars->temporary, 32, "%ld", number);
 				retval = vars->temporary;
 			}
 
diff --git a/engines/glk/adrift/sxstubs.cpp b/engines/glk/adrift/sxstubs.cpp
index bc0cc0605a8..db51bb17ef2 100644
--- a/engines/glk/adrift/sxstubs.cpp
+++ b/engines/glk/adrift/sxstubs.cpp
@@ -194,10 +194,10 @@ os_play_sound(const sc_char *filepath,
 		stub_print_string("<<Sound: id=\"");
 		stub_print_string(stub_notnull(filepath));
 		stub_print_string("\", offset=");
-		sprintf(buffer, "%ld", offset);
+		Common::sprintf_s(buffer, "%ld", offset);
 		stub_print_string(buffer);
 		stub_print_string(", length=");
-		sprintf(buffer, "%ld", length);
+		Common::sprintf_s(buffer, "%ld", length);
 		stub_print_string(buffer);
 		stub_print_string(", looping=");
 		stub_print_string(is_looping ? "true" : "false");
@@ -226,10 +226,10 @@ os_show_graphic(const sc_char *filepath, sc_int offset, sc_int length) {
 		stub_print_string("<<Graphic: id=\"");
 		stub_print_string(stub_notnull(filepath));
 		stub_print_string("\", offset=");
-		sprintf(buffer, "%ld", offset);
+		Common::sprintf_s(buffer, "%ld", offset);
 		stub_print_string(buffer);
 		stub_print_string(", length=");
-		sprintf(buffer, "%ld", length);
+		Common::sprintf_s(buffer, "%ld", length);
 		stub_print_string(buffer);
 		stub_print_string(">>");
 	}
@@ -243,7 +243,7 @@ os_read_line(sc_char *buffer, sc_int length) {
 		status = stub_read_line(buffer, length);
 	else {
 		assert(buffer && length > 4);
-		sprintf(buffer, "%s", "quit");
+		Common::sprintf_s(buffer, "%s", "quit");
 		status = TRUE;
 	}
 
@@ -260,7 +260,7 @@ os_read_line(sc_char *buffer, sc_int length) {
 sc_bool
 os_read_line_debug(sc_char *buffer, sc_int length) {
 	assert(buffer && length > 8);
-	sprintf(buffer, "%s", "continue");
+	Common::sprintf_s(buffer, "%s", "continue");
 
 	if (stub_trace)
 		sx_trace("os_read_line_debug (\"%s\", %ld) -> true\n", buffer, length);
diff --git a/engines/glk/agt/agil.cpp b/engines/glk/agt/agil.cpp
index 49056fc96b1..b64d37603bf 100644
--- a/engines/glk/agt/agil.cpp
+++ b/engines/glk/agt/agil.cpp
@@ -228,10 +228,10 @@ static void print_title(fc_type fc) {
 	agt_textcolor(-1);
 	s = (char *)rmalloc(80);
 	if (height <= screen_height - 5)
-		sprintf(s, "AGiliTy: "
+		Common::sprintf_s(s, 80, "AGiliTy: "
 		        "The (Mostly) Universal AGT Interpreter  %s", version_str);
 	else
-		sprintf(s, "Being run by AGiliTy  %s, "
+		Common::sprintf_s(s, 80, "Being run by AGiliTy  %s, "
 		        "Copyright (C) 1996-99,2001 Robert Masenten",
 		        version_str);
 	writeln(s);
@@ -534,7 +534,7 @@ static void mainloop(void) {
 	doing_restore = 0;
 	while (!quitflag) {
 		if (DEBUG_MEM) {
-			sprintf(memstr,
+			Common::sprintf_s(memstr,
 			        "A:%ld F:%ld  Delta:%ld   Size:%ld+%ld=%ld (%ld left)\n",
 			        ralloc_cnt, rfree_cnt, ralloc_cnt - rfree_cnt,
 			        rm_start_size, rm_size - rm_start_size, rm_size,
@@ -682,7 +682,7 @@ static void fix_dummy(void) {
 
 	if (!PURE_SUBNAME)     /* Replace the 'e' by a space */
 		for (i = 0; i < MAX_SUB; i++)
-			sprintf(dict[sub_name[i]], "subroutin %d", i + 1);
+			Common::sprintf_s(dict[sub_name[i]], strlen(dict[sub_name[i]]) + 1, "subroutin %d", i + 1);
 	/* This must be no longer than 25 characters with the terminating null */
 
 	/* Now set PURE_DOT based on whether any dictionary word
diff --git a/engines/glk/agt/debugcmd.cpp b/engines/glk/agt/debugcmd.cpp
index 4756d0f26cc..080655d0566 100644
--- a/engines/glk/agt/debugcmd.cpp
+++ b/engines/glk/agt/debugcmd.cpp
@@ -61,7 +61,7 @@ static int print_objid(int obj) {
 	char *s;
 	int n;
 
-	sprintf(buff, "%4d: ", obj);
+	Common::sprintf_s(buff, "%4d: ", obj);
 	writestr(buff);
 	s = objname(obj);
 	for (n = 0; s[n] != 0; n++)
@@ -188,13 +188,13 @@ static void var_edit(int vtype)
 		for (i = 0; i <= imax; i++) {
 			switch (vtype) {
 			case 0:
-				sprintf(sbuff, "[Var%3d]=%4ld", i, (long)agt_var[i]);
+				Common::sprintf_s(sbuff, "[Var%3d]=%4ld", i, (long)agt_var[i]);
 				break;
 			case 1:
-				sprintf(sbuff, "[Cnt%3d]=%4ld", i, (long)agt_counter[i]);
+				Common::sprintf_s(sbuff, "[Cnt%3d]=%4ld", i, (long)agt_counter[i]);
 				break;
 			case 2:
-				sprintf(sbuff, "%3d%c", i, flag[i] ? 't' : 'f');
+				Common::sprintf_s(sbuff, "%3d%c", i, flag[i] ? 't' : 'f');
 				break;
 			default:
 				break;
@@ -223,8 +223,8 @@ static void var_edit(int vtype)
 			if (i <= imax) {
 				if (vtype != 2) {
 					if (vtype == 0)
-						sprintf(sbuff, "[Var%d]=%ld", i, (long)agt_var[i]);
-					else sprintf(sbuff, "[Cnt%d]=%ld (-1 means it's off)",
+						Common::sprintf_s(sbuff, "[Var%d]=%ld", i, (long)agt_var[i]);
+					else Common::sprintf_s(sbuff, "[Cnt%d]=%ld (-1 means it's off)",
 						             i, (long)agt_counter[i]);
 					writestr(sbuff);
 					writestr("; new value = ");
@@ -257,7 +257,7 @@ static void edit_str() {
 		writeln("User Definable Strings");
 		writeln("");
 		for (i = 0; i < MAX_USTR; i++) {
-			sprintf(buff, "%2d:", i + 1);
+			Common::sprintf_s(buff, "%2d:", i + 1);
 			writestr(buff);
 			writeln(userstr[i]);
 		}
@@ -322,7 +322,7 @@ static void writeprop(const char *propname, int obj) {
 static int writedir(int index, int dir, int obj) {
 	char sbuff[40];
 
-	sprintf(sbuff, "%2d.%-2s %d", index, exitname[dir], obj);
+	Common::sprintf_s(sbuff, "%2d.%-2s %d", index, exitname[dir], obj);
 	writestr(sbuff);
 	return strlen(sbuff);
 }
@@ -331,7 +331,7 @@ void writenum(const char *propname, int n) {
 	char sbuff[20];
 
 	writestr(propname);
-	sprintf(sbuff, "%4d", n);
+	Common::sprintf_s(sbuff, "%4d", n);
 	writeln(sbuff);
 }
 
@@ -342,7 +342,7 @@ static void writeflags(const char *flagname, int32 flags) {
 	writestr(flagname);
 	for (i = 0; i < 32; i++) {
 		if (flags & 1) {
-			sprintf(sbuff, "%2d ", i);
+			Common::sprintf_s(sbuff, "%2d ", i);
 			writestr(sbuff);
 		} else
 			writestr("   ");
@@ -772,11 +772,11 @@ static void set_debug_options() {
 		agt_clrscr();
 		writeln("DEBUGGING OPTIONS:");
 		writeln("");
-		sprintf(buff, "  1. Trace metacommands: %s", yesnostr[DEBUG_AGT_CMD]);
+		Common::sprintf_s(buff, "  1. Trace metacommands: %s", yesnostr[DEBUG_AGT_CMD]);
 		writeln(buff);
-		sprintf(buff, "  2. Trace ANY metacommands: %s", yesnostr[debug_any]);
+		Common::sprintf_s(buff, "  2. Trace ANY metacommands: %s", yesnostr[debug_any]);
 		writeln(buff);
-		sprintf(buff, "  3. Trace during disambiguation: %s",
+		Common::sprintf_s(buff, "  3. Trace during disambiguation: %s",
 		        yesnostr[debug_disambig]);
 		writeln(buff);
 		writeln("");
diff --git a/engines/glk/agt/disassemble.cpp b/engines/glk/agt/disassemble.cpp
index c7a13a32dd4..942162e7a65 100644
--- a/engines/glk/agt/disassemble.cpp
+++ b/engines/glk/agt/disassemble.cpp
@@ -29,7 +29,7 @@ void dbgprintf(const char *fmt, ...) {
 	char buff[300];
 
 	va_start(vp, fmt);
-	vsprintf(buff, fmt, vp);
+	Common::vsprintf_s(buff, fmt, vp);
 	va_end(vp);
 
 	debugout(buff);
diff --git a/engines/glk/agt/exec.cpp b/engines/glk/agt/exec.cpp
index d7c7f45c17e..baa521d1d47 100644
--- a/engines/glk/agt/exec.cpp
+++ b/engines/glk/agt/exec.cpp
@@ -63,12 +63,13 @@ static void time_out(char *s) {
 	hr = curr_time / 100;
 	min = curr_time % 100;
 
+	// s is minimum 20 bytes large
 	if (milltime_mode)
-		sprintf(s, "%02d:%02d", hr, min);
+		Common::sprintf_s(s, 20, "%02d:%02d", hr, min);
 	else {
 		if (hr > 12) hr = hr - 12;
 		if (hr == 0) hr = 12;
-		sprintf(s, "%2d:%02d %s", hr, min, (curr_time >= 1200) ? "pm" : "am");
+		Common::sprintf_s(s, 20, "%2d:%02d %s", hr, min, (curr_time >= 1200) ? "pm" : "am");
 	}
 }
 
@@ -88,22 +89,22 @@ void set_statline() {
 
 	switch (statusmode) {
 	case 0:
-		sprintf(r_stat, "Score: %ld  Moves: %d", tscore, turncnt);
+		Common::sprintf_s(r_stat, "Score: %ld  Moves: %d", tscore, turncnt);
 		break;
 	case 1:
-		sprintf(r_stat, "Score: %ld   %s", tscore, timestr);
+		Common::sprintf_s(r_stat, "Score: %ld   %s", tscore, timestr);
 		break;
 	case 2:
-		sprintf(r_stat, "Moves: %d", turncnt);
+		Common::sprintf_s(r_stat, "Moves: %d", turncnt);
 		break;
 	case 3:
-		sprintf(r_stat, "%s", timestr);
+		Common::sprintf_s(r_stat, "%s", timestr);
 		break;
 	case 4:
 		r_stat[0] = '\0';
 		break;  /* 'Trinity style' status line */
 	case 5:
-		sprintf(r_stat, "Score: %ld", tscore);
+		Common::sprintf_s(r_stat, "Score: %ld", tscore);
 		break;
 	default:
 		break;
@@ -246,7 +247,7 @@ static void num_name_func(parse_rec *obj_rec, char *fill_buff, word prev_adj)
 		w = it_name(obj_rec->obj);
 
 	if (w == 0) {
-		if (obj_rec->info == D_NUM) sprintf(fill_buff, "%ld", (long)obj_rec->num);
+		if (obj_rec->info == D_NUM) Common::sprintf_s(fill_buff, FILL_SIZE, "%ld", (long)obj_rec->num);
 		else fill_buff[0] = '\0';
 #if 0
 		Common::strcpy_s(fill_buff, FILL_SIZE, "that"); /* We can try and hope */
@@ -519,7 +520,7 @@ static char *wordvar_match(const char **pvarname, char match_type,
 			return nullptr;
 
 		/* Now to convert hold_val into a string */
-		sprintf(fill_buff, "%d", hold_val);
+		Common::sprintf_s(fill_buff, "%d", hold_val);
 
 	}
 	return fill_buff;
@@ -936,8 +937,8 @@ void print_score(void) {
 
 	if (score_mode < 5) {
 		if (score_mode == 0 || score_mode == 1 || score_mode == 4)
-			sprintf(s, "Your score is %ld (out of %ld possible).", tscore, max_score);
-		else sprintf(s, "Your score is %ld.", tscore);
+			Common::sprintf_s(s, "Your score is %ld (out of %ld possible).", tscore, max_score);
+		else Common::sprintf_s(s, "Your score is %ld.", tscore);
 		writeln(s);
 	}
 
@@ -953,9 +954,9 @@ void print_score(void) {
 				totroom++;
 			}
 		if (score_mode % 2 == 0)
-			sprintf(s, "You have visited %d locations (out of %d in the game)", rmcnt,
+			Common::sprintf_s(s, "You have visited %d locations (out of %d in the game)", rmcnt,
 			        totroom);
-		else sprintf(s, "You have visited %d locations.", rmcnt);
+		else Common::sprintf_s(s, "You have visited %d locations.", rmcnt);
 		writeln(s);
 	}
 }
diff --git a/engines/glk/agt/gamedata.cpp b/engines/glk/agt/gamedata.cpp
index 1c534c06b10..1f1b49c184f 100644
--- a/engines/glk/agt/gamedata.cpp
+++ b/engines/glk/agt/gamedata.cpp
@@ -886,13 +886,13 @@ void reinit_dict(void)
 	set_verbflag(); /* Do additional verbflag initialization */
 
 	for (i = 0; i < DVERB; i++) {
-		sprintf(buff, "dummy_verb%d", i + 1);
+		Common::sprintf_s(buff, "dummy_verb%d", i + 1);
 		auxsyn[i + BASE_VERB] = synptr;
 		addsyn(add0_dict(buff));
 		addsyn(-1);
 	}
 	for (i = 0; i < MAX_SUB; i++) {
-		sprintf(buff, "subroutine%d", i + 1);
+		Common::sprintf_s(buff, "subroutine%d", i + 1);
 		auxsyn[i + BASE_VERB + DVERB] = synptr;
 		addsyn(sub_name[i] = add0_dict(buff));
 		addsyn(-1);
@@ -1095,9 +1095,10 @@ char *objname(int i) { /* returns malloc'd name string of object i */
 		return concdup(dict[adjw], dict[nounw]);
 	}
 	/* At this point we can't get a name: return ILLn. */
-	s = (char *)rmalloc(3 + 1 + (5 * sizeof(int)) / 2 + 1);
+	const size_t ln = 3 + 1 + (5 * sizeof(int)) / 2 + 1;
+	s = (char *)rmalloc(ln);
 	/* Make sure we have enough space in case i is big */
-	sprintf(s, "ILL%d", i);
+	Common::sprintf_s(s, ln, "ILL%d", i);
 	return s;
 }
 
diff --git a/engines/glk/agt/interface.cpp b/engines/glk/agt/interface.cpp
index e4373a32857..75a54f6ed90 100644
--- a/engines/glk/agt/interface.cpp
+++ b/engines/glk/agt/interface.cpp
@@ -603,7 +603,7 @@ int agt_menu(const char *header, int size, int width, menuentry *menu)
 	for (i = 0; i < colheight; i++) {
 		for (j = 0; j < numcol; j++) {
 			if (j * colheight + i >= size) break;
-			sprintf(sbuff, "%2d.", j * colheight + i + 1);
+			Common::sprintf_s(sbuff, "%2d.", j * colheight + i + 1);
 			writestr(sbuff);
 			writestr(menu[j * colheight + i]);
 			if (j < numcol - 1) padout(width - 3 - strlen(menu[j * colheight + i]));
diff --git a/engines/glk/agt/metacommand.cpp b/engines/glk/agt/metacommand.cpp
index c4eabcc748a..aa6692b0f98 100644
--- a/engines/glk/agt/metacommand.cpp
+++ b/engines/glk/agt/metacommand.cpp
@@ -890,7 +890,7 @@ static void scan_dbg(int vcode) {
 	else w = syntbl[auxsyn[vcode]];
 
 	if (strlen(dict[w]) > 200) return; /* Just in case... */
-	sprintf(buff, "+++++Scanning %s\n", dict[w]);
+	Common::sprintf_s(buff, "+++++Scanning %s\n", dict[w]);
 	debugout(buff);
 }
 
diff --git a/engines/glk/agt/os_glk.cpp b/engines/glk/agt/os_glk.cpp
index 679921589d8..18cbfdf9e18 100644
--- a/engines/glk/agt/os_glk.cpp
+++ b/engines/glk/agt/os_glk.cpp
@@ -3234,7 +3234,7 @@ static void gagt_display_debug() {
 		gagt_paragraphref_t paragraph;
 
 		paragraph = line->paragraph;
-		sprintf(buffer,
+		Common::sprintf_s(buffer,
 		        "%2d:%2d->%2ld A=%-3d L=%-2d I=%-2d O=%-2d R=%-2d %c%c| ",
 		        paragraph ? paragraph->id + 1 : 0,
 		        paragraph ? paragraph->line_count : 0,
@@ -3256,7 +3256,7 @@ static void gagt_display_debug() {
 	}
 
 	if (gagt_current_buffer.length > 0) {
-		sprintf(buffer,
+		Common::sprintf_s(buffer,
 		        "__,__->__ A=%-3d L=%-2d I=__ O=__ R=__ %s| ",
 		        gagt_current_buffer.allocation, gagt_current_buffer.length,
 		        gagt_help_requested ? "HR" : "__");
@@ -4097,7 +4097,7 @@ static void gagt_command_width(const char *argument) {
 	}
 
 	gagt_normal_string("Glk's current display width is approximately ");
-	sprintf(buffer, "%d", status_width);
+	Common::sprintf_s(buffer, "%d", status_width);
 	gagt_normal_string(buffer);
 	gagt_normal_string(status_width == 1 ? " character" : " characters");
 	gagt_normal_string(".\n");
@@ -4216,7 +4216,7 @@ static void gagt_command_statusline(const char *argument) {
 static void gagt_command_print_version_number(glui32 version) {
 	char buffer[64];
 
-	sprintf(buffer, "%u.%u.%u",
+	Common::sprintf_s(buffer, "%u.%u.%u",
 	        version >> 16, (version >> 8) & 0xff, version & 0xff);
 	gagt_normal_string(buffer);
 }
diff --git a/engines/glk/agt/parser.cpp b/engines/glk/agt/parser.cpp
index 31791dd86d9..a9c1ee6ebd4 100644
--- a/engines/glk/agt/parser.cpp
+++ b/engines/glk/agt/parser.cpp
@@ -112,17 +112,17 @@ static void print_nlist(parse_rec *n) {
 	for (c = 0; n->info != D_END && c < 20; n++, c++)
 		if (n->info == D_AND) writestr(" AND ");
 		else if (n->info == D_NUM) { /* Number entered */
-			sprintf(buff, "#%ld(%d); ", n->num, n->obj);
+			Common::sprintf_s(buff, "#%ld(%d); ", n->num, n->obj);
 			writestr(buff);
 		} else if (n->obj < 0) {
 			writestr(dict[-(n->obj)]);
-			sprintf(buff, "(%d); ", n->obj);
+			Common::sprintf_s(buff, "(%d); ", n->obj);
 			writestr(buff);
 		} else {
 			s = objname(n->obj);
 			writestr(s);
 			rfree(s);
-			sprintf(buff, "(%d) ['%s %s']; ", n->obj, dict[n->adj], dict[n->noun]);
+			Common::sprintf_s(buff, "(%d) ['%s %s']; ", n->obj, dict[n->adj], dict[n->noun]);
 			writestr(buff);
 		}
 	if (n->info != D_END) writestr("///");
@@ -922,7 +922,7 @@ static int disambig_phrase(parse_rec **ilist, parse_rec *truenoun, int tn_ofs,
 					s = (char *)objname(list[i].obj);
 				else {
 					s = (char *)rmalloc(30 * sizeof(char));
-					sprintf(s, "%ld", list[i].num);
+					Common::sprintf_s(s, 30, "%ld", list[i].num);
 				}
 				writestr(s);
 				rfree(s);
diff --git a/engines/glk/agt/runverb.cpp b/engines/glk/agt/runverb.cpp
index bbf3d9e9381..c6a1b552bae 100644
--- a/engines/glk/agt/runverb.cpp
+++ b/engines/glk/agt/runverb.cpp
@@ -1131,7 +1131,7 @@ static void exec_verb_info(void) {
 	a = objname(dobj);
 	b = objname(iobj);
 	c = objname(actor);
-	sprintf(buff, "\t\t]]%s, %s %s(%ld) %s %s(%ld)", c, dict[ syntbl[auxsyn[vb]] ],
+	Common::sprintf_s(buff, "\t\t]]%s, %s %s(%ld) %s %s(%ld)", c, dict[ syntbl[auxsyn[vb]] ],
 	        a, dobj_rec->num, prep == 0 ? "->" : dict[prep], b, iobj_rec->num);
 	writeln(buff);
 	rfree(a);
diff --git a/engines/glk/agt/token.cpp b/engines/glk/agt/token.cpp
index b34edd6e06e..26a6c71995e 100644
--- a/engines/glk/agt/token.cpp
+++ b/engines/glk/agt/token.cpp
@@ -87,9 +87,9 @@ static long ask_for_number(int n1, int n2) {
 	int n;
 
 	if (n1 != n2)
-		sprintf(s, "Enter a number from %d to %d: ", n1, n2);
+		Common::sprintf_s(s, "Enter a number from %d to %d: ", n1, n2);
 	else
-		sprintf(s, "Enter a number: ");
+		Common::sprintf_s(s, "Enter a number: ");
 	for (;;) {
 		writestr(s);
 		n = read_number();
diff --git a/engines/glk/agt/util.cpp b/engines/glk/agt/util.cpp
index 6cd027c7620..42d46d8aefe 100644
--- a/engines/glk/agt/util.cpp
+++ b/engines/glk/agt/util.cpp
@@ -100,7 +100,7 @@ void rprintf(const char *fmt, ...) {
 	va_list args;
 
 	va_start(args, fmt);
-	vsprintf(s, fmt, args);
+	Common::vsprintf_s(s, fmt, args);
 	va_end(args);
 	i = strlen(s) - 1;
 	if (i >= 0 && s[i] == '\n') {
@@ -316,8 +316,9 @@ void build_trans_ascii(void) {
 
 void print_error(const char *fname, filetype ext, const char *err, rbool ferr) {
 	char *estring; /* Hold error string */
-	estring = (char *)rmalloc(strlen(err) + strlen(fname) + 2);
-	sprintf(estring, err, fname);
+	size_t ln = strlen(err) + strlen(fname) + 2;
+	estring = (char *)rmalloc(ln);
+	Common::sprintf_s(estring, ln, err, fname);
 	if (ferr) fatal(estring);
 	else writeln(estring);
 	rfree(estring);
@@ -568,7 +569,7 @@ buffreopen will be called before any major file activity
 	if (agx_file) block_size = minbuff; /* Just for the beginning */
 
 	if (block_size % recnum != 0) {
-		sprintf(ebuff, "Fractional record count in %s file.", rectype);
+		Common::sprintf_s(ebuff, "Fractional record count in %s file.", rectype);
 		agtwarn(ebuff, 0);
 	}
 	buff_rsize = recsize = block_size / recnum;
@@ -647,7 +648,7 @@ static void buffreopen(long f_ofs, long file_recsize, long recnum,
 	block_size = bl_size; /* Size of the entire block (all records) */
 	if (block_size % recnum != 0) {
 		/* Check that the number of records divides the block size evenly */
-		sprintf(ebuff, "Fractional record count in %s block.", rectype);
+		Common::sprintf_s(ebuff, "Fractional record count in %s block.", rectype);
 		agtwarn(ebuff, 0);
 	}
 	buff_rsize = recsize = block_size / recnum;
@@ -1444,7 +1445,7 @@ void startwatch(void) {
 
 static char watchbuff[81];
 char *timestring(void) {
-	sprintf(watchbuff, "User:%ld.%02ld   Sys:%ld.%02ld   Total:%ld.%02ld"
+	Common::sprintf_s(watchbuff, "User:%ld.%02ld   Sys:%ld.%02ld   Total:%ld.%02ld"
 	        "   Real:%ld.%02ld",
 	        delta.tms_utime / 100, delta.tms_utime % 100,
 	        delta.tms_stime / 100, delta.tms_stime % 100,
diff --git a/engines/glk/alan2/debug.cpp b/engines/glk/alan2/debug.cpp
index b24ddb7a625..ead9aacd8ee 100644
--- a/engines/glk/alan2/debug.cpp
+++ b/engines/glk/alan2/debug.cpp
@@ -40,7 +40,7 @@ static void showatrs(Aword atradr) {
 
 	i = 1;
 	for (at = (AtrElem *) addrTo(atradr); !endOfTable(at); at++) {
-		sprintf(str, "$i%3ld: %ld (%s)", (long) i, (unsigned long) at->val, (char *) addrTo(at->stradr));
+		Common::sprintf_s(str, "$i%3ld: %ld (%s)", (long) i, (unsigned long) at->val, (char *) addrTo(at->stradr));
 		output(str);
 		i++;
 	}
@@ -52,7 +52,7 @@ static void showobjs() {
 
 	output("OBJECTS:");
 	for (obj = OBJMIN; obj <= OBJMAX; obj++) {
-		sprintf(str, "$i%3ld: ", (long) obj);
+		Common::sprintf_s(str, "$i%3ld: ", (long) obj);
 		output(str);
 		say(obj);
 	}
@@ -64,16 +64,16 @@ static void showobj(int obj) {
 
 
 	if (!isObj(obj)) {
-		sprintf(str, "Object number out of range. Between %ld and %ld, please.", (unsigned long) OBJMIN, (unsigned long) OBJMAX);
+		Common::sprintf_s(str, "Object number out of range. Between %ld and %ld, please.", (unsigned long) OBJMIN, (unsigned long) OBJMAX);
 		output(str);
 		return;
 	}
 
-	sprintf(str, "OBJECT %d :", obj);
+	Common::sprintf_s(str, "OBJECT %d :", obj);
 	output(str);
 	say(obj);
 
-	sprintf(str, "$iLocation = %ld", (unsigned long) where(obj));
+	Common::sprintf_s(str, "$iLocation = %ld", (unsigned long) where(obj));
 	output(str);
 	if (isLoc(objs[OBJ].loc))
 		say(objs[OBJ].loc);
@@ -105,7 +105,7 @@ static void showcnts() {
 
 	output("CONTAINERS:");
 	for (cnt = CNTMIN; cnt <= CNTMAX; cnt++) {
-		sprintf(str, "$i%3ld: ", (long) cnt);
+		Common::sprintf_s(str, "$i%3ld: ", (long) cnt);
 		output(str);
 		if (cnts[CNT].nam != 0)
 			interpret(cnts[CNT].nam);
@@ -123,19 +123,19 @@ static void showcnt(int cnt) {
 #define  CNT (int)(cnt - CNTMIN)
 
 	if (cnt < (int)CNTMIN || cnt >(int)CNTMAX) {
-		sprintf(str, "Container number out of range. Between %ld and %ld, please.", (unsigned long) CNTMIN, (unsigned long) CNTMAX);
+		Common::sprintf_s(str, "Container number out of range. Between %ld and %ld, please.", (unsigned long) CNTMIN, (unsigned long) CNTMAX);
 		output(str);
 		return;
 	}
 
-	sprintf(str, "CONTAINER %d :", cnt);
+	Common::sprintf_s(str, "CONTAINER %d :", cnt);
 	output(str);
 	if (cnts[CNT].nam != 0)
 		interpret(cnts[CNT].nam);
 	if (cnts[CNT].parent != 0) {
 		cnt = cnts[CNT].parent;
 		say(cnt);
-		sprintf(str, "$iLocation = %ld", (unsigned long) where(cnt));
+		Common::sprintf_s(str, "$iLocation = %ld", (unsigned long) where(cnt));
 		output(str);
 	}
 	output("$iContains ");
@@ -145,7 +145,7 @@ static void showcnt(int cnt) {
 				output("$n");
 				found = TRUE;
 			}
-			sprintf(str, "$t$t%d: ", i);
+			Common::sprintf_s(str, "$t$t%d: ", i);
 			output(str);
 			say(i);
 		}
@@ -162,7 +162,7 @@ static void showlocs() {
 
 	output("LOCATIONS:");
 	for (loc = LOCMIN; loc <= LOCMAX; loc++) {
-		sprintf(str, "$i%3ld: ", (long) loc);
+		Common::sprintf_s(str, "$i%3ld: ", (long) loc);
 		output(str);
 		say(loc);
 	}
@@ -173,12 +173,12 @@ static void showloc(int loc) {
 
 
 	if (!isLoc(loc)) {
-		sprintf(str, "Location number out of range. Between %ld and %ld, please.", (unsigned long) LOCMIN, (unsigned long) LOCMAX);
+		Common::sprintf_s(str, "Location number out of range. Between %ld and %ld, please.", (unsigned long) LOCMIN, (unsigned long) LOCMAX);
 		output(str);
 		return;
 	}
 
-	sprintf(str, "LOCATION %d :", loc);
+	Common::sprintf_s(str, "LOCATION %d :", loc);
 	output(str);
 	say(loc);
 
@@ -192,7 +192,7 @@ static void showacts() {
 
 	output("ACTORS:");
 	for (act = ACTMIN; act <= ACTMAX; act++) {
-		sprintf(str, "$i%3ld:", (long) act);
+		Common::sprintf_s(str, "$i%3ld:", (long) act);
 		output(str);
 		say(act);
 	}
@@ -203,19 +203,19 @@ static void showact(int act) {
 	Boolean oldstp;
 
 	if (!isAct(act)) {
-		sprintf(str, "Actor number out of range. Between %ld and %ld, please.", (unsigned long) ACTMIN, (unsigned long) ACTMAX);
+		Common::sprintf_s(str, "Actor number out of range. Between %ld and %ld, please.", (unsigned long) ACTMIN, (unsigned long) ACTMAX);
 		output(str);
 		return;
 	}
 
-	sprintf(str, "ACTOR %d :", act);
+	Common::sprintf_s(str, "ACTOR %d :", act);
 	output(str);
 	oldstp = stpflg;
 	stpflg = FALSE; /* Make sure not to trace this! */
 	say(act);
 	stpflg = oldstp;
 
-	sprintf(str, "$iLocation = %ld", (unsigned long) acts[act - ACTMIN].loc);
+	Common::sprintf_s(str, "$iLocation = %ld", (unsigned long) acts[act - ACTMIN].loc);
 	output(str);
 	if (isLoc(acts[act - ACTMIN].loc))
 		say(acts[act - ACTMIN].loc);
@@ -224,10 +224,10 @@ static void showact(int act) {
 	else
 		output("Illegal location!");
 
-	sprintf(str, "$iScript = %ld", (unsigned long) acts[act - ACTMIN].script);
+	Common::sprintf_s(str, "$iScript = %ld", (unsigned long) acts[act - ACTMIN].script);
 	output(str);
 
-	sprintf(str, "$iStep = %ld", (unsigned long) acts[act - ACTMIN].step);
+	Common::sprintf_s(str, "$iStep = %ld", (unsigned long) acts[act - ACTMIN].step);
 	output(str);
 
 	output("$iAttributes =");
@@ -241,14 +241,14 @@ static void showevts() {
 
 	output("EVENTS:");
 	for (uint evt = EVTMIN; evt <= EVTMAX; evt++) {
-		sprintf(str, "$i%d (%s):", evt, (char *)addrTo(evts[evt - EVTMIN].stradr));
+		Common::sprintf_s(str, "$i%d (%s):", evt, (char *)addrTo(evts[evt - EVTMIN].stradr));
 		output(str);
 		scheduled = FALSE;
 		for (i = 0; i < etop; i++)
 			if ((scheduled = (eventq[i].event == (int)evt)))
 				break;
 		if (scheduled) {
-			sprintf(str, "Scheduled for +%d, at ", eventq[i].time - cur.tick);
+			Common::sprintf_s(str, "Scheduled for +%d, at ", eventq[i].time - cur.tick);
 			output(str);
 			say(eventq[i].where);
 		} else
diff --git a/engines/glk/alan2/exe.cpp b/engines/glk/alan2/exe.cpp
index 626c4fa4869..0e2bb9756eb 100644
--- a/engines/glk/alan2/exe.cpp
+++ b/engines/glk/alan2/exe.cpp
@@ -137,10 +137,10 @@ void score(Aword sc) {
 
 	if (sc == 0) {
 		prmsg(M_SCORE1);
-		sprintf(buf, "%d", cur.score);
+		Common::sprintf_s(buf, "%d", cur.score);
 		output(buf);
 		prmsg(M_SCORE2);
-		sprintf(buf, "%ld.", (unsigned long) header->maxscore);
+		Common::sprintf_s(buf, "%ld.", (unsigned long) header->maxscore);
 		output(buf);
 	} else {
 		cur.score += scores[sc - 1];
@@ -304,7 +304,7 @@ void make(Aword id, Aword atr, Aword val) {
 	else if (isAct(id))
 		makact(id, atr, val);
 	else {
-		sprintf(str, "Can't MAKE item (%ld).", (unsigned long) id);
+		Common::sprintf_s(str, "Can't MAKE item (%ld).", (unsigned long) id);
 		syserr(str);
 	}
 }
@@ -339,7 +339,7 @@ void set(Aword id, Aword atr, Aword val) {
 	else if (isAct(id))
 		setact(id, atr, val);
 	else {
-		sprintf(str, "Can't SET item (%ld).", (unsigned long) id);
+		Common::sprintf_s(str, "Can't SET item (%ld).", (unsigned long) id);
 		syserr(str);
 	}
 }
@@ -398,7 +398,7 @@ void incr(Aword id, Aword atr, Aword step) {
 	else if (isAct(id))
 		incract(id, atr, step);
 	else {
-		sprintf(str, "Can't INCR item (%ld).", (unsigned long) id);
+		Common::sprintf_s(str, "Can't INCR item (%ld).", (unsigned long) id);
 		syserr(str);
 	}
 }
@@ -415,7 +415,7 @@ void decr(Aword id, Aword atr, Aword step) {
 	else if (isAct(id))
 		incract(id, atr, static_cast<uint>(-(int)step));
 	else {
-		sprintf(str, "Can't DECR item (%ld).", (unsigned long) id);
+		Common::sprintf_s(str, "Can't DECR item (%ld).", (unsigned long) id);
 		syserr(str);
 	}
 }
@@ -445,7 +445,7 @@ static Aptr litatr(Aword lit, Aword atr) {
 	if (atr == 1)
 		return litValues[lit - LITMIN].value;
 	else {
-		sprintf(str, "Unknown attribute for literal (%ld).", (unsigned long) atr);
+		Common::sprintf_s(str, "Unknown attribute for literal (%ld).", (unsigned long) atr);
 		syserr(str);
 	}
 	return (Aptr)EOD;
@@ -463,7 +463,7 @@ Aptr attribute(Aword id, Aword atr) {
 	else if (isLit(id))
 		return litatr(id, atr);
 	else {
-		sprintf(str, "Can't ATTRIBUTE item (%ld).", (unsigned long) id);
+		Common::sprintf_s(str, "Can't ATTRIBUTE item (%ld).", (unsigned long) id);
 		syserr(str);
 	}
 	return (Aptr)EOD;
@@ -502,7 +502,7 @@ Aword where(Aword id) {
 	else if (isAct(id))
 		return actloc(id);
 	else {
-		sprintf(str, "Can't WHERE item (%ld).", (unsigned long) id);
+		Common::sprintf_s(str, "Can't WHERE item (%ld).", (unsigned long) id);
 		syserr(str);
 	}
 	return (Aptr)EOD;
@@ -619,7 +619,7 @@ void locate(Aword id, Aword whr) {
 	else if (isAct(id))
 		locact(id, whr);
 	else {
-		sprintf(str, "Can't LOCATE item (%ld).", (unsigned long) id);
+		Common::sprintf_s(str, "Can't LOCATE item (%ld).", (unsigned long) id);
 		syserr(str);
 	}
 }
@@ -654,7 +654,7 @@ Abool isHere(Aword id) {
 	else if (isAct(id))
 		return acthere(id);
 	else {
-		sprintf(str, "Can't HERE item (%ld).", (unsigned long) id);
+		Common::sprintf_s(str, "Can't HERE item (%ld).", (unsigned long) id);
 		syserr(str);
 	}
 	return (Abool)EOD;
@@ -688,7 +688,7 @@ Abool isNear(Aword id) {
 	else if (isAct(id))
 		return actnear(id);
 	else {
-		sprintf(str, "Can't NEAR item (%ld).", (unsigned long) id);
+		Common::sprintf_s(str, "Can't NEAR item (%ld).", (unsigned long) id);
 		syserr(str);
 	}
 	return (Abool)EOD;
@@ -733,7 +733,7 @@ void sayint(Aword val) {
 	char buf[25];
 
 	if (isHere(HERO)) {
-		sprintf(buf, "%ld", (unsigned long) val);
+		Common::sprintf_s(buf, "%ld", (unsigned long) val);
 		output(buf);
 	}
 }
@@ -777,7 +777,7 @@ void say(Aword id) {
 		else if (isLit(id))
 			saylit(id);
 		else {
-			sprintf(str, "Can't SAY item (%ld).", (unsigned long) id);
+			Common::sprintf_s(str, "Can't SAY item (%ld).", (unsigned long) id);
 			syserr(str);
 		}
 	}
@@ -848,7 +848,7 @@ void describe(Aword id) {
 	else if (isAct(id))
 		dscract(id);
 	else {
-		sprintf(str, "Can't DESCRIBE item (%ld).", (unsigned long) id);
+		Common::sprintf_s(str, "Can't DESCRIBE item (%ld).", (unsigned long) id);
 		syserr(str);
 	}
 
@@ -866,7 +866,7 @@ void use(Aword act, Aword scr) {
 	char str[80];
 
 	if (!isAct(act)) {
-		sprintf(str, "Item is not an Actor (%ld).", (unsigned long) act);
+		Common::sprintf_s(str, "Item is not an Actor (%ld).", (unsigned long) act);
 		syserr(str);
 	}
 
diff --git a/engines/glk/alan2/glkio.cpp b/engines/glk/alan2/glkio.cpp
index 47e4119a463..6b7c8761d61 100644
--- a/engines/glk/alan2/glkio.cpp
+++ b/engines/glk/alan2/glkio.cpp
@@ -39,7 +39,7 @@ void glkio_printf(const char *fmt, ...) {
 	va_start(argp, fmt);
 	if (glkMainWin) {
 		char buf[1024]; /* FIXME: buf size should be foolproof */
-		vsprintf(buf, fmt, argp);
+		Common::vsprintf_s(buf, fmt, argp);
 		g_vm->glk_put_string(buf);
 	} else {
 		// assume stdio is available in this case only
diff --git a/engines/glk/alan2/main.cpp b/engines/glk/alan2/main.cpp
index fbd903f85d2..07dc415849a 100644
--- a/engines/glk/alan2/main.cpp
+++ b/engines/glk/alan2/main.cpp
@@ -189,9 +189,9 @@ void statusline() {
 	needsp = FALSE;
 	say(where(HERO));
 	if (header->maxscore > 0)
-		sprintf(line, "Score %d(%d)/%d moves", cur.score, (int)header->maxscore, cur.tick);
+		Common::sprintf_s(line, "Score %d(%d)/%d moves", cur.score, (int)header->maxscore, cur.tick);
 	else
-		sprintf(line, "%d moves", cur.tick);
+		Common::sprintf_s(line, "%d moves", cur.tick);
 	g_vm->glk_window_move_cursor(glkStatusWin, glkWidth - col - strlen(line), 0);
 	printf(line);
 	needsp = FALSE;
@@ -867,7 +867,7 @@ static void do_it(CONTEXT) {
 						else if (i == 1)
 							Common::strcpy_s(trace, "in LOCATION");
 						else
-							sprintf(trace, "in PARAMETER %d", i - 1);
+							Common::sprintf_s(trace, "in PARAMETER %d", i - 1);
 						if (alt[i]->qual == (Aword)Q_BEFORE)
 							printf("\n<VERB %d, %s (BEFORE), Body:>\n", cur.vrb, trace);
 						else
@@ -893,7 +893,7 @@ static void do_it(CONTEXT) {
 						else if (i == 1)
 							Common::strcpy_s(trace, "in LOCATION");
 						else
-							sprintf(trace, "in PARAMETER %d", i - 1);
+							Common::sprintf_s(trace, "in PARAMETER %d", i - 1);
 						printf("\n<VERB %d, %s, Body:>\n", cur.vrb, trace);
 					}
 					CALL1(interpret, alt[i]->action)
@@ -914,7 +914,7 @@ static void do_it(CONTEXT) {
 					else if (i == 1)
 						Common::strcpy_s(trace, "in LOCATION");
 					else
-						sprintf(trace, "in PARAMETER %d", i - 1);
+						Common::sprintf_s(trace, "in PARAMETER %d", i - 1);
 					printf("\n<VERB %d, %s (AFTER), Body:>\n", cur.vrb, trace);
 				}
 				CALL1(interpret, alt[i]->action)
@@ -943,7 +943,7 @@ void action(CONTEXT, ParamElem plst[] /* IN - Plural parameter list */) {
 		   over this position (and replace it by each present in the plst)
 		 */
 		for (mpos = 0; params[mpos].code != 0; mpos++); /* Find multiple position */
-		sprintf(marker, "($%d)", mpos + 1); /* Prepare a printout with $1/2/3 */
+		Common::sprintf_s(marker, "($%d)", mpos + 1); /* Prepare a printout with $1/2/3 */
 		for (i = 0; plst[i].code != EOD; i++) {
 			params[mpos] = plst[i];
 			output(marker);
@@ -1049,7 +1049,7 @@ static void checkvers(AcdHdr *hdr) {
 #endif
 				if (errflg) {
 					char str[80];
-					sprintf(str, "Incompatible version of ACODE program. Game is %ld.%ld, interpreter %ld.%ld.",
+					Common::sprintf_s(str, "Incompatible version of ACODE program. Game is %ld.%ld, interpreter %ld.%ld.",
 					        (long)(hdr->vers[0]),
 					        (long)(hdr->vers[1]),
 					        (long) alan.version.version,
@@ -1108,7 +1108,7 @@ static void load() {
 		crc += (memory[i] >> 24) & 0xff;
 	}
 	if (crc != tmphdr.acdcrc) {
-		sprintf(err, "Checksum error in .ACD file (0x%lx instead of 0x%lx).",
+		Common::sprintf_s(err, "Checksum error in .ACD file (0x%lx instead of 0x%lx).",
 		        (unsigned long) crc, (unsigned long) tmphdr.acdcrc);
 		if (errflg)
 			syserr(err);
diff --git a/engines/glk/alan2/parse.cpp b/engines/glk/alan2/parse.cpp
index fd579dc79a0..0a8b1ebb5a0 100644
--- a/engines/glk/alan2/parse.cpp
+++ b/engines/glk/alan2/parse.cpp
@@ -622,7 +622,7 @@ static void tryMatch(CONTEXT, ParamElem matchLst[]) {
 						   It wasn't ALL, we need to say something about it, so
 						   prepare a printout with $1/2/3
 						 */
-						sprintf(marker, "($%ld)", (unsigned long) cla->code);
+						Common::sprintf_s(marker, "($%ld)", (unsigned long) cla->code);
 						output(marker);
 						interpret(cla->stms);
 						para();
diff --git a/engines/glk/alan3/act.cpp b/engines/glk/alan3/act.cpp
index ab2608e8651..4943940230a 100644
--- a/engines/glk/alan3/act.cpp
+++ b/engines/glk/alan3/act.cpp
@@ -99,7 +99,7 @@ void action(CONTEXT, int verb, Parameter parameters[], Parameter multipleMatches
 
 	multiplePosition = findMultiplePosition(parameters);
 	if (multiplePosition != -1) {
-		sprintf(marker, "($%d)", multiplePosition + 1); /* Prepare a printout with $1/2/3 */
+		Common::sprintf_s(marker, "($%d)", multiplePosition + 1); /* Prepare a printout with $1/2/3 */
 		for (int i = 0; !isEndOfArray(&multipleMatches[i]); i++) {
 			copyParameter(&parameters[multiplePosition], &multipleMatches[i]);
 			setGlobalParameters(parameters); /* Need to do this here since the marker use them */
diff --git a/engines/glk/alan3/debug.cpp b/engines/glk/alan3/debug.cpp
index 32e4cd5b1a8..a13fee780a0 100644
--- a/engines/glk/alan3/debug.cpp
+++ b/engines/glk/alan3/debug.cpp
@@ -62,7 +62,7 @@ static void showAttributes(AttributeEntry *attrib) {
 
 	i = 1;
 	for (at = attrib; !isEndOfArray(at); at++) {
-		sprintf(str, "$i$t%s[%d] = %d", (char *) pointerTo(at->id), at->code, (int)at->value);
+		Common::sprintf_s(str, "$i$t%s[%d] = %d", (char *) pointerTo(at->id), at->code, (int)at->value);
 
 		output(str);
 		i++;
@@ -83,7 +83,7 @@ static void showContents(CONTEXT, int cnt) {
 				found = TRUE;
 			output("$i$t");
 			say(context, i);
-			sprintf(str, "[%d] ", i);
+			Common::sprintf_s(str, "[%d] ", i);
 			output(str);
 		}
 	}
@@ -104,7 +104,7 @@ static char *idOfInstance(CONTEXT, int instance) {
 static void sayInstanceNumberAndName(CONTEXT, int ins) {
 	char buf[1000];
 
-	sprintf(buf, "[%d] %s (\"$$", ins, idOfInstance(context, ins));
+	Common::sprintf_s(buf, "[%d] %s (\"$$", ins, idOfInstance(context, ins));
 	output(buf);
 	say(context, ins);
 	output("$$\")");
@@ -167,7 +167,7 @@ static void showInstance(CONTEXT, int ins) {
 	char str[80];
 
 	if (ins > (int)header->instanceMax || ins < 1) {
-		sprintf(str, "Instance index %d is out of range.", ins);
+		Common::sprintf_s(str, "Instance index %d is out of range.", ins);
 		output(str);
 		return;
 	}
@@ -175,12 +175,12 @@ static void showInstance(CONTEXT, int ins) {
 	output("The");
 	CALL1(sayInstanceNumberAndName, ins)
 	if (instances[ins].parent) {
-		sprintf(str, "Isa %s[%d]", idOfClass(instances[ins].parent), instances[ins].parent);
+		Common::sprintf_s(str, "Isa %s[%d]", idOfClass(instances[ins].parent), instances[ins].parent);
 		output(str);
 	}
 
 	if (!isA(ins, header->locationClassId) || (isA(ins, header->locationClassId) && admin[ins].location != 0)) {
-		sprintf(str, "$iLocation:");
+		Common::sprintf_s(str, "$iLocation:");
 		output(str);
 		needSpace = TRUE;
 		CALL2(sayLocationOfInstance, ins, "")
@@ -196,7 +196,7 @@ static void showInstance(CONTEXT, int ins) {
 		if (admin[ins].script == 0)
 			output("$iIs idle");
 		else {
-			sprintf(str, "$iExecuting script: %d, Step: %d", admin[ins].script, admin[ins].step);
+			Common::sprintf_s(str, "$iExecuting script: %d, Step: %d", admin[ins].script, admin[ins].step);
 			output(str);
 		}
 	}
@@ -220,7 +220,7 @@ static void showObject(CONTEXT, int obj) {
 
 
 	if (!isAObject(obj)) {
-		sprintf(str, "Instance %d is not an object", obj);
+		Common::sprintf_s(str, "Instance %d is not an object", obj);
 		output(str);
 		return;
 	}
@@ -258,7 +258,7 @@ static void showClassInheritance(int c) {
 	if (classes[c].parent != 0) {
 		output(", Isa");
 		printClassName(classes[c].parent);
-		sprintf(str, "[%d]", classes[c].parent);
+		Common::sprintf_s(str, "[%d]", classes[c].parent);
 		output(str);
 	}
 }
@@ -269,14 +269,14 @@ static void showClass(int cla) {
 	char str[80];
 
 	if (cla < 1) {
-		sprintf(str, "Class index %d is out of range.", cla);
+		Common::sprintf_s(str, "Class index %d is out of range.", cla);
 		output(str);
 		return;
 	}
 
 	output("$t");
 	printClassName(cla);
-	sprintf(str, "[%d]", cla);
+	Common::sprintf_s(str, "[%d]", cla);
 	output(str);
 	showClassInheritance(cla);
 }
@@ -286,7 +286,7 @@ static void showClass(int cla) {
 static void listClass(int c) {
 	char str[80];
 
-	sprintf(str, "%3d: ", c);
+	Common::sprintf_s(str, "%3d: ", c);
 	output(str);
 	printClassName(c);
 	showClassInheritance(c);
@@ -328,14 +328,14 @@ static void showLocation(CONTEXT, int loc) {
 
 
 	if (!isALocation(loc)) {
-		sprintf(str, "Instance %d is not a location.", loc);
+		Common::sprintf_s(str, "Instance %d is not a location.", loc);
 		output(str);
 		return;
 	}
 
 	output("The ");
 	CALL1(say, loc)
-	sprintf(str, "(%d) Isa location :", loc);
+	Common::sprintf_s(str, "(%d) Isa location :", loc);
 	output(str);
 
 	output("$iAttributes =");
@@ -359,7 +359,7 @@ static void showActor(CONTEXT, int act) {
 	char str[80];
 
 	if (!isAActor(act)) {
-		sprintf(str, "Instance %d is not an actor.", act);
+		Common::sprintf_s(str, "Instance %d is not an actor.", act);
 		output(str);
 		return;
 	}
@@ -377,7 +377,7 @@ static void showEvents(CONTEXT) {
 
 	output("Events:");
 	for (event = 1; event <= header->eventMax; event++) {
-		sprintf(str, "$i%d [%s]:", event, (char *)pointerTo(events[event].id));
+		Common::sprintf_s(str, "$i%d [%s]:", event, (char *)pointerTo(events[event].id));
 
 		output(str);
 		scheduled = FALSE;
@@ -385,7 +385,7 @@ static void showEvents(CONTEXT) {
 			if ((scheduled = (eventQueue[i].event == (int)event)))
 				break;
 		if (scheduled) {
-			sprintf(str, "Scheduled for +%d, at ", eventQueue[i].after);
+			Common::sprintf_s(str, "Scheduled for +%d, at ", eventQueue[i].after);
 			output(str);
 			CALL1(say, eventQueue[i].where)
 		} else
@@ -541,7 +541,7 @@ static void setBreakpoint(int file, int line) {
 				printf("Line %d not available\n", line);
 			} else {
 				if (entry[lineIndex].line != line)
-					sprintf(leadingText, "Line %d not available, breakpoint instead", line);
+					Common::sprintf_s(leadingText, "Line %d not available, breakpoint instead", line);
 				breakpoint[i].file = entry[lineIndex].file;
 				breakpoint[i].line = entry[lineIndex].line;
 				printf("%s set at %s:%d\n", leadingText, sourceFileName(entry[lineIndex].file), entry[lineIndex].line);
@@ -698,7 +698,7 @@ static void handleHelpCommand() {
 	output("$nADBG Commands (can be abbreviated):");
 	for (entry = commandEntries; entry->command != nullptr; entry++) {
 		char buf[200];
-		sprintf(buf, "$i%s %s %s$n$t$t-- %s", entry->command, entry->parameter, padding(entry, maxLength), entry->helpText);
+		Common::sprintf_s(buf, "$i%s %s %s$n$t$t-- %s", entry->command, entry->parameter, padding(entry, maxLength), entry->helpText);
 		output(buf);
 	}
 }
diff --git a/engines/glk/alan3/exe.cpp b/engines/glk/alan3/exe.cpp
index a8744114baf..1767d09406e 100644
--- a/engines/glk/alan3/exe.cpp
+++ b/engines/glk/alan3/exe.cpp
@@ -535,7 +535,7 @@ void use(CONTEXT, int actor, int script) {
 	StepEntry *step;
 
 	if (!isAActor(actor)) {
-		sprintf(str, "Instance is not an Actor (%d).", actor);
+		Common::sprintf_s(str, "Instance is not an Actor (%d).", actor);
 		syserr(str);
 	}
 
@@ -554,7 +554,7 @@ void stop(int act) {
 	char str[80];
 
 	if (!isAActor(act)) {
-		sprintf(str, "Instance is not an Actor (%d).", act);
+		Common::sprintf_s(str, "Instance is not an Actor (%d).", act);
 		syserr(str);
 	}
 
diff --git a/engines/glk/alan3/glkio.cpp b/engines/glk/alan3/glkio.cpp
index 6ea8224b922..b350011c591 100644
--- a/engines/glk/alan3/glkio.cpp
+++ b/engines/glk/alan3/glkio.cpp
@@ -144,9 +144,9 @@ void GlkIO::statusLine(CONTEXT) {
 
 		// TODO Add status message1  & 2 as author customizable messages
 		if (header->maximumScore > 0)
-			sprintf(line, "Score %d(%d)/%d moves", current.score, (int)header->maximumScore, current.tick);
+			Common::sprintf_s(line, "Score %d(%d)/%d moves", current.score, (int)header->maximumScore, current.tick);
 		else
-			sprintf(line, "%d moves", current.tick);
+			Common::sprintf_s(line, "%d moves", current.tick);
 	glk_window_move_cursor(glkStatusWin, glkWidth - strlen(line) - 1, 0);
 	glk_put_string(line);
 	needSpace = FALSE;
diff --git a/engines/glk/alan3/instance.cpp b/engines/glk/alan3/instance.cpp
index e2ec48493ab..4ffe5b17406 100644
--- a/engines/glk/alan3/instance.cpp
+++ b/engines/glk/alan3/instance.cpp
@@ -130,7 +130,7 @@ void setInstanceAttribute(int instance, int attribute, Aptr value) {
 			   changed so describe next time */
 			admin[instance].visitsCount = 0;
 	} else {
-		sprintf(str, "Can't SET/MAKE instance (%d).", instance);
+		Common::sprintf_s(str, "Can't SET/MAKE instance (%d).", instance);
 		syserr(str);
 	}
 }
@@ -180,7 +180,7 @@ Aptr getInstanceAttribute(int instance, int attribute) {
 			else
 				return getAttribute(admin[instance].attributes, attribute);
 		} else {
-			sprintf(str, "Can't ATTRIBUTE item (%d).", instance);
+			Common::sprintf_s(str, "Can't ATTRIBUTE item (%d).", instance);
 			syserr(str);
 		}
 	}
@@ -205,10 +205,10 @@ static void verifyInstance(int instance, const char *action) {
 	char message[200];
 
 	if (instance == 0) {
-		sprintf(message, "Can't %s instance (%d).", action, instance);
+		Common::sprintf_s(message, "Can't %s instance (%d).", action, instance);
 		syserr(message);
 	} else if (instance > (int)header->instanceMax) {
-		sprintf(message, "Can't %s instance (%d > instanceMax).", action, instance);
+		Common::sprintf_s(message, "Can't %s instance (%d > instanceMax).", action, instance);
 		syserr(message);
 	}
 }
@@ -503,7 +503,7 @@ void sayInteger(int value) {
 	char buf[25];
 
 	if (isHere(HERO, /*FALSE*/ TRANSITIVE)) {
-		sprintf(buf, "%d", value);
+		Common::sprintf_s(buf, "%d", value);
 		output(buf);
 	}
 }
@@ -538,7 +538,7 @@ static char *wordWithCode(int classBit, int code) {
 	for (w = 0; w < dictionarySize; w++)
 		if (dictionary[w].code == (Aword)code && ((classBit & dictionary[w].classBits) != 0))
 			return (char *)pointerTo(dictionary[w].string);
-	sprintf(str, "Could not find word of class %d with code %d.", classBit, code);
+	Common::sprintf_s(str, "Could not find word of class %d with code %d.", classBit, code);
 	syserr(str);
 	return nullptr;
 }
diff --git a/engines/glk/alan3/inter.cpp b/engines/glk/alan3/inter.cpp
index f4638d7bd7e..33a69a60014 100644
--- a/engines/glk/alan3/inter.cpp
+++ b/engines/glk/alan3/inter.cpp
@@ -321,7 +321,7 @@ static const char *booleanValue(Abool value) {
 static const char *stringValue(Aptr address) {
 	static char string[1000];
 
-	sprintf(string, "0x%lx (\"%s\")\t\t", (unsigned long) address, (char *)fromAptr(address));
+	Common::sprintf_s(string, "0x%lx (\"%s\")\t\t", (unsigned long) address, (char *)fromAptr(address));
 	return string;
 }
 
@@ -329,7 +329,7 @@ static const char *stringValue(Aptr address) {
 static const char *pointerValue(Aptr address) {
 	static char string[100];
 
-	sprintf(string, "@%6lx", (unsigned long) address);
+	Common::sprintf_s(string, "@%6lx", (unsigned long) address);
 	return string;
 }
 
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index 8d86b519543..899568c2a43 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -183,7 +183,7 @@ static void loadAndCheckMemory(ACodeHeader tmphdr, Aword crc, char err[]) {
 		crc += (memory[i] >> 24) & 0xff;
 	}
 	if (crc != tmphdr.acdcrc) {
-		sprintf(err, "Checksum error in Acode (.a3c) file (0x%lx instead of 0x%lx).",
+		Common::sprintf_s(err, 100, "Checksum error in Acode (.a3c) file (0x%lx instead of 0x%lx).",
 		        (unsigned long) crc, (unsigned long) tmphdr.acdcrc);
 		if (!ignoreErrorOption)
 			syserr(err);
@@ -217,7 +217,7 @@ static const char *decodeState(int c) {
 /*======================================================================*/
 char *decodedGameVersion(const byte version[]) {
 	static char str[100];
-	sprintf(str, "%d.%d%s%d",
+	Common::sprintf_s(str, "%d.%d%s%d",
 	        (int)version[3],
 	        (int)version[2],
 	        decodeState(version[0]),
@@ -268,7 +268,7 @@ static void nonDevelopmentRunningDevelopmentStateGame(const byte version[]) {
 	char versionString[100];
 
 	Common::strcpy_s(errorMessage, "Games generated by a development state compiler");
-	sprintf(versionString, "(this game is v%d.%d.%d%s)", version[0], version[1],
+	Common::sprintf_s(versionString, "(this game is v%d.%d.%d%s)", version[0], version[1],
 	        version[2], decodeState(version[3]));
 	Common::strcat_s(errorMessage, versionString);
 	Common::strcat_s(errorMessage, "can only be run with a matching interpreter. Look for a game file generated with an alpha, beta or release state compiler.>\n");
diff --git a/engines/glk/alan3/parse.cpp b/engines/glk/alan3/parse.cpp
index 2e181a29a1c..b3d383170f1 100644
--- a/engines/glk/alan3/parse.cpp
+++ b/engines/glk/alan3/parse.cpp
@@ -621,9 +621,9 @@ static char *classNameAndId(int classId) {
 	static char buffer[1000] = "";
 
 	if (classId != -1)
-		sprintf(buffer, "%s[%d]", idOfClass(classId), classId);
+		Common::sprintf_s(buffer, "%s[%d]", idOfClass(classId), classId);
 	else
-		sprintf(buffer, "Container");
+		Common::sprintf_s(buffer, "Container");
 	return buffer;
 }
 
@@ -635,9 +635,9 @@ static char *parameterNumberAndName(int parameterNumber) {
 	char *parameterName = parameterNameInSyntax(current.syntax, parameterNumber);
 
 	if (parameterName != nullptr)
-		sprintf(buffer, "%s(#%d)", parameterName, parameterNumber);
+		Common::sprintf_s(buffer, "%s(#%d)", parameterName, parameterNumber);
 	else
-		sprintf(buffer, "#%d", parameterNumber);
+		Common::sprintf_s(buffer, "#%d", parameterNumber);
 	return buffer;
 }
 
@@ -892,7 +892,7 @@ static void checkRestrictedParameters(CONTEXT, ParameterPosition parameterPositi
 						/* It wasn't ALL, we need to say something about it, so
 						 * prepare a printout with $1/2/3
 						 */
-						sprintf(marker, "($%ld)", (unsigned long) restriction->parameterNumber);
+						Common::sprintf_s(marker, "($%ld)", (unsigned long) restriction->parameterNumber);
 						setGlobalParameters(localParameters);
 						output(marker);
 						CALL2(runRestriction, restriction, localParameters)
diff --git a/engines/glk/hugo/heexpr.cpp b/engines/glk/hugo/heexpr.cpp
index 3b682903ad9..202ff7a4055 100644
--- a/engines/glk/hugo/heexpr.cpp
+++ b/engines/glk/hugo/heexpr.cpp
@@ -245,7 +245,7 @@ ReturnResult:
 #if defined (DEBUG_EXPR_EVAL)
 	if (p==0 && exprt)
 	{
-		sprintf(line, " = %d", result);
+		Common::sprintf_s(line, " = %d", result);
 		AP(line);
 	}
 #endif
@@ -968,7 +968,7 @@ char Hugo::IsIncrement(long addr) {
 	if (t && debug_eval)
 	{
 		debug_eval_error = true;
-		sprintf(debug_line, "'%s%s' illegal in watch/assignment", token[a], token[MEM(addr+1)]);
+		Common::sprintf_s(debug_line, "'%s%s' illegal in watch/assignment", token[a], token[MEM(addr+1)]);
 		DebugMessageBox("Expression Error", debug_line);
 		t = 0;
 	}
@@ -1027,7 +1027,7 @@ void PrintExpr(void)
 		{
 			case 0:
 			{
-				sprintf(line, "%d ", eval[i + 1]);
+				Common::sprintf_s(line, "%d ", eval[i + 1]);
 				strcat(e, line);
 				break;
 			}
diff --git a/engines/glk/hugo/hemedia.cpp b/engines/glk/hugo/hemedia.cpp
index 54fb07b8d01..142db57a2cb 100644
--- a/engines/glk/hugo/hemedia.cpp
+++ b/engines/glk/hugo/hemedia.cpp
@@ -42,7 +42,7 @@ int Hugo::loadres(HUGO_FILE infile, int reslen, int type) {
 		return -1;
 
 	idVal = numres[type]++;
-	sprintf(buf, "%s%d", type == PIC ? "PIC" : "SND", idVal);
+	Common::sprintf_s(buf, "%s%d", type == PIC ? "PIC" : "SND", idVal);
 	resids[type][idVal] = offset;
 
 	fileref = glk_fileref_create_by_name(fileusage_Data, buf, 0);
diff --git a/engines/glk/hugo/hemisc.cpp b/engines/glk/hugo/hemisc.cpp
index 81b2ba5dd1a..354d9296568 100644
--- a/engines/glk/hugo/hemisc.cpp
+++ b/engines/glk/hugo/hemisc.cpp
@@ -557,7 +557,7 @@ ContextCommandLoop:
 		strncpy(context_command[context_commands], cc = GetWord(n), 64);
 		context_command[context_commands][63] = '\0';
 		if (strlen(cc)>=64)
-			sprintf(context_command[context_commands]+60, "...");
+			Common::sprintf_s(context_command[context_commands]+60, 4, "...");
 		context_commands++;
 	}
 #endif
@@ -614,7 +614,7 @@ unsigned int Hugo::Dict() {
 	if ((long)(pos+strlen(line)) > (long)(codeend-dicttable*16L))
 	{
 #ifdef DEBUGGER
-		sprintf(debug_line, "$MAXDICTEXTEND dictionary space exceeded");
+		Common::sprintf_s(debug_line, "$MAXDICTEXTEND dictionary space exceeded");
 		RuntimeWarning(debug_line);
 #endif
 		defseg = gameseg;
@@ -650,39 +650,39 @@ void Hugo::FatalError(int n) {
 	switch (n)
 	{
 		case MEMORY_E:
-			{sprintf(line, "Out of memory\n");
+			{Common::sprintf_s(line, "Out of memory\n");
 			break;}
 
 		case OPEN_E:
-			{sprintf(line, "Cannot open file\n");
+			{Common::sprintf_s(line, "Cannot open file\n");
 			break;}
 
 		case READ_E:
-			{sprintf(line, "Cannot read from file\n");
+			{Common::sprintf_s(line, "Cannot read from file\n");
 			break;}
 
 		case WRITE_E:
-			{sprintf(line, "Cannot write to save file\n");
+			{Common::sprintf_s(line, "Cannot write to save file\n");
 			break;}
 
 		case EXPECT_VAL_E:
-			{sprintf(line, "Expecting value at $%s\n", PrintHex(codeptr));
+			{Common::sprintf_s(line, "Expecting value at $%s\n", PrintHex(codeptr));
 			break;}
 
 		case UNKNOWN_OP_E:
-			{sprintf(line, "Unknown operation at $%s\n", PrintHex(codeptr));
+			{Common::sprintf_s(line, "Unknown operation at $%s\n", PrintHex(codeptr));
 			break;}
 
 		case ILLEGAL_OP_E:
-			{sprintf(line, "Illegal operation at $%s\n", PrintHex(codeptr));
+			{Common::sprintf_s(line, "Illegal operation at $%s\n", PrintHex(codeptr));
 			break;}
 
 		case OVERFLOW_E:
-			{sprintf(line, "Overflow at $%s\n", PrintHex(codeptr));
+			{Common::sprintf_s(line, "Overflow at $%s\n", PrintHex(codeptr));
 			break;}
 
 		case DIVIDE_E:
-			{sprintf(line, "Divide by zero at $%s\n", PrintHex(codeptr));
+			{Common::sprintf_s(line, "Divide by zero at $%s\n", PrintHex(codeptr));
 			break;}
 	}
 
@@ -1023,7 +1023,7 @@ void Hugo::HandleTailRecursion(long addr) {
 	call[window[VIEW_CALLS].count-1].addr = currentroutine;
 	call[window[VIEW_CALLS].count-1].param = true;
 
-	sprintf(debug_line, "Calling:  %s", RoutineName(currentroutine));
+	Common::sprintf_s(debug_line, "Calling:  %s", RoutineName(currentroutine));
 	/* Don't duplicate blank separator line in code window */
 	if (codeline[window[CODE_WINDOW].count-1][0] != 0)
 		AddStringtoCodeWindow("");
@@ -1149,9 +1149,11 @@ void Hugo::LoadGame() {
 		hugo_cleanup_screen();
 		hugo_clearfullscreen();
 #endif
-		sprintf(line, "Hugo Compiler v%d.%d or later required.\n", HEVERSION, HEREVISION);
-		if (game_version>0)
-			sprintf(line+strlen(line), "File \"%s\" is v%d.%d.\n", gamefile, game_version/10, game_version%10);
+		Common::sprintf_s(line, "Hugo Compiler v%d.%d or later required.\n", HEVERSION, HEREVISION);
+		if (game_version>0) {
+			size_t ln = strlen(line);
+			Common::sprintf_s(line+ln, sizeof(line)-ln, "File \"%s\" is v%d.%d.\n", gamefile, game_version/10, game_version%10);
+		}
 
 #if defined (DEBUGGER_PRINTFATALERROR)
 		DEBUGGER_PRINTFATALERROR(line);
@@ -1170,7 +1172,7 @@ void Hugo::LoadGame() {
 		hugo_cleanup_screen();
 		hugo_clearfullscreen();
 #endif
-		sprintf(line, "File \"%s\" is incorrect or unknown version.\n", gamefile);
+		Common::sprintf_s(line, "File \"%s\" is incorrect or unknown version.\n", gamefile);
 
 #if defined (DEBUGGER_PRINTFATALERROR)
 		DEBUGGER_PRINTFATALERROR(line);
@@ -1462,7 +1464,7 @@ const char *Hugo::PrintHex(long a) {
 	if (a < 256L) hex[h++] = '0';
 	if (a < 16L) hex[h++] = '0';
 
-	sprintf(hex+h, "%lX", a);
+	Common::sprintf_s(hex+h, sizeof(hex)-h, "%lX", a);
 
 	return hex;
 }
diff --git a/engines/glk/hugo/heobject.cpp b/engines/glk/hugo/heobject.cpp
index 34ea80215da..ca7fe6b34cb 100644
--- a/engines/glk/hugo/heobject.cpp
+++ b/engines/glk/hugo/heobject.cpp
@@ -385,7 +385,7 @@ GetNextProp:
 							if (IsBreakpoint(orig_inprop))
 								complex_prop_breakpoint = true;
 
-							sprintf(debug_line, "Calling:  %s.%s", objectname[obj], propertyname[p]);
+							Common::sprintf_s(debug_line, "Calling:  %s.%s", objectname[obj], propertyname[p]);
 							trace_complex_prop_routine = true;
 
 							tempdbnest = dbnest;
diff --git a/engines/glk/hugo/heparse.cpp b/engines/glk/hugo/heparse.cpp
index b15d1f49f6a..fb8ca70219c 100644
--- a/engines/glk/hugo/heparse.cpp
+++ b/engines/glk/hugo/heparse.cpp
@@ -96,7 +96,7 @@ void Hugo::AddPossibleObject(int obj, char type, unsigned int w) {
 #ifdef DEBUG_PARSER
 {
 	char buf[100];
-	sprintf(buf, "AddPossibleObject(%d:\"%s\")", obj, Name(obj));
+	Common::sprintf_s(buf, "AddPossibleObject(%d:\"%s\")", obj, Name(obj));
 	Printout(buf);
 }
 #endif
@@ -1302,7 +1302,7 @@ Clarify:
 					if (strcmp(Name(i), ""))
 					{
 						pobj = i;
-						sprintf(line, "(%s)", Name(i));
+						Common::sprintf_s(line, "(%s)", Name(i));
 						AP(line);
 						goto RestoreTempArrays;
 					}
@@ -1656,7 +1656,7 @@ CheckWord:
 		/* a number */
 		case NUMBER_T:
 			if ((STARTS_AS_NUMBER(word[*wordnum])) &&
-				!strcmp(itoa(atoi(word[*wordnum]), num, 10), word[*wordnum]))
+				!strcmp(itoa(atoi(word[*wordnum]), num, 10, sizeof(num)), word[*wordnum]))
 			{
 				if (obj_match_state==1)
 					var[xobject] = atoi(word[*wordnum]);
@@ -1739,7 +1739,7 @@ CheckWordorString:
 
 					/* or a number */
 					else if ((p==NUMBER_T && STARTS_AS_NUMBER(word[*wordnum])) &&
-						!strcmp(word[*wordnum], itoa(atoi(word[*wordnum]), num, 10)))
+						!strcmp(word[*wordnum], itoa(atoi(word[*wordnum]), num, 10, sizeof(num))))
 					{
 						grammaraddr = nextsyntax;
 						if (*wordnum != objstart)
@@ -1852,7 +1852,7 @@ CheckXobjectFinish:
 							goto CheckXobjectFinish;
 						}
 						else if ((p==NUMBER_T && STARTS_AS_NUMBER(word[*wordnum])) &&
-							!strcmp(word[*wordnum], itoa(atoi(word[*wordnum]), num, 10)))
+							!strcmp(word[*wordnum], itoa(atoi(word[*wordnum]), num, 10, sizeof(num))))
 						{
 							objfinish = i;
 							break;
@@ -1984,7 +1984,7 @@ int Hugo::Parse() {
 			wd[i] = FindWord(word[i]);
 
 			/* Numbers -32768 to 32767 are valid...*/
-			if (!strcmp(word[i], itoa(atoi(word[i]), num, 10)))
+			if (!strcmp(word[i], itoa(atoi(word[i]), num, 10, sizeof(num))))
 			{
 #if !defined (MATH_16BIT)
 				if (atoi(word[i]) > 32767 || atoi(word[i]) < -32768)
@@ -2169,7 +2169,7 @@ void Hugo::ParseError(int e, int a) {
 			break;
 
 		case 1:
-			sprintf(line, "You can't use the word \"%s\".", parseerr);
+			Common::sprintf_s(line, "You can't use the word \"%s\".", parseerr);
 			AP(line);
 			break;
 
@@ -2178,7 +2178,7 @@ void Hugo::ParseError(int e, int a) {
 			break;
 
 		case 3:
-			sprintf(line, "You can't %s multiple objects.", parseerr);
+			Common::sprintf_s(line, "You can't %s multiple objects.", parseerr);
 			AP(line);
 			break;
 
@@ -2187,7 +2187,7 @@ void Hugo::ParseError(int e, int a) {
 			break;
 
 		case 5:
-			sprintf(line, "You haven't seen any \"%s\", nor are you likely to in the near future even if such a thing exists.", parseerr);
+			Common::sprintf_s(line, "You haven't seen any \"%s\", nor are you likely to in the near future even if such a thing exists.", parseerr);
 			AP(line);
 			break;
 
@@ -2201,7 +2201,7 @@ void Hugo::ParseError(int e, int a) {
 
 		case 8:
 		{
-			sprintf(line, "Which %s do you mean, ", !parse_called_twice?parseerr:"exactly");
+			Common::sprintf_s(line, "Which %s do you mean, ", !parse_called_twice?parseerr:"exactly");
 			count = 1;
 			for (k=0; k<pobjcount; k++)
 			{
@@ -2227,7 +2227,7 @@ void Hugo::ParseError(int e, int a) {
 						if (!strcmp(w, "a") || !strcmp(w, "an"))
 							Common::strcat_s(line, "the ");
 						else
-							sprintf(line+strlen(line), "%s ", w);
+							Common::sprintf_s(line+strlen(line), "%s ", w);
 						*/
 						/* We'll just use "the" */
 						if (w) Common::strcat_s(line, "the ");
@@ -2242,7 +2242,7 @@ void Hugo::ParseError(int e, int a) {
 		}
 
 		case 9:
-			sprintf(line, "Nothing to %s.", parseerr);
+			Common::sprintf_s(line, "Nothing to %s.", parseerr);
 			AP(line);
 			break;
 
@@ -2255,7 +2255,7 @@ void Hugo::ParseError(int e, int a) {
 			break;
 
 		case 12:
-			sprintf(line, "You can't do that with the %s.", Name(a));
+			Common::sprintf_s(line, "You can't do that with the %s.", Name(a));
 			AP(line);
 			break;
 
@@ -2415,10 +2415,12 @@ void Hugo::SeparateWords() {
 			   as the modified word, storing the original hh:mm
 			   in parse$:
 			*/
-			if (!strcmp(w1, itoa((int)n1, temp, 10)) && !strcmp(w2, itoa((int)n2, temp, 10)) && (n1 > 0 && n1 < 25) && (n2 >= 0 && n2 < 60))
+			if (!strcmp(w1, itoa((int)n1, temp, 10, sizeof(temp))) &&
+				!strcmp(w2, itoa((int)n2, temp, 10, sizeof(temp))) &&
+				(n1 > 0 && n1 < 25) && (n2 >= 0 && n2 < 60))
 			{
 				Common::strcpy_s(parseerr, word[i]);
-				itoa(n1 * 60 + n2, word[i], 10);
+				itoa(n1 * 60 + n2, word[i], 10, strlen(word[i]) + 1);
 			}
 		}
 	}
@@ -2457,7 +2459,7 @@ void Hugo::SubtractPossibleObject(int obj) {
 #ifdef DEBUG_PARSER
 {
 	char buf[100];
-	sprintf(buf, "SubtractPossibleObject(%d:\"%s\")", obj, Name(obj));
+	Common::sprintf_s(buf, "SubtractPossibleObject(%d:\"%s\")", obj, Name(obj));
 	Printout(buf);
 }
 #endif
diff --git a/engines/glk/hugo/heres.cpp b/engines/glk/hugo/heres.cpp
index db8a0a75ce4..5a046a0d69e 100644
--- a/engines/glk/hugo/heres.cpp
+++ b/engines/glk/hugo/heres.cpp
@@ -355,7 +355,7 @@ ResfileError:
 
 #if defined (DEBUGGER)
 	SwitchtoDebugger();
-	sprintf(debug_line, "Unable to find \"%s\" in \"%s\"", resname, filename);
+	Common::sprintf_s(debug_line, "Unable to find \"%s\" in \"%s\"", resname, filename);
 	DebugMessageBox("Resource Error", debug_line);
 	SwitchtoGame();
 #endif
diff --git a/engines/glk/hugo/herun.cpp b/engines/glk/hugo/herun.cpp
index 8815d40352b..79861bd7ea5 100644
--- a/engines/glk/hugo/herun.cpp
+++ b/engines/glk/hugo/herun.cpp
@@ -304,7 +304,7 @@ FreshInput:
 */
 								while (buffer[strlen(buffer)-1]==0x0d || buffer[strlen(buffer)-1]==0x0a)
 									buffer[strlen(buffer)-1] = '\0';
-								sprintf(line, "\n%s%s", GetWord(var[prompt]), buffer);
+								Common::sprintf_s(line, "\n%s%s", GetWord(var[prompt]), buffer);
 								if (script)
 									/* fprintf() this way for Glk */
 									script->putBuffer("\n", 1);
@@ -559,7 +559,7 @@ NextPerform:
 								*/
 								if (objcount > 1)
 								{
-									sprintf(line, "%s:  \\;", Name(var[object]));
+									Common::sprintf_s(line, "%s:  \\;", Name(var[object]));
 									AP(line);
 								}
 
@@ -1045,11 +1045,11 @@ void Hugo::RunPrint() {
 							itoa((unsigned int)a, line, 10);
 						else
 #endif
-							itoa(a, line, 10);
+							itoa(a, line, 10, sizeof(line));
 						capital = 0;
 					}
 					else
-						sprintf(line, "%X", a);
+						Common::sprintf_s(line, "%X", a);
 
 					number = 0;
 					hexnumber = 0;
@@ -1256,7 +1256,7 @@ void Hugo::RunRoutine(long addr) {
 	{
 		if (codeptr != addr)
 		{
-			sprintf(line, "[ROUTINE:  $%6s]", PrintHex(addr));
+			Common::sprintf_s(line, "[ROUTINE:  $%6s]", PrintHex(addr));
 			AP(line);
 			wascalled = 1;
 		}
@@ -1306,7 +1306,7 @@ void Hugo::RunRoutine(long addr) {
 			   already holds the calling information
 			*/
 			if (!trace_complex_prop_routine)
-				sprintf(debug_line, "Calling:  %s", RoutineName(currentroutine));
+				Common::sprintf_s(debug_line, "Calling:  %s", RoutineName(currentroutine));
 			else
 				trace_comp_prop = true;
 			trace_complex_prop_routine = false;
@@ -1332,7 +1332,7 @@ void Hugo::RunRoutine(long addr) {
 				Common::strcat_s(debug_line, "(");
 				for (i=0; i<arguments_passed; i++)
 				{
-					sprintf(debug_line+strlen(debug_line), "%d", var[MAXGLOBALS+i]);
+					Common::sprintf_s(debug_line+strlen(debug_line), "%d", var[MAXGLOBALS+i]);
 					if (i<arguments_passed-1)
 						Common::strcat_s(debug_line, ", ");
 				}
@@ -1390,7 +1390,7 @@ ContinueRunning:
 #if defined (DEBUG_CODE)
 		if (!inwindow)
 		{
-			sprintf(line, "[%6s:  %s]", PrintHex(codeptr), token[t]);
+			Common::sprintf_s(line, "[%6s:  %s]", PrintHex(codeptr), token[t]);
 			AP(line);
 		}
 #endif
@@ -1400,7 +1400,7 @@ ContinueRunning:
 #if defined (DEBUGGER)
 		if (++runaway_counter>=65535 && runtime_warnings)
 		{
-			sprintf(debug_line, "Possible runaway loop (65535 unchecked steps)");
+			Common::sprintf_s(debug_line, "Possible runaway loop (65535 unchecked steps)");
 			RuntimeWarning(debug_line);
 			buffered_code_lines = FORCE_REDRAW;
 			runaway_counter = 0;
@@ -1485,7 +1485,7 @@ ContinueRunning:
 		   reason, the line array was altered (see above)
 		*/
 		if (!trace_complex_prop_routine)
-			sprintf(debug_line, "Calling:  %s", RoutineName(currentroutine));
+			Common::sprintf_s(debug_line, "Calling:  %s", RoutineName(currentroutine));
 		trace_complex_prop_routine = false;
 
 
@@ -1633,8 +1633,8 @@ ProcessToken:
 Printcharloop:
 				codeptr++;
 				i = GetValue();
-				if (capital) sprintf(line, "%c\\;", toupper(i));
-				else sprintf(line, "%c\\;", i);
+				if (capital) Common::sprintf_s(line, "%c\\;", toupper(i));
+				else Common::sprintf_s(line, "%c\\;", i);
 				capital = 0;
 				AP(line);
 				if (Peek(codeptr)==COMMA_T)
@@ -2090,19 +2090,19 @@ LeaveRunRoutine:
 		else if (!debugger_step_over)
 		{
 ReturnfromRoutine:
-			sprintf(debug_line, "(Returning %d", ret);
+			Common::sprintf_s(debug_line, "(Returning %d", ret);
 
 			/* Since a complex property routine will give "<Routine>" as the
 			   routine name, skip those
 			*/
 			called_from = RoutineName(currentroutine);
 			if (!trace_comp_prop && called_from[0]!='<')
-				sprintf(debug_line+strlen(debug_line), " from %s", called_from);
+				Common::sprintf_s(debug_line+strlen(debug_line), " from %s", called_from);
 
 			if (old_currentroutine!=mainaddr && old_currentroutine!=initaddr
 				&& currentroutine!=mainaddr && currentroutine!=initaddr)
 			{
-				sprintf(debug_line+strlen(debug_line), " to %s", RoutineName(old_currentroutine));
+				Common::sprintf_s(debug_line+strlen(debug_line), " to %s", RoutineName(old_currentroutine));
 			}
 			Common::strcat_s(debug_line, ")");
 			AddStringtoCodeWindow(debug_line);
@@ -2349,7 +2349,7 @@ int Hugo::RunSystem() {
 #ifndef NO_STRFTIME
 			TimeDate td;
 			g_system->getTimeAndDate(td);
-			sprintf(parseerr, "%d-%.2d-%.2d %d:%.2d:%.2d", td.tm_year, td.tm_mon, td.tm_mday,
+			Common::sprintf_s(parseerr, "%d-%.2d-%.2d %d:%.2d:%.2d", td.tm_year, td.tm_mon, td.tm_mday,
 				td.tm_hour, td.tm_min, td.tm_sec);
 #else
 			hugo_gettimeformatted(parseerr);
diff --git a/engines/glk/hugo/heset.cpp b/engines/glk/hugo/heset.cpp
index eda485c5be9..75a9794e597 100644
--- a/engines/glk/hugo/heset.cpp
+++ b/engines/glk/hugo/heset.cpp
@@ -144,7 +144,7 @@ GetNextWord:
 				if ((unsigned short)wd[a]!=UNKNOWN_WORD)
 					Common::strcpy_s(buffer+t, sizeof(buffer) - t, GetWord(wd[a]));
 				else
-					itoa(parsed_number, buffer+t, 10);
+					itoa(parsed_number, buffer+t, 10, sizeof(buffer) - t);
 			        word[a] = buffer + t;
 				t+=strlen(word[a])+1;
 			}
diff --git a/engines/glk/hugo/hugo.h b/engines/glk/hugo/hugo.h
index 91977a0a575..9648899d0bc 100644
--- a/engines/glk/hugo/hugo.h
+++ b/engines/glk/hugo/hugo.h
@@ -1122,9 +1122,9 @@ private:
 		return _random.getRandomNumber(0xffffff);
 	}
 
-	char *itoa(int value, char *str, int base) {
+	char *itoa(int value, char *str, int base, size_t str_size) {
 		assert(base == 10);
-		sprintf(str, "%d", value);
+		Common::sprintf_s(str, str_size, "%d", value);
 		return str;
 	}
 
diff --git a/engines/glk/jacl/errors.cpp b/engines/glk/jacl/errors.cpp
index 3901529a377..da1695f523b 100644
--- a/engines/glk/jacl/errors.cpp
+++ b/engines/glk/jacl/errors.cpp
@@ -33,127 +33,127 @@ extern const char               *word[];
 extern char                     error_buffer[];
 
 void badparrun() {
-	sprintf(error_buffer, BAD_PARENT, executing_function->name);
+	Common::sprintf_s(error_buffer, 1024, BAD_PARENT, executing_function->name);
 
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void notintrun() {
-	sprintf(error_buffer, NOT_INTEGER, executing_function->name, word[0]);
+	Common::sprintf_s(error_buffer, 1024, NOT_INTEGER, executing_function->name, word[0]);
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void unkfunrun(const char *name) {
-	sprintf(error_buffer, UNKNOWN_FUNCTION_RUN, name);
+	Common::sprintf_s(error_buffer, 1024, UNKNOWN_FUNCTION_RUN, name);
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void unkkeyerr(int line, int wordno) {
-	sprintf(error_buffer, UNKNOWN_KEYWORD_ERR, line, word[wordno]);
+	Common::sprintf_s(error_buffer, 1024, UNKNOWN_KEYWORD_ERR, line, word[wordno]);
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void unkatterr(int line, int wordno) {
-	sprintf(error_buffer, UNKNOWN_ATTRIBUTE_ERR, line,
+	Common::sprintf_s(error_buffer, 1024, UNKNOWN_ATTRIBUTE_ERR, line,
 	        word[wordno]);
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void unkvalerr(int line, int wordno) {
-	sprintf(error_buffer, UNKNOWN_VALUE_ERR, line,
+	Common::sprintf_s(error_buffer, 1024, UNKNOWN_VALUE_ERR, line,
 	        word[wordno]);
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void noproprun(int) {
-	sprintf(error_buffer, INSUFFICIENT_PARAMETERS_RUN, executing_function->name, word[0]);
+	Common::sprintf_s(error_buffer, 1024, INSUFFICIENT_PARAMETERS_RUN, executing_function->name, word[0]);
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void noobjerr(int line) {
-	sprintf(error_buffer, NO_OBJECT_ERR,
+	Common::sprintf_s(error_buffer, 1024, NO_OBJECT_ERR,
 	        line, word[0]);
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void noproperr(int line) {
-	sprintf(error_buffer, INSUFFICIENT_PARAMETERS_ERR,
+	Common::sprintf_s(error_buffer, 1024, INSUFFICIENT_PARAMETERS_ERR,
 	        line, word[0]);
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void nongloberr(int line) {
-	sprintf(error_buffer, NON_GLOBAL_FIRST, line);
+	Common::sprintf_s(error_buffer, 1024, NON_GLOBAL_FIRST, line);
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void nofnamerr(int line) {
-	sprintf(error_buffer, NO_NAME_FUNCTION, line);
+	Common::sprintf_s(error_buffer, 1024, NO_NAME_FUNCTION, line);
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void unkobjerr(int line, int wordno) {
-	sprintf(error_buffer, UNDEFINED_ITEM_ERR, line, word[wordno]);
+	Common::sprintf_s(error_buffer, 1024, UNDEFINED_ITEM_ERR, line, word[wordno]);
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void maxatterr(int line, int wordno) {
-	sprintf(error_buffer,
+	Common::sprintf_s(error_buffer, 1024,
 	        MAXIMUM_ATTRIBUTES_ERR, line, word[wordno]);
 	log_error(error_buffer, PLUS_STDERR);
 }
 
 void unkobjrun(int wordno) {
-	sprintf(error_buffer, UNDEFINED_ITEM_RUN, executing_function->name, word[wordno]);
+	Common::sprintf_s(error_buffer, 1024, UNDEFINED_ITEM_RUN, executing_function->name, word[wordno]);
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void unkattrun(int wordno) {
-	sprintf(error_buffer, UNKNOWN_ATTRIBUTE_RUN, executing_function->name, word[wordno]);
+	Common::sprintf_s(error_buffer, 1024, UNKNOWN_ATTRIBUTE_RUN, executing_function->name, word[wordno]);
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void unkdirrun(int wordno) {
-	sprintf(error_buffer, UNDEFINED_DIRECTION_RUN,
+	Common::sprintf_s(error_buffer, 1024, UNDEFINED_DIRECTION_RUN,
 	        executing_function->name, word[wordno]);
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void badparun() {
-	sprintf(error_buffer, BAD_PARENT, executing_function->name);
+	Common::sprintf_s(error_buffer, 1024, BAD_PARENT, executing_function->name);
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void badplrrun(int value) {
-	sprintf(error_buffer, BAD_PLAYER, executing_function->name, value);
+	Common::sprintf_s(error_buffer, 1024, BAD_PLAYER, executing_function->name, value);
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void badptrrun(const char *name, int value) {
-	sprintf(error_buffer, BAD_POINTER, executing_function->name, name, value);
+	Common::sprintf_s(error_buffer, 1024, BAD_POINTER, executing_function->name, name, value);
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void unkvarrun(const char *variable) {
-	sprintf(error_buffer, UNDEFINED_CONTAINER_RUN, executing_function->name, arg_text_of(variable));
+	Common::sprintf_s(error_buffer, 1024, UNDEFINED_CONTAINER_RUN, executing_function->name, arg_text_of(variable));
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void unkstrrun(const char *variable) {
-	sprintf(error_buffer, UNDEFINED_STRING_RUN, executing_function->name, variable);
+	Common::sprintf_s(error_buffer, 1024, UNDEFINED_STRING_RUN, executing_function->name, variable);
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void unkscorun(const char *scope) {
-	sprintf(error_buffer, UNKNOWN_SCOPE_RUN, executing_function->name, scope);
+	Common::sprintf_s(error_buffer, 1024, UNKNOWN_SCOPE_RUN, executing_function->name, scope);
 	log_error(error_buffer, PLUS_STDOUT);
 }
 
 void totalerrs(int errors) {
 	if (errors == 1)
-		sprintf(error_buffer, ERROR_DETECTED);
+		Common::sprintf_s(error_buffer, 1024, ERROR_DETECTED);
 	else {
-		sprintf(error_buffer, ERRORS_DETECTED, errors);
+		Common::sprintf_s(error_buffer, 1024, ERRORS_DETECTED, errors);
 	}
 
 	log_error(error_buffer, PLUS_STDERR);
diff --git a/engines/glk/jacl/glk_saver.cpp b/engines/glk/jacl/glk_saver.cpp
index 378b1b36c0f..b81b0808a3d 100644
--- a/engines/glk/jacl/glk_saver.cpp
+++ b/engines/glk/jacl/glk_saver.cpp
@@ -98,7 +98,7 @@ bool save_game(strid_t save) {
 
 	// Save the current volume of each of the sound channels
 	for (index = 0; index < 8; index++) {
-		sprintf(temp_buffer, "volume[%d]", index);
+		Common::sprintf_s(temp_buffer, 1024, "volume[%d]", index);
 		write_integer(save, cinteger_resolve(temp_buffer)->value);
 	}
 
@@ -168,7 +168,7 @@ bool restore_game(strid_t save, bool warn) {
 
 	// Restore the current volume of each of the sound channels
 	for (index = 0; index < 8; index++) {
-		sprintf(temp_buffer, "volume[%d]", index);
+		Common::sprintf_s(temp_buffer, 1024, "volume[%d]", index);
 		counter = read_integer(save);
 		cinteger_resolve(temp_buffer)->value = counter;
 
diff --git a/engines/glk/jacl/interpreter.cpp b/engines/glk/jacl/interpreter.cpp
index 93e5c95ad1f..47dba1460d9 100644
--- a/engines/glk/jacl/interpreter.cpp
+++ b/engines/glk/jacl/interpreter.cpp
@@ -325,7 +325,7 @@ void cb1(void *s, size_t i, void *not_used) {
 	//sprintf (temp_buffer, "Trying to set field %d to equal %s^", field_no, (const char *) s);
 	//write_text(temp_buffer);
 
-	sprintf(temp_buffer, "field[%d]", field_no);
+	Common::sprintf_s(temp_buffer, 1024, "field[%d]", field_no);
 
 	if ((resolved_cstring = cstring_resolve(temp_buffer)) != nullptr) {
 		//write_text("Resolved ");
@@ -440,7 +440,7 @@ int execute(const char *funcname) {
 				// THIS ENDWHILE COMMAND WAS BEING EXECUTED,
 				// NOT JUST COUNTED.
 				if (top_of_while == FALSE) {
-					sprintf(error_buffer, NO_WHILE, executing_function->name);
+					Common::sprintf_s(error_buffer, 1024, NO_WHILE, executing_function->name);
 					log_error(error_buffer, PLUS_STDOUT);
 				} else {
 #ifdef GLK
@@ -457,7 +457,7 @@ int execute(const char *funcname) {
 				// THIS ENDITERATE COMMAND WAS BEING EXECUTED,
 				// NOT JUST COUNTED.
 				if (top_of_iterate == FALSE) {
-					sprintf(error_buffer, NO_ITERATE, executing_function->name);
+					Common::sprintf_s(error_buffer, 1024, NO_ITERATE, executing_function->name);
 					log_error(error_buffer, PLUS_STDOUT);
 				} else {
 #ifdef GLK
@@ -474,7 +474,7 @@ int execute(const char *funcname) {
 				// THIS ENDUPDATE COMMAND WAS BEING EXECUTED,
 				// NOT JUST COUNTED.
 				if (top_of_update == FALSE) {
-					sprintf(error_buffer, NO_UPDATE, executing_function->name);
+					Common::sprintf_s(error_buffer, 1024, NO_UPDATE, executing_function->name);
 					log_error(error_buffer, PLUS_STDOUT);
 				} else {
 #ifdef GLK
@@ -545,7 +545,7 @@ int execute(const char *funcname) {
 					return (exit_function(TRUE));
 				} else {
 					if (top_of_do_loop == FALSE) {
-						sprintf(error_buffer, NO_REPEAT, executing_function->name);
+						Common::sprintf_s(error_buffer, 1024, NO_REPEAT, executing_function->name);
 						log_error(error_buffer, PLUS_STDOUT);
 					} else if (!condition()) {
 #ifdef GLK
@@ -562,7 +562,7 @@ int execute(const char *funcname) {
 					return (exit_function(TRUE));
 				} else {
 					if (top_of_do_loop == FALSE) {
-						sprintf(error_buffer, NO_REPEAT, executing_function->name);
+						Common::sprintf_s(error_buffer, 1024, NO_REPEAT, executing_function->name);
 						log_error(error_buffer, PLUS_STDOUT);
 					} else if (!and_condition()) {
 #ifdef GLK
@@ -603,7 +603,7 @@ int execute(const char *funcname) {
 				}
 
 				if (infile == nullptr) {
-					sprintf(error_buffer, "Failed to open file %s\n", temp_buffer);
+					Common::sprintf_s(error_buffer, 1024, "Failed to open file %s\n", temp_buffer);
 					log_error(error_buffer, LOG_ONLY);
 					infile = nullptr;
 				} else {
@@ -621,7 +621,7 @@ int execute(const char *funcname) {
 							//sprintf (temp_buffer, "Read ~%s~ with %d bytes.^", csv_buffer, i);
 							//write_text(temp_buffer);
 							if (csv_parse(&parser_csv, csv_buffer, i, cb1, cb2, (void *) nullptr) != (uint)i) {
-								sprintf(error_buffer, "Error parsing file: %s\n", csv_strerror(csv_error(&parser_csv)));
+								Common::sprintf_s(error_buffer, 1024, "Error parsing file: %s\n", csv_strerror(csv_error(&parser_csv)));
 								log_error(error_buffer, PLUS_STDOUT);
 								delete infile;
 								infile = nullptr;
@@ -685,7 +685,7 @@ int execute(const char *funcname) {
 				}
 
 				if (infile == nullptr) {
-					sprintf(error_buffer, "Failed to open input CSV file ~%s\n", in_name);
+					Common::sprintf_s(error_buffer, 1024, "Failed to open input CSV file ~%s\n", in_name);
 					log_error(error_buffer, LOG_ONLY);
 					if (outfile != nullptr) {
 						delete outfile;
@@ -694,7 +694,7 @@ int execute(const char *funcname) {
 					return (exit_function(TRUE));
 				} else {
 					if (outfile == nullptr) {
-						sprintf(error_buffer, "Failed to open output CSV file ~%s~\n", out_name);
+						Common::sprintf_s(error_buffer, 1024, "Failed to open output CSV file ~%s~\n", out_name);
 						log_error(error_buffer, LOG_ONLY);
 						if (infile != nullptr) {
 							delete infile;
@@ -714,7 +714,7 @@ int execute(const char *funcname) {
 									jacl_sleep(1000);
 									continue;
 								}
-								sprintf(error_buffer, "File busy unable to get lock on output file.\n");
+								Common::sprintf_s(error_buffer, 1024, "File busy unable to get lock on output file.\n");
 								log_error(error_buffer, PLUS_STDOUT);
 								return (exit_function(TRUE));
 							}
@@ -732,7 +732,7 @@ int execute(const char *funcname) {
 									jacl_sleep(1000);
 									continue;
 								}
-								sprintf(error_buffer, "File busy unable to get lock on input file.\n");
+								Common::sprintf_s(error_buffer, 1024, "File busy unable to get lock on input file.\n");
 								log_error(error_buffer, PLUS_STDOUT);
 								return (exit_function(TRUE));
 							}
@@ -749,7 +749,7 @@ int execute(const char *funcname) {
 							if (infile->pos() < infile->size()) {
 								i = strlen(csv_buffer);
 								if (csv_parse(&parser_csv, csv_buffer, i, cb1, cb2, (int *) &field_no) != (uint)i) {
-									sprintf(error_buffer, "Error parsing file: %s\n", csv_strerror(csv_error(&parser_csv)));
+									Common::sprintf_s(error_buffer, 1024, "Error parsing file: %s\n", csv_strerror(csv_error(&parser_csv)));
 									log_error(error_buffer, PLUS_STDOUT);
 									read_lck.l_type = F_UNLCK;  // SETTING A READ LOCK
 									fcntl(read_fd, F_SETLK, &read_lck);
@@ -826,7 +826,7 @@ int execute(const char *funcname) {
 
 			} else if (!strcmp(word[0], "endloop")) {
 				if (top_of_loop == FALSE) {
-					sprintf(error_buffer, NO_LOOP, executing_function->name);
+					Common::sprintf_s(error_buffer, 1024, NO_LOOP, executing_function->name);
 					log_error(error_buffer, PLUS_STDOUT);
 				} else {
 					*loop_integer += 1;
@@ -936,7 +936,7 @@ int execute(const char *funcname) {
 				}
 			} else if (!strcmp(word[0], "endselect")) {
 				if (top_of_select == FALSE) {
-					sprintf(error_buffer, NO_LOOP, executing_function->name);
+					Common::sprintf_s(error_buffer, 1024, NO_LOOP, executing_function->name);
 					log_error(error_buffer, PLUS_STDOUT);
 				} else {
 					if (select_next(/* select_integer, criterion_type, criterion_value, scope_criterion */)) {
@@ -1017,7 +1017,7 @@ int execute(const char *funcname) {
 
 						/* STORE A COPY OF THE CURRENT VOLUME FOR ACCESS
 						 * FROM JACL CODE */
-						sprintf(temp_buffer, "volume[%d]", channel);
+						Common::sprintf_s(temp_buffer, 1024, "volume[%d]", channel);
 						cinteger_resolve(temp_buffer)->value = volume;
 
 						/* NOW SCALE THE 0-100 VOLUME TO THE 0-65536 EXPECTED
@@ -1081,7 +1081,7 @@ int execute(const char *funcname) {
 							 * NOTIFICATION EVENT CAN USE THE INFORMATION
 							 * IT HAS 1 ADDED TO IT SO THAT IT IS A NON-ZERO
 							 * NUMBER AND THE EVENT IS ACTIVATED */
-							sprintf(error_buffer, "Unable to play sound: %ld", value_of(word[1], FALSE));
+							Common::sprintf_s(error_buffer, 1024, "Unable to play sound: %ld", value_of(word[1], FALSE));
 							log_error(error_buffer, PLUS_STDERR);
 						}
 					}
@@ -1094,7 +1094,7 @@ int execute(const char *funcname) {
 						return (exit_function(TRUE));
 					} else {
 						if (!g_vm->loadingSavegame() && g_vm->glk_image_draw(mainwin, (glui32) value_of(word[1], TRUE), imagealign_InlineDown, 0) == 0) {
-							sprintf(error_buffer, "Unable to draw image: %ld", value_of(word[1], FALSE));
+							Common::sprintf_s(error_buffer, 1024, "Unable to draw image: %ld", value_of(word[1], FALSE));
 							log_error(error_buffer, PLUS_STDERR);
 						}
 					}
@@ -1368,11 +1368,11 @@ int execute(const char *funcname) {
 				} else {
 					index = value_of(word[1]);
 					if (word[2] != NULL) {
-						sprintf(option_buffer, "<option value=\"%d\">",
+						Common::sprintf_s(option_buffer, "<option value=\"%d\">",
 						        index);
 					} else {
 						object_names(index, temp_buffer);
-						sprintf(option_buffer, "<option value=\"%s\">", temp_buffer);
+						Common::sprintf_s(option_buffer, "<option value=\"%s\">", temp_buffer);
 					}
 
 					write_text(option_buffer);
@@ -1409,16 +1409,16 @@ int execute(const char *funcname) {
 					return (TRUE);
 				}
 				if (word[2] != NULL) {
-					sprintf(option_buffer, "<input class=~button~ type=~image~ src=~%s~ name=~verb~ value=~", text_of_word(2));
+					Common::sprintf_s(option_buffer, "<input class=~button~ type=~image~ src=~%s~ name=~verb~ value=~", text_of_word(2));
 					strcat(option_buffer, text_of_word(1));
 					strcat(option_buffer, "~>");
 					write_text(option_buffer);
 				} else {
-					sprintf(option_buffer, "<input class=~button~ type=~submit~ style=~width: 90px; margin: 5px;~ name=~verb~ value=~%s~>", text_of_word(1));
+					Common::sprintf_s(option_buffer, "<input class=~button~ type=~submit~ style=~width: 90px; margin: 5px;~ name=~verb~ value=~%s~>", text_of_word(1));
 					write_text(option_buffer);
 				}
 			} else if (!strcmp(word[0], "hidden")) {
-				sprintf(temp_buffer, "<INPUT TYPE=\"hidden\" NAME=\"user_id\" VALUE=\"%s\">", user_id);
+				Common::sprintf_s(temp_buffer, 1024, "<INPUT TYPE=\"hidden\" NAME=\"user_id\" VALUE=\"%s\">", user_id);
 				write_text(temp_buffer);
 			} else if (!strcmp(word[0], "control")) {
 				/* USED TO CREATE A HYPERLINK THAT IS AN IMAGE */
@@ -1427,7 +1427,7 @@ int execute(const char *funcname) {
 					pop_stack();
 					return (TRUE);
 				} else {
-					sprintf(option_buffer, "<a href=\"?command=%s&user_id=%s\"><img border=0 SRC=\"", text_of_word(2), user_id);
+					Common::sprintf_s(option_buffer, "<a href=\"?command=%s&user_id=%s\"><img border=0 SRC=\"", text_of_word(2), user_id);
 					strcat(option_buffer, text_of_word(1));
 					strcat(option_buffer, "\"></a>");
 					write_text(option_buffer);
@@ -1450,13 +1450,13 @@ int execute(const char *funcname) {
 					}
 
 					if (word[3] == NULL) {
-						sprintf(string_buffer, "<a href=\"?command=%s&user_id=%s\">", encoded, user_id);
+						Common::sprintf_s(string_buffer, "<a href=\"?command=%s&user_id=%s\">", encoded, user_id);
 						strcat(string_buffer, text_of_word(1));
 						strcat(string_buffer, "</a>");
 					} else {
-						sprintf(string_buffer, "<a class=\"%s\" href=\"?command=", text_of_word(3));
+						Common::sprintf_s(string_buffer, "<a class=\"%s\" href=\"?command=", text_of_word(3));
 						strcat(string_buffer, encoded);
-						sprintf(option_buffer, "&user_id=%s\">%s</a>", user_id, text_of_word(1));
+						Common::sprintf_s(option_buffer, "&user_id=%s\">%s</a>", user_id, text_of_word(1));
 						strcat(string_buffer, option_buffer);
 					}
 
@@ -1469,13 +1469,13 @@ int execute(const char *funcname) {
 			} else if (!strcmp(word[0], "prompt")) {
 				/* USED TO OUTPUT A HTML INPUT CONTROL THAT CONTAINS SESSION INFORMATION */
 				if (word[1] != NULL) {
-					sprintf(temp_buffer, "<input id=\"JACLCommandPrompt\" type=text name=~command~ onKeyPress=~%s~>\n", word[1]);
+					Common::sprintf_s(temp_buffer, 1024, "<input id=\"JACLCommandPrompt\" type=text name=~command~ onKeyPress=~%s~>\n", word[1]);
 					write_text(temp_buffer);
 				} else {
-					sprintf(temp_buffer, "<input id=\"JACLCommandPrompt\" type=text name=~command~>\n");
+					Common::sprintf_s(temp_buffer, 1024, "<input id=\"JACLCommandPrompt\" type=text name=~command~>\n");
 					write_text(temp_buffer);
 				}
-				sprintf(temp_buffer, "<input type=hidden name=\"user_id\" value=\"%s\">", user_id);
+				Common::sprintf_s(temp_buffer, 1024, "<input type=hidden name=\"user_id\" value=\"%s\">", user_id);
 				write_text(temp_buffer);
 			} else if (!strcmp(word[0], "style")) {
 				/* THIS COMMAND IS USED TO OUTPUT ANSI CODES OR SET GLK
@@ -1549,9 +1549,9 @@ int execute(const char *funcname) {
 					return (exit_function(TRUE));
 				} else {
 					if (word[2] == NULL) {
-						sprintf(option_buffer, "<img src=~%s~>", text_of_word(1));
+						Common::sprintf_s(option_buffer, "<img src=~%s~>", text_of_word(1));
 					} else {
-						sprintf(option_buffer, "<img class=~%s~ src=~%s~>", text_of_word(2), text_of_word(1));
+						Common::sprintf_s(option_buffer, "<img class=~%s~ src=~%s~>", text_of_word(2), text_of_word(1));
 					}
 
 					write_text(option_buffer);
@@ -1564,7 +1564,7 @@ int execute(const char *funcname) {
 				} else {
 					write_text("<audio autoplay=~autoplay~>");
 					if (word[3] == NULL) {
-						sprintf(option_buffer, "<source src=~%s~ type=~%s~>", text_of_word(1), text_of_word(2));
+						Common::sprintf_s(option_buffer, "<source src=~%s~ type=~%s~>", text_of_word(1), text_of_word(2));
 						write_text(option_buffer);
 					}
 					write_text("</audio>");
@@ -1641,7 +1641,7 @@ int execute(const char *funcname) {
 						if (argstart != nullptr)
 							*argstart = 0;
 
-						sprintf(error_buffer, UNDEFINED_FUNCTION, executing_function->name, string_buffer);
+						Common::sprintf_s(error_buffer, 1024, UNDEFINED_FUNCTION, executing_function->name, string_buffer);
 						log_error(error_buffer, PLUS_STDOUT);
 					} else {
 						execute(string_buffer);
@@ -1663,7 +1663,7 @@ int execute(const char *funcname) {
 #endif
 #endif
 						write_text(cstring_resolve("SCORE_UP")->value);
-						sprintf(temp_buffer, "%ld", value_of(word[1], TRUE));
+						Common::sprintf_s(temp_buffer, 1024, "%ld", value_of(word[1], TRUE));
 						write_text(temp_buffer);
 						if (value_of(word[1], TRUE) == 1) {
 							write_text(cstring_resolve("POINT")->value);
@@ -1862,7 +1862,7 @@ int execute(const char *funcname) {
 							*match = 0;
 							Common::strcpy_s(container_buffer, var_text_of_word(4));
 							Common::strcat_s(container_buffer, "[");
-							sprintf(integer_buffer, "%d", *split_container);
+							Common::sprintf_s(integer_buffer, "%d", *split_container);
 							Common::strcat_s(container_buffer, integer_buffer);
 							Common::strcat_s(container_buffer, "]");
 
@@ -1877,7 +1877,7 @@ int execute(const char *funcname) {
 						}
 						Common::strcpy_s(container_buffer, var_text_of_word(4));
 						Common::strcat_s(container_buffer, "[");
-						sprintf(integer_buffer, "%d", *split_container);
+						Common::sprintf_s(integer_buffer, "%d", *split_container);
 						Common::strcat_s(container_buffer, integer_buffer);
 						Common::strcat_s(container_buffer, "]");
 
@@ -2112,7 +2112,7 @@ int execute(const char *funcname) {
 								*container = *container % counter;
 							else if (word[mark][0] == '/') {
 								if (counter == 0) {
-									sprintf(error_buffer, DIVIDE_BY_ZERO,
+									Common::sprintf_s(error_buffer, 1024, DIVIDE_BY_ZERO,
 									        executing_function->name);
 									log_error(error_buffer, PLUS_STDOUT);
 								} else
@@ -2124,7 +2124,7 @@ int execute(const char *funcname) {
 							} else if (word[mark][0] == '=') {
 								*container = counter;
 							} else {
-								sprintf(error_buffer, ILLEGAL_OPERATOR,
+								Common::sprintf_s(error_buffer, 1024, ILLEGAL_OPERATOR,
 								        executing_function->name,
 								        word[2]);
 								log_error(error_buffer, PLUS_STDOUT);
@@ -2193,7 +2193,7 @@ int execute(const char *funcname) {
 					outfile = File::openForWriting(temp_buffer);
 
 					if (outfile == nullptr) {
-						sprintf(error_buffer, "Failed to open file %s\n", temp_buffer);
+						Common::sprintf_s(error_buffer, 1024, "Failed to open file %s\n", temp_buffer);
 						log_error(error_buffer, PLUS_STDOUT);
 					} else {
 						for (counter = 2; word[counter] != nullptr && counter < MAX_WORDS; counter++) {
@@ -2336,7 +2336,7 @@ int execute(const char *funcname) {
 					executionLevel++;
 				}
 			} else {
-				sprintf(error_buffer, UNKNOWN_COMMAND,
+				Common::sprintf_s(error_buffer, 1024, UNKNOWN_COMMAND,
 				        executing_function->name, word[0]);
 				log_error(error_buffer, PLUS_STDOUT);
 			}
@@ -3054,7 +3054,7 @@ int logic_test(int first) {
 			}
 		}
 	} else {
-		sprintf(error_buffer,
+		Common::sprintf_s(error_buffer, 1024,
 		        "ERROR: In function \"%s\", illegal operator \"%s\".^",
 		        executing_function->name, word[2]);
 		write_text(error_buffer);
@@ -3142,7 +3142,7 @@ int str_test(int first) {
 		else
 			return (FALSE);
 	} else {
-		sprintf(error_buffer,
+		Common::sprintf_s(error_buffer, 1024,
 		        "ERROR: In function \"%s\", illegal operator \"%s\".^",
 		        executing_function->name, word[2]);
 		write_text(error_buffer);
@@ -3323,12 +3323,12 @@ void inspect(int object_num)  {
 		while (location_elements[index] != nullptr) {
 			if (index < 12) {
 				if (object[object_num]->integer[index] < 1 || object[object_num]->integer[index] > objects) {
-					sprintf(temp_buffer, "%s: nowhere (%d)^", location_elements[index], object[object_num]->integer[index]);
+					Common::sprintf_s(temp_buffer, 1024, "%s: nowhere (%d)^", location_elements[index], object[object_num]->integer[index]);
 				} else {
-					sprintf(temp_buffer, "%s: %s (%d)^", location_elements[index], object[object[object_num]->integer[index]]->label, object[object_num]->integer[index]);
+					Common::sprintf_s(temp_buffer, 1024, "%s: %s (%d)^", location_elements[index], object[object[object_num]->integer[index]]->label, object[object_num]->integer[index]);
 				}
 			} else {
-				sprintf(temp_buffer, "%s: %d^", location_elements[index], object[object_num]->integer[index]);
+				Common::sprintf_s(temp_buffer, 1024, "%s: %d^", location_elements[index], object[object_num]->integer[index]);
 			}
 			write_text(temp_buffer);
 			index++;
@@ -3336,9 +3336,9 @@ void inspect(int object_num)  {
 	} else {
 		while (object_elements[index] != nullptr) {
 			if (index == 0) {
-				sprintf(temp_buffer, "%s: %s (%d)^", object_elements[index], object[object[object_num]->integer[index]]->label, object[object_num]->integer[index]);
+				Common::sprintf_s(temp_buffer, 1024, "%s: %s (%d)^", object_elements[index], object[object[object_num]->integer[index]]->label, object[object_num]->integer[index]);
 			} else {
-				sprintf(temp_buffer, "%s: %d^", object_elements[index], object[object_num]->integer[index]);
+				Common::sprintf_s(temp_buffer, 1024, "%s: %d^", object_elements[index], object[object_num]->integer[index]);
 			}
 			write_text(temp_buffer);
 			index++;
diff --git a/engines/glk/jacl/jacl_main.cpp b/engines/glk/jacl/jacl_main.cpp
index 4f5cfb968ca..9dd20d3d64a 100644
--- a/engines/glk/jacl/jacl_main.cpp
+++ b/engines/glk/jacl/jacl_main.cpp
@@ -239,7 +239,7 @@ void glk_main() {
 	if ((resolved_string = cstring_resolve("game_title")) != NULL) {
 		wing_vm->glk_window_set_title(resolved_string->value);
 	} else {
-		sprintf(temp_buffer, "JACL v%d.%d.%d ", J_VERSION, J_RELEASE, J_BUILD);
+		Common::sprintf_s(temp_buffer, "JACL v%d.%d.%d ", J_VERSION, J_RELEASE, J_BUILD);
 		wing_vm->glk_window_set_title(temp_buffer);
 	}
 #endif
@@ -342,7 +342,7 @@ void glk_main() {
 					/* A SOUND HAS FINISHED PLAYING CALL +sound_finished
 					 * WITH THE RESOUCE NUMBER AS THE FIRST ARGUMENT
 					 * AND THE CHANNEL NUMBER AS THE SECOND ARGUMENT */
-					sprintf(temp_buffer, "+sound_finished<%d<%d", (int) ev.val1, (int) ev.val2 - 1);
+					Common::sprintf_s(temp_buffer, "+sound_finished<%d<%d", (int) ev.val1, (int) ev.val2 - 1);
 					execute(temp_buffer);
 					break;
 
@@ -607,7 +607,7 @@ void word_check() {
 		write_text("Public License along with this program; if not, write ");
 		write_text("to the Free Software Foundation, Inc., 675 Mass Ave, ");
 		write_text("Cambridge, MA 02139, USA.^^");
-		sprintf(temp_buffer, "OBJECTS DEFINED:   %d^", objects);
+		Common::sprintf_s(temp_buffer, "OBJECTS DEFINED:   %d^", objects);
 		write_text(temp_buffer);
 		TIME->value = FALSE;
 	} else {
@@ -624,10 +624,10 @@ void word_check() {
 void version_info() {
 	char            buffer[80];
 
-	sprintf(buffer, "JACL Interpreter v%d.%d.%d ", J_VERSION, J_RELEASE,
+	Common::sprintf_s(buffer, "JACL Interpreter v%d.%d.%d ", J_VERSION, J_RELEASE,
 	        J_BUILD);
 	write_text(buffer);
-	sprintf(buffer, "/ %d object.^", MAX_OBJECTS);
+	Common::sprintf_s(buffer, "/ %d object.^", MAX_OBJECTS);
 	write_text(buffer);
 	write_text("Copyright (c) 1992-2010 Stuart Allen.^^");
 }
@@ -802,7 +802,7 @@ void status_line() {
 
 		/* BUILD THE SCORE/ MOVES STRING */
 		temp_buffer[0] = 0;
-		sprintf(temp_buffer, "Score: %d  Moves: %d", SCORE->value, TOTAL_MOVES->value);
+		Common::sprintf_s(temp_buffer, "Score: %d  Moves: %d", SCORE->value, TOTAL_MOVES->value);
 
 		cursor = status_width - strlen(temp_buffer);
 		cursor--;
@@ -868,7 +868,7 @@ int get_number(int insist, int low, int high) {
 
 	status_line();
 
-	sprintf(temp_buffer, cstring_resolve("TYPE_NUMBER")->value, low, high);
+	Common::sprintf_s(temp_buffer, cstring_resolve("TYPE_NUMBER")->value, low, high);
 
 	/* THIS LOOP IS IDENTICAL TO THE MAIN COMMAND LOOP IN g_vm->glk_main(). */
 
diff --git a/engines/glk/jacl/jpp.cpp b/engines/glk/jacl/jpp.cpp
index f05ab9c63bf..58974fb17b0 100644
--- a/engines/glk/jacl/jpp.cpp
+++ b/engines/glk/jacl/jpp.cpp
@@ -82,7 +82,7 @@ int jpp() {
 		char *result = NULL;
 
 		if (inputFile->read(text_buffer, 1024) != 1024) {
-			sprintf(error_buffer, CANT_OPEN_SOURCE, game_file);
+			Common::sprintf_s(error_buffer, 1024, CANT_OPEN_SOURCE, game_file);
 			return (FALSE);
 		}
 
@@ -92,7 +92,7 @@ int jpp() {
 				 * DIRECTLY */
 				if (sscanf(text_buffer, "#processed:%d", &game_version)) {
 					if (INTERPRETER_VERSION < game_version) {
-						sprintf(error_buffer, OLD_INTERPRETER, game_version);
+						Common::sprintf_s(error_buffer, 1024, OLD_INTERPRETER, game_version);
 						return (FALSE);
 					}
 				}
@@ -108,20 +108,20 @@ int jpp() {
 
 		delete inputFile;
 	} else {
-		sprintf(error_buffer, NOT_FOUND);
+		Common::sprintf_s(error_buffer, 1024, NOT_FOUND);
 		return (FALSE);
 	}
 
 	/* SAVE A TEMPORARY FILENAME INTO PROCESSED_FILE */
-	sprintf(processed_file, "%s%s.j2", temp_directory, prefix);
+	Common::sprintf_s(processed_file, "%s%s.j2", temp_directory, prefix);
 
 	/* ATTEMPT TO OPEN THE PROCESSED FILE IN THE TEMP DIRECTORY */
 	if ((outputFile = fopen(processed_file, "w")) == NULL) {
 		/* NO LUCK, TRY OPEN THE PROCESSED FILE IN THE CURRENT DIRECTORY */
-		sprintf(processed_file, "%s.j2", prefix);
+		Common::sprintf_s(processed_file, "%s.j2", prefix);
 		if ((outputFile = fopen(processed_file, "w")) == NULL) {
 			/* NO LUCK, CAN'T CONTINUE */
-			sprintf(error_buffer, CANT_OPEN_PROCESSED, processed_file);
+			Common::sprintf_s(error_buffer, 1024, CANT_OPEN_PROCESSED, processed_file);
 			return (FALSE);
 		}
 	}
@@ -154,12 +154,12 @@ int process_file(const char *sourceFile1, char *sourceFile2) {
 		if (sourceFile2 != nullptr) {
 			srcFile = File::openForReading(sourceFile2);
 			if (!srcFile) {
-				sprintf(error_buffer, CANT_OPEN_OR, sourceFile1, sourceFile2);
+				Common::sprintf_s(error_buffer, 1024, CANT_OPEN_OR, sourceFile1, sourceFile2);
 				return (FALSE);
 			}
 
 		} else {
-			sprintf(error_buffer, CANT_OPEN_SOURCE, sourceFile1);
+			Common::sprintf_s(error_buffer, 1024, CANT_OPEN_SOURCE, sourceFile1);
 			return (FALSE);
 		}
 	}
@@ -167,7 +167,7 @@ int process_file(const char *sourceFile1, char *sourceFile2) {
 	*text_buffer = 0;
 
 	if (srcFile->read(text_buffer, 1024) != 1024) {
-		sprintf(error_buffer, READ_ERROR);
+		Common::sprintf_s(error_buffer, 1024, READ_ERROR);
 		delete srcFile;
 		return (FALSE);
 	}
@@ -191,7 +191,7 @@ int process_file(const char *sourceFile1, char *sourceFile2) {
 					return (FALSE);
 				}
 			} else {
-				sprintf(error_buffer, BAD_INCLUDE);
+				Common::sprintf_s(error_buffer, 1024, BAD_INCLUDE);
 				return (FALSE);
 			}
 		} else {
@@ -214,7 +214,7 @@ int process_file(const char *sourceFile1, char *sourceFile2) {
 
 			lines_written++;
 			if (lines_written == 1) {
-				sprintf(temp_buffer, "#processed:%d\n", INTERPRETER_VERSION);
+				Common::sprintf_s(temp_buffer, 1024, "#processed:%d\n", INTERPRETER_VERSION);
 				outputFile->writeString(temp_buffer);
 			}
 		}
diff --git a/engines/glk/jacl/loader.cpp b/engines/glk/jacl/loader.cpp
index c8654ab9657..3e118e76ac3 100644
--- a/engines/glk/jacl/loader.cpp
+++ b/engines/glk/jacl/loader.cpp
@@ -1063,7 +1063,7 @@ int legal_label_check(const char *label_word, int line, int type) {
 	        !strcmp(label_word, "noun4") ||
 	        !strcmp(label_word, "objects") ||
 	        validate(label_word)) {
-		sprintf(error_buffer, ILLEGAL_LABEL, line, label_word);
+		Common::sprintf_s(error_buffer, 1024, ILLEGAL_LABEL, line, label_word);
 		log_error(error_buffer, PLUS_STDERR);
 
 		return (TRUE);
@@ -1071,7 +1071,7 @@ int legal_label_check(const char *label_word, int line, int type) {
 
 	if (type == CSTR_TYPE) {
 		if (!strcmp(label_word, "command_prompt")) {
-			sprintf(error_buffer, USED_LABEL_STR, line, label_word);
+			Common::sprintf_s(error_buffer, 1024, USED_LABEL_STR, line, label_word);
 			log_error(error_buffer, PLUS_STDERR);
 
 			return (TRUE);
@@ -1080,7 +1080,7 @@ int legal_label_check(const char *label_word, int line, int type) {
 
 	while (integer_pointer != nullptr && type != INT_TYPE) {
 		if (!strcmp(label_word, integer_pointer->name)) {
-			sprintf(error_buffer, USED_LABEL_INT, line, label_word);
+			Common::sprintf_s(error_buffer, 1024, USED_LABEL_INT, line, label_word);
 			log_error(error_buffer, PLUS_STDERR);
 
 			return (TRUE);
@@ -1091,7 +1091,7 @@ int legal_label_check(const char *label_word, int line, int type) {
 
 	while (cinteger_pointer != nullptr && type != CINT_TYPE) {
 		if (!strcmp(label_word, cinteger_pointer->name)) {
-			sprintf(error_buffer, USED_LABEL_CINT, line, label_word);
+			Common::sprintf_s(error_buffer, 1024, USED_LABEL_CINT, line, label_word);
 			log_error(error_buffer, PLUS_STDERR);
 
 			return (TRUE);
@@ -1101,7 +1101,7 @@ int legal_label_check(const char *label_word, int line, int type) {
 
 	while (string_pointer != nullptr && type != STR_TYPE) {
 		if (!strcmp(label_word, string_pointer->name)) {
-			sprintf(error_buffer, USED_LABEL_STR, line, label_word);
+			Common::sprintf_s(error_buffer, 1024, USED_LABEL_STR, line, label_word);
 			log_error(error_buffer, PLUS_STDERR);
 
 			return (TRUE);
@@ -1111,7 +1111,7 @@ int legal_label_check(const char *label_word, int line, int type) {
 
 	while (cstring_pointer != nullptr && type != CSTR_TYPE) {
 		if (!strcmp(label_word, cstring_pointer->name)) {
-			sprintf(error_buffer, USED_LABEL_CSTR, line, label_word);
+			Common::sprintf_s(error_buffer, 1024, USED_LABEL_CSTR, line, label_word);
 			log_error(error_buffer, PLUS_STDERR);
 
 			return (TRUE);
@@ -1122,7 +1122,7 @@ int legal_label_check(const char *label_word, int line, int type) {
 	/* DON'T CHECK FOR ATT_TYPE AS YOU CAN'T HAVE ATTRIBUTE ARRAYS. */
 	while (attribute_pointer != nullptr) {
 		if (!strcmp(label_word, attribute_pointer->name)) {
-			sprintf(error_buffer, USED_LABEL_ATT, line, label_word);
+			Common::sprintf_s(error_buffer, 1024, USED_LABEL_ATT, line, label_word);
 			write_text(error_buffer);
 
 			return (TRUE);
@@ -1132,7 +1132,7 @@ int legal_label_check(const char *label_word, int line, int type) {
 
 	for (index = 1; index <= objects; index++) {
 		if (!strcmp(label_word, object[index]->label)) {
-			sprintf(error_buffer, USED_LABEL_OBJ,
+			Common::sprintf_s(error_buffer, 1024, USED_LABEL_OBJ,
 			        line, label_word);
 			log_error(error_buffer, PLUS_STDERR);
 
@@ -1170,7 +1170,7 @@ void restart_game() {
 
 			/* STORE A COPY OF THE CURRENT VOLUME FOR ACCESS
 			 * FROM JACL CODE */
-			sprintf(temp_buffer, "volume[%d]", index);
+			Common::sprintf_s(temp_buffer, 1024, "volume[%d]", index);
 			cinteger_resolve(temp_buffer)->value = 100;
 		}
 	}
diff --git a/engines/glk/jacl/logging.cpp b/engines/glk/jacl/logging.cpp
index 2cdd201665a..6573b438caa 100644
--- a/engines/glk/jacl/logging.cpp
+++ b/engines/glk/jacl/logging.cpp
@@ -37,7 +37,7 @@ void log_error(const char *message, int console) {
 	event_t         event;
 
 	// BUILD A STRING SUITABLE FOR DISPLAY ON THE CONSOLE.
-	sprintf(consoleMessage, "ERROR: %s^", message);
+	Common::sprintf_s(consoleMessage, "ERROR: %s^", message);
 
 	g_vm->glk_set_style(style_Alert);
 	write_text(consoleMessage);
diff --git a/engines/glk/jacl/parser.cpp b/engines/glk/jacl/parser.cpp
index 2c14dbf0a55..a89d30805c5 100644
--- a/engines/glk/jacl/parser.cpp
+++ b/engines/glk/jacl/parser.cpp
@@ -183,7 +183,7 @@ void parser() {
 					if (last_exact == -1) {
 						write_text(cstring_resolve("NO_MULTI_START")->value);
 					} else {
-						sprintf(error_buffer, cstring_resolve("NO_MULTI_VERB")->value, word[last_exact]);
+						Common::sprintf_s(error_buffer, 1024, cstring_resolve("NO_MULTI_VERB")->value, word[last_exact]);
 						write_text(error_buffer);
 					}
 
@@ -684,7 +684,7 @@ int build_object_list(struct word_type *scope_word, int noun_number) {
 				 * RESOLVED LIST */
 				noun_number = noun_number + 2;
 			} else {
-				sprintf(error_buffer, cstring_resolve("DOUBLE_EXCEPT")->value, except_word);
+				Common::sprintf_s(error_buffer, 1024, cstring_resolve("DOUBLE_EXCEPT")->value, except_word);
 				write_text(error_buffer);
 				custom_error = TRUE;
 				return (FALSE);
@@ -1031,9 +1031,9 @@ int verify_from_object(int from_object) {
 	if (object[from_object]->attributes & CONTAINER && object[from_object]->attributes & CLOSED) {
 		//printf("--- container is concealing\n");
 		if (object[from_object]->attributes & FEMALE) {
-			sprintf(error_buffer, cstring_resolve("CONTAINER_CLOSED_FEM")->value, sentence_output(from_object, TRUE));
+			Common::sprintf_s(error_buffer, 1024, cstring_resolve("CONTAINER_CLOSED_FEM")->value, sentence_output(from_object, TRUE));
 		} else {
-			sprintf(error_buffer, cstring_resolve("CONTAINER_CLOSED")->value, sentence_output(from_object, TRUE));
+			Common::sprintf_s(error_buffer, 1024, cstring_resolve("CONTAINER_CLOSED")->value, sentence_output(from_object, TRUE));
 		}
 		write_text(error_buffer);
 		custom_error = TRUE;
@@ -1675,7 +1675,7 @@ int noun_resolve(struct word_type *scope_word, int finding_from, int noun_number
 	for (index = 1; index <= objects; index++) {
 		if (confidence[index] != FALSE) {
 			possible_objects[counter] = index;
-			sprintf(text_buffer, "  [%d] ", counter);
+			Common::sprintf_s(text_buffer, 1024, "  [%d] ", counter);
 			write_text(text_buffer);
 			sentence_output(index, 0);
 			write_text(temp_buffer);
@@ -1830,7 +1830,7 @@ int find_parent(int index) {
 
 		if (index == parent) {
 			/* THIS OBJECT HAS ITS PARENT SET TO ITSELF */
-			sprintf(error_buffer, SELF_REFERENCE, executing_function->name, object[index]->label);
+			Common::sprintf_s(error_buffer, 1024, SELF_REFERENCE, executing_function->name, object[index]->label);
 			log_error(error_buffer, PLUS_STDOUT);
 			return (FALSE);
 		} else  if (!(object[parent]->attributes & LOCATION)
@@ -1881,7 +1881,7 @@ int parent_of(int parent_, int child, int restricted) {
 
 		if (index == child) {
 			/* THIS CHILD HAS IT'S PARENT SET TO ITSELF */
-			sprintf(error_buffer, SELF_REFERENCE, executing_function->name, object[index]->label);
+			Common::sprintf_s(error_buffer, 1024, SELF_REFERENCE, executing_function->name, object[index]->label);
 			log_error(error_buffer, PLUS_STDOUT);
 			//printf("--- self parent_.\n");
 			return (FALSE);
diff --git a/engines/glk/jacl/resolvers.cpp b/engines/glk/jacl/resolvers.cpp
index c74a001b64d..b7c4225c718 100644
--- a/engines/glk/jacl/resolvers.cpp
+++ b/engines/glk/jacl/resolvers.cpp
@@ -176,17 +176,17 @@ const char *text_of(const char *string) {
 	} else if ((resolved_integer = integer_resolve(string)) != nullptr) {
 		value_has_been_resolved = FALSE;
 		integer_buffer[0] = 0;
-		sprintf(integer_buffer, "%d", resolved_integer->value);
+		Common::sprintf_s(integer_buffer, "%d", resolved_integer->value);
 		return (integer_buffer);
 	} else if ((resolved_cinteger = cinteger_resolve(string)) != nullptr) {
 		value_has_been_resolved = FALSE;
 		integer_buffer[0] = 0;
-		sprintf(integer_buffer, "%d", resolved_cinteger->value);
+		Common::sprintf_s(integer_buffer, "%d", resolved_cinteger->value);
 		return (integer_buffer);
 	} else if (object_element_resolve(string)) {
 		value_has_been_resolved = FALSE;
 		integer_buffer[0] = 0;
-		sprintf(integer_buffer, "%d", oec);
+		Common::sprintf_s(integer_buffer, "%d", oec);
 		return (integer_buffer);
 	} else if ((index = object_resolve(string)) != -1) {
 		value_has_been_resolved = FALSE;
@@ -202,7 +202,7 @@ const char *text_of(const char *string) {
 		return (resolved_cstring->value);
 	} else if (function_resolve(string) != nullptr) {
 		value_has_been_resolved = FALSE;
-		sprintf(integer_buffer, "%d", execute(string));
+		Common::sprintf_s(integer_buffer, "%d", execute(string));
 		return (integer_buffer);
 #ifndef GLK
 #ifndef __NDS__
@@ -745,7 +745,7 @@ const char *expand_function(const char *name) {
 	        object_element_resolve(&expression[delimiter])) {
 		/* THE DELIMETER RESOLVES TO A CONSTANT, VARIABLE OR OBJECT
 		 * ELEMENT, SO TAKE NOTE OF THAT */
-		sprintf(function_name, "%ld", value_of(&expression[delimiter], TRUE));
+		Common::sprintf_s(function_name, 81, "%ld", value_of(&expression[delimiter], TRUE));
 	} else {
 		Common::strcpy_s(function_name, 81, &expression[delimiter]);
 	}
@@ -974,7 +974,7 @@ char *macro_resolve(const char *testString) {
 		Common::strcpy_s(macro_function, "+macro_");
 		Common::strcat_s(macro_function, &expression[delimiter]);
 		Common::strcat_s(macro_function, "<");
-		sprintf(temp_buffer, "%d", index);
+		Common::sprintf_s(temp_buffer, 1024, "%d", index);
 		Common::strcat_s(macro_function, temp_buffer);
 
 		// BUILD THE FUNCTION NAME AND PASS THE OBJECT AS
@@ -1148,7 +1148,7 @@ int object_element_resolve(const char *testString) {
 	counter = value_of(&expression[delimiter], TRUE);
 
 	if (counter < 0 || counter > 15) {
-		sprintf(error_buffer,
+		Common::sprintf_s(error_buffer, 1024,
 		        "ERROR: In function \"%s\", element \"%s\" out of range (%d).^",
 		        executing_function->name, &expression[delimiter], counter);
 		write_text(error_buffer);
@@ -1178,7 +1178,7 @@ int object_resolve(const char *object_string) {
 	else if (!strcmp(object_string, "self") ||
 	         !strcmp(object_string, "this")) {
 		if (executing_function != nullptr && executing_function->self == 0) {
-			sprintf(error_buffer,
+			Common::sprintf_s(error_buffer, 1024,
 			        "ERROR: Reference to 'self' from global function \"%s\".^",
 			        executing_function->name);
 			write_text(error_buffer);
diff --git a/engines/glk/jacl/utils.cpp b/engines/glk/jacl/utils.cpp
index ffbbdf315cf..34865f80667 100644
--- a/engines/glk/jacl/utils.cpp
+++ b/engines/glk/jacl/utils.cpp
@@ -141,9 +141,9 @@ void create_paths(char *full_path) {
 		/* THIS ADDITION OF ./ TO THE FRONT OF THE GAMEFILE IF IT IS IN THE
 		 * CURRENT DIRECTORY IS REQUIRED TO KEEP Gargoyle HAPPY. */
 #ifdef __NDS__
-		sprintf(temp_buffer, "%c%s", DIR_SEPARATOR, game_file);
+		Common::sprintf_s(temp_buffer, "%c%s", DIR_SEPARATOR, game_file);
 #else
-		sprintf(temp_buffer, ".%c%s", DIR_SEPARATOR, game_file);
+		Common::sprintf_s(temp_buffer, ".%c%s", DIR_SEPARATOR, game_file);
 #endif
 		strcpy(game_file, temp_buffer);
 	} else {
@@ -157,13 +157,13 @@ void create_paths(char *full_path) {
 
 #ifdef GLK
 	/* SET DEFAULT WALKTHRU FILE NAME */
-	sprintf(walkthru, "%s.walkthru", prefix);
+	Common::sprintf_s(walkthru, "%s.walkthru", prefix);
 
 	/* SET DEFAULT SAVED GAME FILE NAME */
-	sprintf(bookmark, "%s.bookmark", prefix);
+	Common::sprintf_s(bookmark, "%s.bookmark", prefix);
 
 	/* SET DEFAULT BLORB FILE NAME */
-	sprintf(blorb, "%s.blorb", prefix);
+	Common::sprintf_s(blorb, "%s.blorb", prefix);
 #endif
 
 	/* SET DEFAULT FILE LOCATIONS IF NOT SET BY THE USER IN CONFIG */
diff --git a/engines/glk/level9/bitmap.cpp b/engines/glk/level9/bitmap.cpp
index 6707fa6be62..46e06702ddc 100644
--- a/engines/glk/level9/bitmap.cpp
+++ b/engines/glk/level9/bitmap.cpp
@@ -328,7 +328,7 @@ void bitmap_st2_name(int num, char *dir, char *out) {
 	/* title picture is #30 */
 	if (num == 0)
 		num = 30;
-	sprintf(out, "%s%d.squ", dir, num);
+	Common::sprintf_s(out, MAX_PATH, "%s%d.squ", dir, num);
 }
 
 /*
@@ -346,7 +346,7 @@ void bitmap_pc_name(int num, char *dir, char *out) {
 	/* title picture is #30 */
 	if (num == 0)
 		num = 30;
-	sprintf(out, "%s%d.pic", dir, num);
+	Common::sprintf_s(out, MAX_PATH, "%s%d.pic", dir, num);
 }
 
 /*
@@ -737,14 +737,14 @@ BitmapType bitmap_pc_type(char *file) {
 
 void bitmap_noext_name(int num, char *dir, char *out) {
 	if (num == 0) {
-		sprintf(out, "%stitle", dir);
+		Common::sprintf_s(out, MAX_PATH, "%stitle", dir);
 		if (Common::File::exists(out))
 			return;
 
 		num = 30;
 	}
 
-	sprintf(out, "%s%d", dir, num);
+	Common::sprintf_s(out, MAX_PATH, "%s%d", dir, num);
 }
 
 int bitmap_amiga_intensity(int col) {
@@ -1002,34 +1002,34 @@ const Colour bitmap_bbc_colours[] = {
 
 void bitmap_c64_name(int num, char *dir, char *out) {
 	if (num == 0)
-		sprintf(out, "%stitle mpic", dir);
+		Common::sprintf_s(out, MAX_PATH, "%stitle mpic", dir);
 	else
-		sprintf(out, "%spic%d", dir, num);
+		Common::sprintf_s(out, MAX_PATH, "%spic%d", dir, num);
 }
 
 void bitmap_bbc_name(int num, char *dir, char *out) {
 	if (num == 0) {
-		sprintf(out, "%sP.Title", dir);
+		Common::sprintf_s(out, MAX_PATH, "%sP.Title", dir);
 		if (Common::File::exists(out))
 			return;
 
-		sprintf(out, "%stitle", dir);
+		Common::sprintf_s(out, MAX_PATH, "%stitle", dir);
 	} else {
-		sprintf(out, "%sP.Pic%d", dir, num);
+		Common::sprintf_s(out, MAX_PATH, "%sP.Pic%d", dir, num);
 		if (Common::File::exists(out))
 			return;
 
-		sprintf(out, "%spic%d", dir, num);
+		Common::sprintf_s(out, MAX_PATH, "%spic%d", dir, num);
 	}
 }
 
 void bitmap_cpc_name(int num, char *dir, char *out) {
 	if (num == 0)
-		sprintf(out, "%stitle.pic", dir);
+		Common::sprintf_s(out, MAX_PATH, "%stitle.pic", dir);
 	else if (num == 1)
-		sprintf(out, "%s1.pic", dir);
+		Common::sprintf_s(out, MAX_PATH, "%s1.pic", dir);
 	else
-		sprintf(out, "%sallpics.pic", dir);
+		Common::sprintf_s(out, MAX_PATH, "%sallpics.pic", dir);
 }
 
 BitmapType bitmap_c64_type(char *file) {
diff --git a/engines/glk/level9/level9_main.cpp b/engines/glk/level9/level9_main.cpp
index bc101089245..c1f1d510f6f 100644
--- a/engines/glk/level9/level9_main.cpp
+++ b/engines/glk/level9/level9_main.cpp
@@ -327,7 +327,7 @@ void printstring(const char *buf) {
 
 void printdecimald0(int d0) {
 	char temp[12];
-	sprintf(temp, "%d", d0);
+	Common::sprintf_s(temp, "%d", d0);
 	printstring(temp);
 }
 
diff --git a/engines/glk/level9/os_glk.cpp b/engines/glk/level9/os_glk.cpp
index cb7b76e4dfb..0f65b2ba9fd 100644
--- a/engines/glk/level9/os_glk.cpp
+++ b/engines/glk/level9/os_glk.cpp
@@ -3013,11 +3013,11 @@ static void gln_command_graphics(const char *argument) {
 
 				gln_normal_string("There is a picture loaded, ");
 
-				sprintf(buffer, "%d", width);
+				Common::sprintf_s(buffer, "%d", width);
 				gln_normal_string(buffer);
 				gln_normal_string(" by ");
 
-				sprintf(buffer, "%d", height);
+				Common::sprintf_s(buffer, "%d", height);
 				gln_normal_string(buffer);
 
 				gln_normal_string(" pixels.\n");
@@ -3038,7 +3038,7 @@ static void gln_command_graphics(const char *argument) {
 				gln_normal_string("Graphics are ");
 				gln_normal_string(is_active ? "active, " : "displayed, ");
 
-				sprintf(buffer, "%d", color_count);
+				Common::sprintf_s(buffer, "%d", color_count);
 				gln_normal_string(buffer);
 				gln_normal_string(" colours");
 
@@ -3210,7 +3210,7 @@ static void gln_command_prompts(const char *argument) {
 static void gln_command_print_version_number(glui32 version) {
 	char buffer[64];
 
-	sprintf(buffer, "%lu.%lu.%lu",
+	Common::sprintf_s(buffer, "%lu.%lu.%lu",
 	        (unsigned long) version >> 16,
 	        (unsigned long)(version >> 8) & 0xff,
 	        (unsigned long) version & 0xff);
diff --git a/engines/glk/magnetic/glk.cpp b/engines/glk/magnetic/glk.cpp
index e00a0c372e6..babd1cf15e4 100644
--- a/engines/glk/magnetic/glk.cpp
+++ b/engines/glk/magnetic/glk.cpp
@@ -2296,7 +2296,7 @@ void Magnetic::gms_hint_display_text(const ms_hint hints_[],
 	for (index = 0; index < hints_[node].elcount; index++) {
 		char buf[16];
 
-		sprintf(buf, "%3d.  ", index + 1);
+		Common::sprintf_s(buf, "%3d.  ", index + 1);
 		gms_hint_text_print(buf);
 
 		gms_hint_text_print(index < cursor[node]
@@ -2839,11 +2839,11 @@ void Magnetic::gms_command_graphics(const char *argument) {
 				gms_normal_string(is_animated ? "an animated" : "a");
 				gms_normal_string(" picture loaded, ");
 
-				sprintf(buf, "%d", width);
+				Common::sprintf_s(buf, "%d", width);
 				gms_normal_string(buf);
 				gms_normal_string(" by ");
 
-				sprintf(buf, "%d", height);
+				Common::sprintf_s(buf, "%d", height);
 				gms_normal_string(buf);
 
 				gms_normal_string(" pixels.\n");
@@ -2864,7 +2864,7 @@ void Magnetic::gms_command_graphics(const char *argument) {
 				gms_normal_string("Graphics are ");
 				gms_normal_string(is_active ? "active, " : "displayed, ");
 
-				sprintf(buf, "%d", color_count);
+				Common::sprintf_s(buf, "%d", color_count);
 				gms_normal_string(buf);
 				gms_normal_string(" colours");
 
diff --git a/engines/glk/quest/quest.cpp b/engines/glk/quest/quest.cpp
index e430f3ba7ac..0061d8d678e 100644
--- a/engines/glk/quest/quest.cpp
+++ b/engines/glk/quest/quest.cpp
@@ -77,7 +77,7 @@ void Quest::playGame() {
 		else
 			glk_put_cstring("\n");
 
-		sprintf(cur_buf, "> ");
+		Common::sprintf_s(cur_buf, "> ");
 		glk_put_string_stream(inputwinstream, cur_buf);
 
 		glk_request_line_event(inputwin, buf, (sizeof buf) - 1, 0);
diff --git a/engines/glk/scott/unp64/unp64.cpp b/engines/glk/scott/unp64/unp64.cpp
index 7da8e279a33..5f3723a1222 100644
--- a/engines/glk/scott/unp64/unp64.cpp
+++ b/engines/glk/scott/unp64/unp64.cpp
@@ -589,9 +589,13 @@ int unp64(uint8_t *compressed, size_t length, uint8_t *destinationBuffer, size_t
 	if (*forcedname) {
 		Common::strcpy_s(name, forcedname);
 	} else {
-		if (strlen(name) > 248) /* dirty hack in case name is REALLY long */
+		size_t ln = strlen(name);
+		if (ln > 248) {/* dirty hack in case name is REALLY long */
 			name[248] = 0;
-		sprintf(name + strlen(name), ".%04x%s", r->_pc, ((_G(_unp)._wrMemF | _G(_unp)._lfMemF) ? ".clean" : ""));
+			ln = 248;
+		}
+
+		Common::sprintf_s(name + ln, sizeof(name) - ln, ".%04x%s", r->_pc, ((_G(_unp)._wrMemF | _G(_unp)._lfMemF) ? ".clean" : ""));
 	}
 
 	/*  endadr is set to a ZP location? then use it as a pointer
diff --git a/engines/glk/tads/os_glk.cpp b/engines/glk/tads/os_glk.cpp
index 7306814e9fd..0994ef84113 100644
--- a/engines/glk/tads/os_glk.cpp
+++ b/engines/glk/tads/os_glk.cpp
@@ -345,7 +345,7 @@ int os_get_status()
 void os_score(int score, int turncount)
 {
 	char buf[40];
-	sprintf(buf, "%d/%d", score, turncount);
+	Common::sprintf_s(buf, "%d/%d", score, turncount);
 	os_strsc(buf);
 }
 
@@ -368,8 +368,8 @@ static void os_status_redraw(void) {
 	g_vm->glk_window_get_size(statuswin, &wid, nullptr);
 	div = wid - strlen(rbuf) - 3;
 
-	sprintf(fmt, " %%%ds %%s ", - (int)div);
-	sprintf(buf, fmt, lbuf, rbuf);
+	Common::sprintf_s(fmt, " %%%ds %%s ", - (int)div);
+	Common::sprintf_s(buf, fmt, lbuf, rbuf);
 
 	g_vm->glk_window_clear(statuswin);
 	g_vm->glk_set_window(statuswin);
diff --git a/engines/glk/tads/os_glk.h b/engines/glk/tads/os_glk.h
index d3662ff657e..925a1567c9e 100644
--- a/engines/glk/tads/os_glk.h
+++ b/engines/glk/tads/os_glk.h
@@ -1609,7 +1609,7 @@ int os_get_status();
  *.  void os_score(int score, int turncount)
  *.  {
  *.     char buf[40];
- *.     sprintf(buf, "%d/%d", score, turncount);
+ *.     Common::sprintf_s(buf, "%d/%d", score, turncount);
  *.     os_strsc(buf);
  *.  }
  */
diff --git a/engines/glk/tads/tads2/built_in.cpp b/engines/glk/tads/tads2/built_in.cpp
index 27247af298f..23104fcf77b 100644
--- a/engines/glk/tads/tads2/built_in.cpp
+++ b/engines/glk/tads/tads2/built_in.cpp
@@ -517,7 +517,7 @@ void bifsay(bifcxdef *ctx, int argc)
 	{
 	case DAT_NUMBER:
 		num = runpopnum(ctx->bifcxrun);
-		sprintf(numbuf, "%ld", num);
+		Common::sprintf_s(numbuf, "%ld", num);
 		tioputs(ctx->bifcxtio, numbuf);
 		break;
 
@@ -1208,7 +1208,7 @@ void bifcvs(bifcxdef *ctx, int argc)
 		break;
 
 	case DAT_NUMBER:
-		sprintf(buf, "%ld", runpopnum(ctx->bifcxrun));
+		Common::sprintf_s(buf, "%ld", runpopnum(ctx->bifcxrun));
 		p = buf;
 		len = strlen(buf);
 		break;
diff --git a/engines/glk/tads/tads2/debug.cpp b/engines/glk/tads/tads2/debug.cpp
index b641c3295ea..cf30ffe980f 100644
--- a/engines/glk/tads/tads2/debug.cpp
+++ b/engines/glk/tads/tads2/debug.cpp
@@ -175,7 +175,7 @@ int dbgnam(dbgcxdef *ctx, char *outbuf, int typ, int val)
 		}
 		else
 		{
-			sprintf(outbuf, "<object#%u>", val);
+			Common::sprintf_s(outbuf, TOKNAMMAX + 1, "<object#%u>", val);
 			return strlen(outbuf);
 		}
 	}
@@ -198,7 +198,7 @@ static void dbgpbval(dbgcxdef *ctx, dattyp typ, const uchar *val,
 	switch(typ)
 	{
 	case DAT_NUMBER:
-		sprintf(buf, "%ld", (long)osrp4s(val));
+		Common::sprintf_s(buf, "%ld", (long)osrp4s(val));
 		len = strlen(buf);
 		break;
 
@@ -270,7 +270,7 @@ void dbgpval(dbgcxdef *ctx, runsdef *val,
 	switch(val->runstyp)
 	{
 	case DAT_NUMBER:
-		sprintf((char *)buf, "%ld", val->runsv.runsvnum);
+		Common::sprintf_s(buf, "%ld", val->runsv.runsvnum);
 		len = strlen((char *)buf);
 		typ = "number";
 		break;
@@ -393,7 +393,7 @@ void dbgstktr(dbgcxdef *ctx,
 		else if (include_markers)
 		{
 			c = (i == level + 1 ? '*' : ' ');
-			sprintf(buf, "%3d%c  ", j, c);
+			Common::sprintf_s(buf, "%3d%c  ", j, c);
 			p += 4;
 		}
 
diff --git a/engines/glk/tads/tads2/error.cpp b/engines/glk/tads/tads2/error.cpp
index 6e1b195eece..476ac4f53d5 100644
--- a/engines/glk/tads/tads2/error.cpp
+++ b/engines/glk/tads/tads2/error.cpp
@@ -76,7 +76,7 @@ int errfmt(char *outbuf, int outbufl, const char *fmt, int argc, const erradef *
 				break;
 
 			case 'd':
-				sprintf(buf, "%d", argv[argi].erraint);
+				Common::sprintf_s(buf, "%d", argv[argi].erraint);
 				len = strlen(buf);
 				p = buf;
 				break;
diff --git a/engines/glk/tads/tads2/error_handling.cpp b/engines/glk/tads/tads2/error_handling.cpp
index 8d1685a9f13..220d5f06ef3 100644
--- a/engines/glk/tads/tads2/error_handling.cpp
+++ b/engines/glk/tads/tads2/error_handling.cpp
@@ -77,13 +77,13 @@ int errfmt(char *outbuf, int outbufl, char *fmt, int argc, erradef *argv)
 				break;
 
 			case 'd':
-				sprintf(buf, "%d", argv[argi].erraint);
+				Common::sprintf_s(buf, "%d", argv[argi].erraint);
 				len = strlen(buf);
 				p = buf;
 				break;
 
 			case 'u':
-				sprintf(buf, "%u", argv[argi].erraint);
+				Common::sprintf_s(buf, "%u", argv[argi].erraint);
 				len = strlen(buf);
 				p = buf;
 				break;
diff --git a/engines/glk/tads/tads2/error_message.cpp b/engines/glk/tads/tads2/error_message.cpp
index c7fa2230844..41b6205cd27 100644
--- a/engines/glk/tads/tads2/error_message.cpp
+++ b/engines/glk/tads/tads2/error_message.cpp
@@ -61,7 +61,7 @@ void lerfre(errcxdef *errcx) {
 }
 
 void errmsg(errcxdef *ctx, char *outbuf, uint outbufl, uint err) {
-	sprintf(outbuf, "Error #%d occurred.", err);
+	Common::sprintf_s(outbuf, outbufl, "Error #%d occurred.", err);
 }
 
 } // End of namespace TADS2
diff --git a/engines/glk/tads/tads2/line_source_file.cpp b/engines/glk/tads/tads2/line_source_file.cpp
index d7714ac1526..e1c39a4b8f5 100644
--- a/engines/glk/tads/tads2/line_source_file.cpp
+++ b/engines/glk/tads/tads2/line_source_file.cpp
@@ -378,7 +378,7 @@ void linfppos(lindef *lin, char *buf, uint buflen)
 {
 	VARUSED(buflen);
 
-	sprintf(buf, "%s(%lu): ", ((linfdef *)lin)->linfnam,
+	Common::sprintf_s(buf, buflen, "%s(%lu): ", ((linfdef *)lin)->linfnam,
 			((linfdef *)lin)->linfnum);
 }
 
diff --git a/engines/glk/tads/tads2/ltk.cpp b/engines/glk/tads/tads2/ltk.cpp
index f9cc7d25a48..476d9764307 100644
--- a/engines/glk/tads/tads2/ltk.cpp
+++ b/engines/glk/tads/tads2/ltk.cpp
@@ -162,7 +162,7 @@ void ltk_dlg(const char *title, const char *msg, ...) {
 
 	/* get the printf args, build the message, and display it */
 	va_start(argp, msg);
-	vsprintf(outbuf, inbuf, argp);
+	Common::vsprintf_s(outbuf, inbuf, argp);
 
 	/* display the message */
 	error("%s", outbuf);
diff --git a/engines/glk/tads/tads2/play.cpp b/engines/glk/tads/tads2/play.cpp
index 4f7648a6829..1948b2ed7d4 100644
--- a/engines/glk/tads/tads2/play.cpp
+++ b/engines/glk/tads/tads2/play.cpp
@@ -189,7 +189,7 @@ startover:
 			{
 				char buf[60 + OSFNMAX];
 
-				sprintf(buf, "\n\nError: unable to restore file \"%s\"\n\n",
+				Common::sprintf_s(buf, "\n\nError: unable to restore file \"%s\"\n\n",
 						restore_fname);
 				os_printz(buf);
 			}
diff --git a/engines/glk/tads/tads2/runtime_driver.cpp b/engines/glk/tads/tads2/runtime_driver.cpp
index 814d72e4716..cc0f7973b82 100644
--- a/engines/glk/tads/tads2/runtime_driver.cpp
+++ b/engines/glk/tads/tads2/runtime_driver.cpp
@@ -165,7 +165,7 @@ static void trdptf(const char *fmt, ...)
 
 	/* format the string */
 	va_start(va, fmt);
-	vsprintf(buf, fmt, va);
+	Common::vsprintf_s(buf, fmt, va);
 	va_end(va);
 
 	/* print the formatted buffer */
@@ -793,7 +793,7 @@ static void trdlogerr(void *ctx0, const char *fac, int err, int argc, erradef *a
 	char      msg[256];
 
 	/* display the prefix message to the console and log file */
-	sprintf(buf, TRDLOGERR_PREFIX, fac, err);
+	Common::sprintf_s(buf, TRDLOGERR_PREFIX, fac, err);
 	trdptf("%s", buf);
 	out_logfile_print(buf, FALSE);
 
diff --git a/engines/glk/tads/tads2/tokenizer.cpp b/engines/glk/tads/tads2/tokenizer.cpp
index 540d600c2bf..d1466f73557 100644
--- a/engines/glk/tads/tads2/tokenizer.cpp
+++ b/engines/glk/tads/tads2/tokenizer.cpp
@@ -97,7 +97,7 @@ static tokdfdef *tok_find_define(tokcxdef *ctx, const char *sym, int len)
 					l = linlnum(ctx->tokcxlin);
 
 					/* convert it to a textual format for the expansion */
-					sprintf(df->expan, "%lu", l);
+					Common::sprintf_s(df->expan, "%lu", l);
 
 					/* set the expanded value's length */
 					df->explen = strlen(df->expan);
@@ -253,7 +253,7 @@ void tok_add_define_num_cvtcase(tokcxdef *ctx, char *sym, int len, int num)
 	char buf[20];
 
 	/* convert the value to a string */
-	sprintf(buf, "%d", num);
+	Common::sprintf_s(buf, "%d", num);
 
 	/* add the text value */
 	tok_add_define_cvtcase(ctx, sym, len, buf, strlen(buf));
diff --git a/engines/glk/tads/tads2/vocabulary_parser.cpp b/engines/glk/tads/tads2/vocabulary_parser.cpp
index 32cadea85f9..97e23fb100b 100644
--- a/engines/glk/tads/tads2/vocabulary_parser.cpp
+++ b/engines/glk/tads/tads2/vocabulary_parser.cpp
@@ -1844,7 +1844,7 @@ startover:
 			int     cnt;
 
 			(void)tioshow(ctx->voccxtio);
-			sprintf(buf, "... %s (", cmd[cur]);
+			Common::sprintf_s(buf, "... %s (", cmd[cur]);
 			p = buf + strlen(buf);
 			cnt = 0;
 			for (i = 0 ; i < sizeof(type_names)/sizeof(type_names[0]) ; ++i)
@@ -2045,7 +2045,7 @@ static int vocgol(voccxdef *ctx, objnum *list, uint *flags, char **wrdlst,
 	{
 		char buf[128];
 
-		sprintf(buf, "... %s (treating as %s%s)\\n", wrd,
+		Common::sprintf_s(buf, "... %s (treating as %s%s)\\n", wrd,
 				(wrdtyp == PRP_ADJ ? "adjective" :
 				 wrdtyp == PRP_NOUN ? "noun" :
 				 wrdtyp == PRP_INVALID ? "unknown" : "plural"),
@@ -7123,7 +7123,7 @@ static int vocready(voccxdef *ctx, char *cmd[], int *typelist, int cur,
 		{
 			char buf[128];
 
-			sprintf(buf, ". executing verb:  %s %s\\n",
+			Common::sprintf_s(buf, ". executing verb:  %s %s\\n",
 					vverb, vprep ? vprep : "");
 			tioputs(ctx->vocxtio, buf);
 		}
@@ -8144,7 +8144,7 @@ void *voc_stk_alo(voccxdef *ctx, uint siz)
 		char buf[20];
 
 		maxsiz = ctx->voc_stk_cur - ctx->voc_stk_ptr;
-		sprintf(buf, "%u\n", maxsiz);
+		Common::sprintf_s(buf, "%u\n", maxsiz);
 		os_printz(buf);
 	}
 }


Commit: 28318d083964ec0608c7e3a2c1e6a9efeabb1d6f
    https://github.com/scummvm/scummvm/commit/28318d083964ec0608c7e3a2c1e6a9efeabb1d6f
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GNAP: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/gnap/gnap.cpp
    engines/gnap/scenes/arcade.cpp


diff --git a/engines/gnap/gnap.cpp b/engines/gnap/gnap.cpp
index 2ad90cb072d..e57439249e1 100644
--- a/engines/gnap/gnap.cpp
+++ b/engines/gnap/gnap.cpp
@@ -451,7 +451,7 @@ void GnapEngine::updateCursorByHotspot() {
 		if (_debugger->_showHotspotNumber) {
 			// NOTE This causes some display glitches
 			char t[256];
-			sprintf(t, "hotspot = %2d", hotspotIndex);
+			Common::sprintf_s(t, "hotspot = %2d", hotspotIndex);
 			if (!_font)
 				_gameSys->fillSurface(nullptr, 10, 10, 80, 16, 0, 0, 0);
 			else
diff --git a/engines/gnap/scenes/arcade.cpp b/engines/gnap/scenes/arcade.cpp
index a4d451a143b..0e8c451724e 100644
--- a/engines/gnap/scenes/arcade.cpp
+++ b/engines/gnap/scenes/arcade.cpp
@@ -658,7 +658,7 @@ bool Scene50::updateCountdown() {
 
 void Scene50::drawCountdown(int value) {
 	char str[8];
-	sprintf(str, "%02d", value);
+	Common::sprintf_s(str, "%02d", value);
 	_vm->_gameSys->fillSurface(nullptr, 371, 505, 50, 27, 0, 0, 0);
 	_vm->_gameSys->drawTextToSurface(nullptr, 381, 504, 255, 255, 255, str);
 }
@@ -2636,7 +2636,7 @@ void Scene52::initAnims() {
 
 void Scene52::drawScore(int score) {
 	char str[4];
-	sprintf(str, "%03d", score);
+	Common::sprintf_s(str, "%03d", score);
 	_vm->_gameSys->fillSurface(nullptr, 420, 80, 48, 30, 0, 0, 0);
 	_vm->_gameSys->drawTextToSurface(nullptr, 420, 80, 255, 255, 255, str);
 }


Commit: 4a82710bc077742c11d2dc9a3234cbbeb44baadc
    https://github.com/scummvm/scummvm/commit/4a82710bc077742c11d2dc9a3234cbbeb44baadc
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GOB: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/gob/draw_v1.cpp
    engines/gob/draw_v2.cpp
    engines/gob/inter_playtoons.cpp
    engines/gob/inter_v1.cpp
    engines/gob/inter_v7.cpp


diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index a0e6a91b4e9..7e38cc457e7 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -252,7 +252,7 @@ void Draw_v1::printTotText(int16 id) {
 			cmd = ptrEnd[17] & 0x7F;
 			if (cmd == 0) {
 				val = READ_LE_UINT16(ptrEnd + 18) * 4;
-				sprintf(buf, "%d", (int32)VAR_OFFSET(val));
+				Common::sprintf_s(buf, "%d", (int32)VAR_OFFSET(val));
 			} else if (cmd == 1) {
 				val = READ_LE_UINT16(ptrEnd + 18) * 4;
 
@@ -260,7 +260,7 @@ void Draw_v1::printTotText(int16 id) {
 			} else {
 				val = READ_LE_UINT16(ptrEnd + 18) * 4;
 
-				sprintf(buf, "%d", (int32)VAR_OFFSET(val));
+				Common::sprintf_s(buf, "%d", (int32)VAR_OFFSET(val));
 				if (buf[0] == '-') {
 					while (strlen(buf) - 1 < (uint32)ptrEnd[17]) {
 						_vm->_util->insertStr("0", buf, 1);
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index 5d15de01cbf..aacb4950c72 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -573,13 +573,13 @@ void Draw_v2::printTotText(int16 id) {
 			cmd = ptrEnd[17] & 0x7F;
 			if (cmd == 0) {
 				val = READ_LE_UINT16(ptrEnd + 18) * 4;
-				sprintf(buf, "%d", (int32)VAR_OFFSET(val));
+				Common::sprintf_s(buf, "%d", (int32)VAR_OFFSET(val));
 			} else if (cmd == 1) {
 				val = READ_LE_UINT16(ptrEnd + 18) * 4;
 				Common::strlcpy(buf, GET_VARO_STR(val), 20);
 			} else {
 				val = READ_LE_UINT16(ptrEnd + 18) * 4;
-				sprintf(buf, "%d", (int32)VAR_OFFSET(val));
+				Common::sprintf_s(buf, "%d", (int32)VAR_OFFSET(val));
 				if (buf[0] == '-') {
 					while (strlen(buf) - 1 < (uint32)ptrEnd[17]) {
 						_vm->_util->insertStr("0", buf, 1);
diff --git a/engines/gob/inter_playtoons.cpp b/engines/gob/inter_playtoons.cpp
index 48f9ce8997a..8d133506eef 100644
--- a/engines/gob/inter_playtoons.cpp
+++ b/engines/gob/inter_playtoons.cpp
@@ -132,26 +132,26 @@ void Inter_Playtoons::oPlaytoons_printText(OpFuncParams &params) {
 			switch (_vm->_game->_script->peekByte()) {
 			case TYPE_VAR_INT8:
 			case TYPE_ARRAY_INT8:
-				sprintf(buf + i, "%d",
+				Common::sprintf_s(buf + i, sizeof(buf) - i, "%d",
 						(int8) READ_VARO_UINT8(_vm->_game->_script->readVarIndex()));
 				break;
 
 			case TYPE_VAR_INT16:
 			case TYPE_VAR_INT32_AS_INT16:
 			case TYPE_ARRAY_INT16:
-				sprintf(buf + i, "%d",
+				Common::sprintf_s(buf + i, sizeof(buf) - i, "%d",
 						(int16) READ_VARO_UINT16(_vm->_game->_script->readVarIndex()));
 				break;
 
 			case TYPE_VAR_INT32:
 			case TYPE_ARRAY_INT32:
-				sprintf(buf + i, "%d",
+				Common::sprintf_s(buf + i, sizeof(buf) - i, "%d",
 						(int32)VAR_OFFSET(_vm->_game->_script->readVarIndex()));
 				break;
 
 			case TYPE_VAR_STR:
 			case TYPE_ARRAY_STR:
-				sprintf(buf + i, "%s",
+				Common::sprintf_s(buf + i, sizeof(buf) - i, "%s",
 						GET_VARO_STR(_vm->_game->_script->readVarIndex()));
 				break;
 
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 2d1bb80f94d..ff250052a74 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -961,13 +961,13 @@ void Inter_v1::o1_printText(OpFuncParams &params) {
 			switch (_vm->_game->_script->peekByte()) {
 			case TYPE_VAR_INT32:
 			case TYPE_ARRAY_INT32:
-				sprintf(buf + i, "%d",
+				Common::sprintf_s(buf + i, sizeof(buf) - i, "%d",
 					(int32)VAR_OFFSET(_vm->_game->_script->readVarIndex()));
 				break;
 
 			case TYPE_VAR_STR:
 			case TYPE_ARRAY_STR:
-				sprintf(buf + i, "%s",
+				Common::sprintf_s(buf + i, sizeof(buf) - i, "%s",
 					GET_VARO_STR(_vm->_game->_script->readVarIndex()));
 				break;
 
diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp
index 5018ae6adf8..63fc0c34409 100644
--- a/engines/gob/inter_v7.cpp
+++ b/engines/gob/inter_v7.cpp
@@ -235,8 +235,9 @@ void Inter_v7::o7_logString() {
 void Inter_v7::o7_intToString() {
 	uint16 valueIndex = _vm->_game->_script->readVarIndex();
 	uint16 destIndex  = _vm->_game->_script->readVarIndex();
+	uint32 maxLength = _vm->_global->_inter_animDataSize * 4 - 1;
 
-	sprintf(GET_VARO_STR(destIndex), "%d", (int32)READ_VARO_UINT32(valueIndex));
+	Common::sprintf_s(GET_VARO_STR(destIndex), maxLength, "%d", (int32)READ_VARO_UINT32(valueIndex));
 }
 
 void Inter_v7::o7_callFunction() {


Commit: 0674bd29a7c7829986e0dab49ff2884e595ce558
    https://github.com/scummvm/scummvm/commit/0674bd29a7c7829986e0dab49ff2884e595ce558
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GRIFFON: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/griffon/combat.cpp
    engines/griffon/dialogs.cpp
    engines/griffon/draw.cpp
    engines/griffon/input.cpp
    engines/griffon/resources.cpp
    engines/griffon/saveload.cpp


diff --git a/engines/griffon/combat.cpp b/engines/griffon/combat.cpp
index 5a3d86c4807..7f07d2ffd59 100644
--- a/engines/griffon/combat.cpp
+++ b/engines/griffon/combat.cpp
@@ -572,14 +572,14 @@ void GriffonEngine::damageNPC(int npcnum, int damage, int spell) {
 			if (_npcInfo[npcnum].hp < 0)
 				_npcInfo[npcnum].hp = 0;
 
-			sprintf(line, "-%i", damage);
+			Common::sprintf_s(line, "-%i", damage);
 			fcol = 1;
 		} else {
 			_npcInfo[npcnum].hp += damage;
 			if (_npcInfo[npcnum].hp > _npcInfo[npcnum].maxhp)
 				_npcInfo[npcnum].hp = _npcInfo[npcnum].maxhp;
 
-			sprintf(line, "+%i", damage);
+			Common::sprintf_s(line, "+%i", damage);
 			fcol = 5;
 		}
 
@@ -1019,7 +1019,7 @@ void GriffonEngine::damagePlayer(int damage) {
 	if (_player.hp < 0)
 		_player.hp = 0;
 
-	sprintf(line, "-%i", damage);
+	Common::sprintf_s(line, "-%i", damage);
 	if (damage == 0)
 		Common::strcpy_s(line, "miss!");
 
diff --git a/engines/griffon/dialogs.cpp b/engines/griffon/dialogs.cpp
index 128d6d64bd4..c4dc1465b86 100644
--- a/engines/griffon/dialogs.cpp
+++ b/engines/griffon/dialogs.cpp
@@ -568,20 +568,20 @@ void GriffonEngine::renderSaveStates() {
 			int s = (ase - m * 60);
 
 			char line[256];
-			sprintf(line, "Game Time: %02i:%02i:%02i", h, m, s);
+			Common::sprintf_s(line, "Game Time: %02i:%02i:%02i", h, m, s);
 			drawString(_videoBuffer2, line, 160 - strlen(line) * 4, sy, 0);
 
 			sx = 12;
 			sy += 11;
 			int cc = 0;
 
-			sprintf(line, "Health: %i/%i", _playera.hp, _playera.maxHp);
+			Common::sprintf_s(line, "Health: %i/%i", _playera.hp, _playera.maxHp);
 			drawString(_videoBuffer2, line, sx, sy, cc);
 
 			if (_playera.level == 22)
 				Common::strcpy_s(line, "Level: MAX");
 			else
-				sprintf(line, "Level: %i", _playera.level);
+				Common::sprintf_s(line, "Level: %i", _playera.level);
 
 			drawString(_videoBuffer2, line, sx, sy + 11, 0);
 
diff --git a/engines/griffon/draw.cpp b/engines/griffon/draw.cpp
index 71a9aeccbae..f3da046f677 100644
--- a/engines/griffon/draw.cpp
+++ b/engines/griffon/draw.cpp
@@ -305,10 +305,10 @@ void GriffonEngine::drawHud() {
 		}
 
 		char line[128];
-		sprintf(line, "Health: %i/%i", _player.hp, _player.maxHp);
+		Common::sprintf_s(line, "Health: %i/%i", _player.hp, _player.maxHp);
 		drawString(_videoBuffer, line, sx, sy, _player.hp <= _player.maxHp * 0.25 ? (int)_player.hpflash : 0);
 
-		sprintf(line, "Level : %i", _player.level);
+		Common::sprintf_s(line, "Level : %i", _player.level);
 		if (_player.level == _player.maxLevel)
 			Common::strcpy_s(line, "Level : MAX");
 		drawString(_videoBuffer, line, sx, sy + 8, 0);
@@ -336,7 +336,7 @@ void GriffonEngine::drawHud() {
 		int m = ((ase - (ase % 60)) / 60);
 		int s = (ase - m * 60);
 
-		sprintf(line, "%02i:%02i:%02i", h, m, s);
+		Common::sprintf_s(line, "%02i:%02i:%02i", h, m, s);
 		drawString(_videoBuffer, line, 46 + 38 - strlen(line) * 4, 46 + 49, 0);
 
 		drawString(_videoBuffer, "Use", 193, 55, 0);
@@ -378,7 +378,7 @@ void GriffonEngine::drawHud() {
 			else if (i == 4)
 				_itemImg[14]->blit(*_videoBuffer, rcSrc.left, rcSrc.top);
 
-			sprintf(line, "x%i", _player.inventory[i]);
+			Common::sprintf_s(line, "x%i", _player.inventory[i]);
 			drawString(_videoBuffer, line, sx + 17, sy + 7, 0);
 		}
 
diff --git a/engines/griffon/input.cpp b/engines/griffon/input.cpp
index 777122c299d..13b9093d4e8 100644
--- a/engines/griffon/input.cpp
+++ b/engines/griffon/input.cpp
@@ -94,7 +94,7 @@ void GriffonEngine::checkInputs() {
 					_player.hp = _player.hp + heal;
 
 					char text[256];
-					sprintf(text, "+%i", heal);
+					Common::sprintf_s(text, "+%i", heal);
 					addFloatText(text, _player.px + 16 - 4 * strlen(text), _player.py + 16, 5);
 
 					_player.inventory[kInvFlask]--;
@@ -120,7 +120,7 @@ void GriffonEngine::checkInputs() {
 					_player.hp += heal;
 
 					char text[256];
-					sprintf(text, "+%i", heal);
+					Common::sprintf_s(text, "+%i", heal);
 					addFloatText(text, _player.px + 16 - 4 * strlen(text), _player.py + 16, 5);
 
 					_player.inventory[kInvDoubleFlask]--;
diff --git a/engines/griffon/resources.cpp b/engines/griffon/resources.cpp
index 8faf0e60a42..5f13bc6284a 100644
--- a/engines/griffon/resources.cpp
+++ b/engines/griffon/resources.cpp
@@ -84,7 +84,7 @@ void GriffonEngine::initialize() {
 	for (int i = 0; i <= 3; i++) {
 		char name[128];
 
-		sprintf(name, "art/map%i.bmp", i + 1);
+		Common::sprintf_s(name, "art/map%i.bmp", i + 1);
 		mapImg[i] = loadImage(name, true);
 	}
 
@@ -210,7 +210,7 @@ void GriffonEngine::loadMap(int mapnum) {
 
 	char name[256];
 	// read *.map file
-	sprintf(name, "mapdb/%04i.map", mapnum);
+	Common::sprintf_s(name, "mapdb/%04i.map", mapnum);
 	debug(1, "Reading %s", name);
 
 	Common::File file;
@@ -232,7 +232,7 @@ void GriffonEngine::loadMap(int mapnum) {
 	}
 
 	// read *.trg file
-	sprintf(name, "mapdb/%04i.trg", mapnum);
+	Common::sprintf_s(name, "mapdb/%04i.trg", mapnum);
 	debug(1, "Reading %s", name);
 	file.open(name);
 
@@ -480,7 +480,7 @@ void GriffonEngine::loadMap(int mapnum) {
 		_roomLock = true;
 
 	// read *.npc file
-	sprintf(name, "mapdb/%04i.npc", mapnum);
+	Common::sprintf_s(name, "mapdb/%04i.npc", mapnum);
 	debug(1, "Reading %s", name);
 	file.open(name);
 
diff --git a/engines/griffon/saveload.cpp b/engines/griffon/saveload.cpp
index 4e3c864331f..4427908aa80 100644
--- a/engines/griffon/saveload.cpp
+++ b/engines/griffon/saveload.cpp
@@ -43,7 +43,7 @@ namespace Griffon {
 #define PRINT(A,B)                      \
 	do {                                \
 		char line[256];                 \
-		sprintf(line, A "\n", B);       \
+		Common::sprintf_s(line, A "\n", B);       \
 		file->write(line, strlen(line)); \
 	} while(0)
 


Commit: a4073b8c6f0d8c03b421966d855b1df813df9cfc
    https://github.com/scummvm/scummvm/commit/a4073b8c6f0d8c03b421966d855b1df813df9cfc
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GRIM: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/grim/emi/lua_v2.cpp
    engines/grim/lua.cpp
    engines/grim/lua/lauxlib.cpp
    engines/grim/lua/lbuiltin.cpp
    engines/grim/lua/ldo.cpp
    engines/grim/lua/liolib.cpp
    engines/grim/lua/lstrlib.cpp
    engines/grim/lua/lvm.cpp
    engines/grim/lua_v1.cpp
    engines/grim/lua_v1_text.cpp


diff --git a/engines/grim/emi/lua_v2.cpp b/engines/grim/emi/lua_v2.cpp
index 97f94b28ebd..0a5e9445385 100644
--- a/engines/grim/emi/lua_v2.cpp
+++ b/engines/grim/emi/lua_v2.cpp
@@ -553,7 +553,7 @@ void Lua_V2::LocalizeString() {
 	if (lua_isstring(strObj)) {
 		const char *str = lua_getstring(strObj);
 		Common::String msg = parseMsgText(str, msgId);
-		sprintf(buf, "/%s/%s", msgId, msg.c_str());
+		Common::sprintf_s(buf, "/%s/%s", msgId, msg.c_str());
 
 		lua_pushstring(buf);
 	}
diff --git a/engines/grim/lua.cpp b/engines/grim/lua.cpp
index 29ed9909b4e..850ed961dd5 100644
--- a/engines/grim/lua.cpp
+++ b/engines/grim/lua.cpp
@@ -698,12 +698,12 @@ void LuaBase::concatFallback() {
 		strPtr = &result[pos];
 
 		if (lua_isnil(params[i]))
-			sprintf(strPtr, "(nil)");
+			Common::sprintf_s(strPtr, sizeof(result) - pos, "(nil)");
 		else if (lua_isstring(params[i]))
-			sprintf(strPtr, "%s", lua_getstring(params[i]));
+			Common::sprintf_s(strPtr, sizeof(result) - pos, "%s", lua_getstring(params[i]));
 		else if (lua_tag(params[i]) == MKTAG('A','C','T','R')) {
 			Actor *a = getactor(params[i]);
-			sprintf(strPtr, "(actor%p:%s)", (void *)a,
+			Common::sprintf_s(strPtr, sizeof(result) - pos, "(actor%p:%s)", (void *)a,
 					(a->getCurrentCostume() && a->getCurrentCostume()->getModelNodes()) ?
 					a->getCurrentCostume()->getModelNodes()->_name : "");
 		} else {
diff --git a/engines/grim/lua/lauxlib.cpp b/engines/grim/lua/lauxlib.cpp
index 9f8c52ff11c..bafad6eed85 100644
--- a/engines/grim/lua/lauxlib.cpp
+++ b/engines/grim/lua/lauxlib.cpp
@@ -8,6 +8,7 @@
 ** Any function declared here could be written as an application
 ** function. With care, these functions can be used by other libraries.
 */
+#define FORBIDDEN_SYMBOL_EXCEPTION_vsprintf
 
 #include "engines/grim/lua/lauxlib.h"
 #include "engines/grim/lua/lua.h"
diff --git a/engines/grim/lua/lbuiltin.cpp b/engines/grim/lua/lbuiltin.cpp
index 5490c6da623..f64e5e60a9f 100644
--- a/engines/grim/lua/lbuiltin.cpp
+++ b/engines/grim/lua/lbuiltin.cpp
@@ -6,6 +6,7 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
 #define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
 #define FORBIDDEN_SYMBOL_EXCEPTION_printf
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 
 #include "common/util.h"
 
diff --git a/engines/grim/lua/ldo.cpp b/engines/grim/lua/ldo.cpp
index 3b05144c2d3..617a42f31b5 100644
--- a/engines/grim/lua/ldo.cpp
+++ b/engines/grim/lua/ldo.cpp
@@ -6,6 +6,7 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
 #define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
 #define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 #define FORBIDDEN_SYMBOL_EXCEPTION_stderr
 #define FORBIDDEN_SYMBOL_EXCEPTION_exit
 #define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
diff --git a/engines/grim/lua/liolib.cpp b/engines/grim/lua/liolib.cpp
index b017888103a..4cd26b8f614 100644
--- a/engines/grim/lua/liolib.cpp
+++ b/engines/grim/lua/liolib.cpp
@@ -8,6 +8,7 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_fread
 #define FORBIDDEN_SYMBOL_EXCEPTION_fwrite
 #define FORBIDDEN_SYMBOL_EXCEPTION_fseek
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 #define FORBIDDEN_SYMBOL_EXCEPTION_stderr
 #define FORBIDDEN_SYMBOL_EXCEPTION_stdin
 #define FORBIDDEN_SYMBOL_EXCEPTION_stdout
diff --git a/engines/grim/lua/lstrlib.cpp b/engines/grim/lua/lstrlib.cpp
index 8034dc88558..eee8cbff0b7 100644
--- a/engines/grim/lua/lstrlib.cpp
+++ b/engines/grim/lua/lstrlib.cpp
@@ -5,6 +5,7 @@
 
 #define FORBIDDEN_SYMBOL_EXCEPTION_iscntrl
 #define FORBIDDEN_SYMBOL_EXCEPTION_ispunct
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 
 #include "common/util.h"
 
diff --git a/engines/grim/lua/lvm.cpp b/engines/grim/lua/lvm.cpp
index c7279ac44da..3e77db4dc17 100644
--- a/engines/grim/lua/lvm.cpp
+++ b/engines/grim/lua/lvm.cpp
@@ -6,6 +6,7 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
 #define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
 #define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 
 #include "engines/grim/lua/lauxlib.h"
 #include "engines/grim/lua/ldo.h"
diff --git a/engines/grim/lua_v1.cpp b/engines/grim/lua_v1.cpp
index 71b00f0a42d..9273300683e 100644
--- a/engines/grim/lua_v1.cpp
+++ b/engines/grim/lua_v1.cpp
@@ -111,7 +111,7 @@ void Lua_V1::FunctionName() {
 	lua_Object param1 = lua_getparam(1);
 
 	if (!lua_isfunction(param1)) {
-		sprintf(buf, "function InvalidArgsToFunctionName");
+		Common::sprintf_s(buf, "function InvalidArgsToFunctionName");
 		lua_pushstring(buf);
 		return;
 	}
@@ -119,28 +119,29 @@ void Lua_V1::FunctionName() {
 	lua_funcinfo(param1, &filename, &line);
 	switch (*lua_getobjname(param1, &name)) {
 	case 'g':
-		sprintf(buf, "function %.100s", name);
+		Common::sprintf_s(buf, "function %.100s", name);
 		break;
 	case 't':
-		sprintf(buf, "`%.100s' tag method", name);
+		Common::sprintf_s(buf, "`%.100s' tag method", name);
 		break;
 	default:
 		{
 			if (line == 0)
-				sprintf(buf, "main of %.100s", filename);
+				Common::sprintf_s(buf, "main of %.100s", filename);
 			else if (line < 0)
-				sprintf(buf, "%.100s", filename);
+				Common::sprintf_s(buf, "%.100s", filename);
 			else {
-				sprintf(buf, "function (%.100s:%d)", filename, (int)line);
+				Common::sprintf_s(buf, "function (%.100s:%d)", filename, (int)line);
 				filename = nullptr;
 			}
 		}
 	}
 	int curr_line = lua_currentline(param1);
+	size_t pos = strlen(buf);
 	if (curr_line > 0)
-		sprintf(buf + strlen(buf), " at line %d", curr_line);
+		Common::sprintf_s(buf + pos, sizeof(buf) - pos, " at line %d", curr_line);
 	if (filename)
-		sprintf(buf + strlen(buf), " [in file %.100s]", filename);
+		Common::sprintf_s(buf + pos, sizeof(buf) - pos, " [in file %.100s]", filename);
 	lua_pushstring(buf);
 }
 
diff --git a/engines/grim/lua_v1_text.cpp b/engines/grim/lua_v1_text.cpp
index 6b75ef94eb6..ebde640a515 100644
--- a/engines/grim/lua_v1_text.cpp
+++ b/engines/grim/lua_v1_text.cpp
@@ -257,7 +257,7 @@ void Lua_V1::LocalizeString() {
 		// we've been given
 		if (str[0] == '/') {
 			Common::String msg = parseMsgText(str, msgId);
-			sprintf(buf, "/%s/%s", msgId, msg.c_str());
+			Common::sprintf_s(buf, "/%s/%s", msgId, msg.c_str());
 			str = buf;
 		}
 		lua_pushstring(str);


Commit: c93b9981f87878a2356a6e8e5c24236c62661c78
    https://github.com/scummvm/scummvm/commit/c93b9981f87878a2356a6e8e5c24236c62661c78
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
GROOVIE: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/groovie/logic/tlcgame.cpp


diff --git a/engines/groovie/logic/tlcgame.cpp b/engines/groovie/logic/tlcgame.cpp
index cb054f285ba..148bd2d2e5e 100644
--- a/engines/groovie/logic/tlcgame.cpp
+++ b/engines/groovie/logic/tlcgame.cpp
@@ -959,125 +959,125 @@ void TlcGame::tatResultEpisode() {
 	case 0:
 		product = ratioA * 18.0;
 		if (product <= 3) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product - 4);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product - 4);
 		}
 		break;
 
 	case 1:
 		product = ratioA * 13.0;
 		if (product <= 3) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product - 4);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product - 4);
 		}
 		break;
 
 	case 2:
 		product = ratioA * 12.0;
 		if (product <= 3) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product - 4);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product - 4);
 		}
 		break;
 
 	case 3:
 		product = ratioA * 13.0;
 		if (product <= 8) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product - 9);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product - 9);
 		}
 		break;
 
 	case 4:
 		product = ratioA * 11.0;
 		if (product <= 3) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product - 4);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product - 4);
 		}
 		break;
 
 	case 5:
 		product = ratioA * 11.0;
 		if (product >= 4) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product - 4);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product - 4);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product);
 		}
 		break;
 
 	case 6:
 		product = ratioA * 9.0;
 		if (product <= 4) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product - 5);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product - 5);
 		}
 		break;
 
 	case 7:
 		product = ratioA * 10.0;
 		if (product <= 3) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product - 4);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product - 4);
 		}
 		break;
 
 	case 8:
 		product = ratioA * 12.0;
 		if (product <= 4) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product - 5);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product - 5);
 		}
 		break;
 
 	case 9:
 		product = ratioA * 10.0;
-		sprintf(resultStrA, "%cN%02d", idxA + 'A', product);
+		Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product);
 		break;
 
 	case 10:
 		product = ratioA * 7.0;
-		sprintf(resultStrA, "%cN%02d", idxA + 'A', product);
+		Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product);
 		break;
 
 	case 11:
 		product = ratioA * 10.0;
 		if (product >= 4) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product - 4);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product - 4);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product);
 		}
 		break;
 
 	case 12:
 		product = ratioA * 9.0;
 		if (product >= 4) {
-			sprintf(resultStrA, "%cP%02d", idxA + 'A', product - 4);
+			Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product - 4);
 		} else {
-			sprintf(resultStrA, "%cN%02d", idxA + 'A', product);
+			Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product);
 		}
 		break;
 
 	case 13:
 		product = ratioA * 6.0;
-		sprintf(resultStrA, "%cN%02d", idxA + 'A', product);
+		Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product);
 		break;
 
 	case 14:
 		product = ratioA * 7.0;
-		sprintf(resultStrA, "%cP%02d", idxA + 'A', product);
+		Common::sprintf_s(resultStrA, "%cP%02d", idxA + 'A', product);
 		break;
 
 	case 15:
 		product = ratioA * 8.0;
-		sprintf(resultStrA, "%cN%02d", idxA + 'A', product);
+		Common::sprintf_s(resultStrA, "%cN%02d", idxA + 'A', product);
 		break;
 	}
 
@@ -1087,125 +1087,125 @@ void TlcGame::tatResultEpisode() {
 	case 0:
 		product = ratioB * 18.0;
 		if (product <= 3) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product - 4);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product - 4);
 		}
 		break;
 
 	case 1:
 		product = ratioB * 13.0;
 		if (product <= 3) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product - 4);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product - 4);
 		}
 		break;
 
 	case 2:
 		product = ratioB * 12.0;
 		if (product <= 3) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product - 4);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product - 4);
 		}
 		break;
 
 	case 3:
 		product = ratioB * 13.0;
 		if (product <= 8) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product - 9);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product - 9);
 		}
 		break;
 
 	case 4:
 		product = ratioB * 11.0;
 		if (product <= 3) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product - 4);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product - 4);
 		}
 		break;
 
 	case 5:
 		product = ratioB * 11.0;
 		if (product >= 4) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product - 4);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product - 4);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product);
 		}
 		break;
 
 	case 6:
 		product = ratioB * 9.0;
 		if (product <= 4) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product - 5);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product - 5);
 		}
 		break;
 
 	case 7:
 		product = ratioB * 10.0;
 		if (product <= 3) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product - 4);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product - 4);
 		}
 		break;
 
 	case 8:
 		product = ratioB * 12.0;
 		if (product <= 4) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product - 5);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product - 5);
 		}
 		break;
 
 	case 9:
 		product = ratioB * 10.0;
-		sprintf(resultStrB, "%cN%02d", idxB + 'A', product);
+		Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product);
 		break;
 
 	case 10:
 		product = ratioB * 7.0;
-		sprintf(resultStrB, "%cN%02d", idxB + 'A', product);
+		Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product);
 		break;
 
 	case 11:
 		product = ratioB * 10.0;
 		if (product >= 4) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product - 4);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product - 4);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product);
 		}
 		break;
 
 	case 12:
 		product = ratioB * 9.0;
 		if (product >= 4) {
-			sprintf(resultStrB, "%cP%02d", idxB + 'A', product - 4);
+			Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product - 4);
 		} else {
-			sprintf(resultStrB, "%cN%02d", idxB + 'A', product);
+			Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product);
 		}
 		break;
 
 	case 13:
 		product = ratioB * 6.0;
-		sprintf(resultStrB, "%cN%02d", idxB + 'A', product);
+		Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product);
 		break;
 
 	case 14:
 		product = ratioB * 7.0;
-		sprintf(resultStrB, "%cP%02d", idxB + 'A', product);
+		Common::sprintf_s(resultStrB, "%cP%02d", idxB + 'A', product);
 		break;
 
 	case 15:
 		product = ratioB * 8.0;
-		sprintf(resultStrB, "%cN%02d", idxB + 'A', product);
+		Common::sprintf_s(resultStrB, "%cN%02d", idxB + 'A', product);
 		break;
 	}
 


Commit: 8055e2d14c3763e69224ef8f253b89010d2c8794
    https://github.com/scummvm/scummvm/commit/8055e2d14c3763e69224ef8f253b89010d2c8794
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
HDB: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/hdb/ai-bots.cpp
    engines/hdb/gfx.cpp


diff --git a/engines/hdb/ai-bots.cpp b/engines/hdb/ai-bots.cpp
index 4dce905996b..a66f8542175 100644
--- a/engines/hdb/ai-bots.cpp
+++ b/engines/hdb/ai-bots.cpp
@@ -1453,17 +1453,17 @@ void aiLaserInit2(AIEntity *e, int mx, int my) {
 	if (!g_hdb->_ai->_gfxLaserbeamUD[0]) {
 		char name[64];
 		for (int i = 0; i < 4; i++) {
-			sprintf(name, FORCEFIELD_UD"0%d", i + 1);
+			Common::sprintf_s(name, FORCEFIELD_UD"0%d", i + 1);
 			g_hdb->_ai->_gfxLaserbeamUD[i] = g_hdb->_gfx->loadTile(name);
-			sprintf(name, FORCESPLASH_TOP"0%d", i + 1);
+			Common::sprintf_s(name, FORCESPLASH_TOP"0%d", i + 1);
 			g_hdb->_ai->_gfxLaserbeamUDTop[i] = g_hdb->_gfx->loadTile(name);
-			sprintf(name, FORCESPLASH_BTM"0%d", i + 1);
+			Common::sprintf_s(name, FORCESPLASH_BTM"0%d", i + 1);
 			g_hdb->_ai->_gfxLaserbeamUDBottom[i] = g_hdb->_gfx->loadTile(name);
-			sprintf(name, FORCEFIELD_LR"0%d", i + 1);
+			Common::sprintf_s(name, FORCEFIELD_LR"0%d", i + 1);
 			g_hdb->_ai->_gfxLaserbeamLR[i] = g_hdb->_gfx->loadTile(name);
-			sprintf(name, FORCESPLASH_LEFT"0%d", i + 1);
+			Common::sprintf_s(name, FORCESPLASH_LEFT"0%d", i + 1);
 			g_hdb->_ai->_gfxLaserbeamLRLeft[i] = g_hdb->_gfx->loadTile(name);
-			sprintf(name, FORCESPLASH_RIGHT"0%d", i + 1);
+			Common::sprintf_s(name, FORCESPLASH_RIGHT"0%d", i + 1);
 			g_hdb->_ai->_gfxLaserbeamLRRight[i] = g_hdb->_gfx->loadTile(name);
 		}
 	}
@@ -3215,22 +3215,22 @@ void aiDragonInit(AIEntity *e, int mx, int my) {
 	// need to save the dragon's coords and type in the blocking entity for gem-hit-blocking detection
 	AIEntity *block = spawnBlocking(e->tileX - 1, e->tileY, e->level);
 	block->value1 = (int)AI_DRAGON;
-	sprintf(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
+	Common::sprintf_s(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
 	block = spawnBlocking(e->tileX + 1, e->tileY, e->level);
 	block->value1 = (int)AI_DRAGON;
-	sprintf(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
+	Common::sprintf_s(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
 	block = spawnBlocking(e->tileX - 1, e->tileY - 1, e->level);
 	block->value1 = (int)AI_DRAGON;
-	sprintf(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
+	Common::sprintf_s(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
 	block = spawnBlocking(e->tileX + 1, e->tileY - 1, e->level);
 	block->value1 = (int)AI_DRAGON;
-	sprintf(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
+	Common::sprintf_s(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
 	block = spawnBlocking(e->tileX - 1, e->tileY - 2, e->level);
 	block->value1 = (int)AI_DRAGON;
-	sprintf(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
+	Common::sprintf_s(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
 	block = spawnBlocking(e->tileX + 1, e->tileY - 2, e->level);
 	block->value1 = (int)AI_DRAGON;
-	sprintf(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
+	Common::sprintf_s(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY);
 }
 
 void aiDragonInit2(AIEntity *e, int mx, int my) {
diff --git a/engines/hdb/gfx.cpp b/engines/hdb/gfx.cpp
index f46698591e2..b542a9cb81e 100644
--- a/engines/hdb/gfx.cpp
+++ b/engines/hdb/gfx.cpp
@@ -1300,7 +1300,7 @@ void Gfx::drawDebugInfo(Tile *_debugLogo, int fps) {
 	// Draw  FPS
 	setCursor(0, 0);
 	char buff[64];
-	sprintf(buff, "FPS: %d", fps);
+	Common::sprintf_s(buff, "FPS: %d", fps);
 	drawText(buff);
 
 	// Draw Player Info
@@ -1308,22 +1308,22 @@ void Gfx::drawDebugInfo(Tile *_debugLogo, int fps) {
 
 	int x, y;
 	g_hdb->_ai->getPlayerXY(&x, &y);
-	sprintf(buff, "Player X: %d, Y: %d", x / kTileWidth, y / kTileHeight);
+	Common::sprintf_s(buff, "Player X: %d, Y: %d", x / kTileWidth, y / kTileHeight);
 	drawText(buff);
 
 	setCursor(0, 32);
 	AIEntity *p = g_hdb->_ai->getPlayer();
 	if (p) {
-		sprintf(buff, "Player height level: %d", p->level);
+		Common::sprintf_s(buff, "Player height level: %d", p->level);
 		drawText(buff);
 	}
 
 	setCursor(0, 48);
-	sprintf(buff, "Map Name: %s", g_hdb->getInMapName());
+	Common::sprintf_s(buff, "Map Name: %s", g_hdb->getInMapName());
 	drawText(buff);
 
 	setCursor(0, 64);
-	g_hdb->getActionMode() ? sprintf(buff, "Action Mode") : sprintf(buff, "Puzzle Mode");
+	g_hdb->getActionMode() ? Common::sprintf_s(buff, "Action Mode") : Common::sprintf_s(buff, "Puzzle Mode");
 	drawText(buff);
 }
 


Commit: 714ebdd3026f9f3abbfc715bee901e8cecbb05ec
    https://github.com/scummvm/scummvm/commit/714ebdd3026f9f3abbfc715bee901e8cecbb05ec
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
HOPKINS: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/hopkins/computer.cpp


diff --git a/engines/hopkins/computer.cpp b/engines/hopkins/computer.cpp
index 2942625b4d8..6257198a1a8 100644
--- a/engines/hopkins/computer.cpp
+++ b/engines/hopkins/computer.cpp
@@ -923,7 +923,7 @@ void ComputerManager::getScoreName() {
 	_score[scoreLine]._score = "         ";
 
 	char score[16];
-	sprintf(score, "%d", _breakoutScore);
+	Common::sprintf_s(score, "%d", _breakoutScore);
 	int scoreLen = 0;
 	do {
 		++scoreLen;


Commit: 926b7533c50fb08c1e5d89ad2d2eb91b1ad99a2a
    https://github.com/scummvm/scummvm/commit/926b7533c50fb08c1e5d89ad2d2eb91b1ad99a2a
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
HUGO: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/hugo/intro.cpp
    engines/hugo/object.cpp
    engines/hugo/parser.cpp


diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp
index 3185443af82..f415a808efe 100644
--- a/engines/hugo/intro.cpp
+++ b/engines/hugo/intro.cpp
@@ -133,7 +133,7 @@ bool intro_v1d::introPlay() {
 			_font.drawString(&_surf, _vm->getCopyrightString(), 0, 176, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
 
 			if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) {
-				sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib);
+				Common::sprintf_s(buffer, "Distributed by %s.", _vm->_boot._distrib);
 				_font.drawString(&_surf, buffer, 0, 75, 320, _TMAGENTA, Graphics::kTextAlignCenter);
 			}
 
@@ -255,15 +255,15 @@ void intro_v2d::introInit() {
 		error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 8");
 
 	if (_vm->_boot._registered)
-		sprintf(buffer, "%s  Registered Version", _vm->getCopyrightString());
+		Common::sprintf_s(buffer, "%s  Registered Version", _vm->getCopyrightString());
 	else
-		sprintf(buffer, "%s  Shareware Version", _vm->getCopyrightString());
+		Common::sprintf_s(buffer, "%s  Shareware Version", _vm->getCopyrightString());
 
 	_font.drawString(&_surf, buffer, 0, 186, 320, _TLIGHTRED, Graphics::kTextAlignCenter);
 
 	if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) {
 		// TROMAN, size 10-5
-		sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib);
+		Common::sprintf_s(buffer, "Distributed by %s.", _vm->_boot._distrib);
 		_font.drawString(&_surf, buffer, 0, 1, 320, _TLIGHTRED, Graphics::kTextAlignCenter);
 	}
 
@@ -292,9 +292,9 @@ void intro_v3d::introInit() {
 
 	char buffer[128];
 	if (_vm->_boot._registered)
-		sprintf(buffer, "%s  Registered Version", _vm->getCopyrightString());
+		Common::sprintf_s(buffer, "%s  Registered Version", _vm->getCopyrightString());
 	else
-		sprintf(buffer,"%s  Shareware Version", _vm->getCopyrightString());
+		Common::sprintf_s(buffer,"%s  Shareware Version", _vm->getCopyrightString());
 
 	// TROMAN, size 10-5
 	if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8)))
@@ -303,7 +303,7 @@ void intro_v3d::introInit() {
 	_font.drawString(&_surf, buffer, 0, 190, 320, _TBROWN, Graphics::kTextAlignCenter);
 
 	if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) {
-		sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib);
+		Common::sprintf_s(buffer, "Distributed by %s.", _vm->_boot._distrib);
 		_font.drawString(&_surf, buffer, 0, 0, 320, _TBROWN, Graphics::kTextAlignCenter);
 	}
 
diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp
index b59da2f17c8..009dedf4414 100644
--- a/engines/hugo/object.cpp
+++ b/engines/hugo/object.cpp
@@ -139,17 +139,17 @@ void ObjectHandler::useObject(int16 objId) {
 		const char *verb;                                 // Background verb to use directly
 		// Get or use objid directly
 		if ((obj->_genericCmd & TAKE) || obj->_objValue)  // Get collectible item
-			sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_take, 0), _vm->_text->getNoun(obj->_nounIndex, 0));
+			Common::sprintf_s(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_take, 0), _vm->_text->getNoun(obj->_nounIndex, 0));
 		else if (obj->_cmdIndex != 0)                     // Use non-collectible item if able
-			sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(obj->_cmdIndex), 0), _vm->_text->getNoun(obj->_nounIndex, 0));
+			Common::sprintf_s(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(obj->_cmdIndex), 0), _vm->_text->getNoun(obj->_nounIndex, 0));
 		else if ((verb = _vm->_parser->useBG(_vm->_text->getNoun(obj->_nounIndex, 0))) != nullptr)
-			sprintf(_vm->_line, "%s %s", verb, _vm->_text->getNoun(obj->_nounIndex, 0));
+			Common::sprintf_s(_vm->_line, "%s %s", verb, _vm->_text->getNoun(obj->_nounIndex, 0));
 		else
 			return;                                       // Can't use object directly
 	} else {
 		// Use status.objid on objid
 		// Default to first cmd verb
-		sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(_objects[inventObjId]._cmdIndex), 0),
+		Common::sprintf_s(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(_objects[inventObjId]._cmdIndex), 0),
 			                       _vm->_text->getNoun(_objects[inventObjId]._nounIndex, 0),
 			                       _vm->_text->getNoun(obj->_nounIndex, 0));
 
@@ -162,7 +162,7 @@ void ObjectHandler::useObject(int16 objId) {
 				for (Target *target = use->_targets; target->_nounIndex != 0; target++)
 					if (target->_nounIndex == obj->_nounIndex) {
 						foundFl = true;
-						sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(target->_verbIndex, 0),
+						Common::sprintf_s(_vm->_line, "%s %s %s", _vm->_text->getVerb(target->_verbIndex, 0),
 							                       _vm->_text->getNoun(_objects[inventObjId]._nounIndex, 0),
 							                       _vm->_text->getNoun(obj->_nounIndex, 0));
 					}
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index 780137f37be..375b1f50c98 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -264,8 +264,8 @@ void Parser::charHandler() {
 		_cmdLineIndex = strlen(_cmdLine);
 	}
 
-	sprintf(_vm->_statusLine, ">%s%c", _cmdLine, _cmdLineCursor);
-	sprintf(_vm->_scoreLine, "F1-Help  %s  Score: %d of %d Sound %s", (_vm->_config._turboFl) ? "T" : " ", _vm->getScore(), _vm->getMaxScore(), (_vm->_config._soundFl) ? "On" : "Off");
+	Common::sprintf_s(_vm->_statusLine, ">%s%c", _cmdLine, _cmdLineCursor);
+	Common::sprintf_s(_vm->_scoreLine, "F1-Help  %s  Score: %d of %d Sound %s", (_vm->_config._turboFl) ? "T" : " ", _vm->getScore(), _vm->getMaxScore(), (_vm->_config._soundFl) ? "On" : "Off");
 
 	// See if "look" button pressed
 	if (gameStatus._lookFl) {
@@ -393,7 +393,7 @@ void Parser::command(const char *format, ...) {
 
 	va_list marker;
 	va_start(marker, format);
-	vsprintf(_vm->_line, format, marker);
+	Common::vsprintf_s(_vm->_line, format, marker);
 	va_end(marker);
 
 	lineHandler();


Commit: 11b3f7197395fb53e7d9741dfe7dcd514ebc64b5
    https://github.com/scummvm/scummvm/commit/11b3f7197395fb53e7d9741dfe7dcd514ebc64b5
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
ICB: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/icb/actor_view_pc.cpp
    engines/icb/animation_mega_set.cpp
    engines/icb/barriers.cpp
    engines/icb/camera.cpp
    engines/icb/floors.cpp
    engines/icb/fn_icon_functions.cpp
    engines/icb/fn_remora_functions.cpp
    engines/icb/function.cpp
    engines/icb/game_script.cpp
    engines/icb/global_vars.cpp
    engines/icb/icon_menu.cpp
    engines/icb/mission.cpp
    engines/icb/options_manager_pc.cpp
    engines/icb/p4_pc.cpp
    engines/icb/remora_pc.h
    engines/icb/session.cpp
    engines/icb/set_pc.cpp
    engines/icb/speech.cpp
    engines/icb/surface_manager.cpp


diff --git a/engines/icb/actor_view_pc.cpp b/engines/icb/actor_view_pc.cpp
index 8fba1d182e5..3b1137b86a2 100644
--- a/engines/icb/actor_view_pc.cpp
+++ b/engines/icb/actor_view_pc.cpp
@@ -128,7 +128,7 @@ void InitActorView(const char *name, const char *outfit, const char *weapon, con
 	char h_outfit[8];
 	HashFile(outfit, h_outfit);
 	// Make the cluster name
-	sprintf(cluster_name, "\\C\\%s\\%s.OFT", h_character, h_outfit);
+	Common::sprintf_s(cluster_name, "\\C\\%s\\%s.OFT", h_character, h_outfit);
 	// Hash value for this cluster name
 	cluster_name_hash = NULL_HASH;
 
@@ -137,7 +137,7 @@ void InitActorView(const char *name, const char *outfit, const char *weapon, con
 
 	raj_name_hash = NULL_HASH;
 
-	sprintf(raj_name, "%s\\%s.raj", weapon, anim);
+	Common::sprintf_s(raj_name, "%s\\%s.raj", weapon, anim);
 
 	anim_name = const_cast<char *>(anim);
 	weapon_name = const_cast<char *>(weapon);
@@ -159,7 +159,7 @@ void InitActorView(const char *name, const char *outfit, const char *weapon, con
 	char texture_name[128];
 	uint32 texture_name_hash = NULL_HASH;
 
-	sprintf(texture_name, "material.revtex");
+	Common::sprintf_s(texture_name, "material.revtex");
 
 	TextureHandle *texHan = GetRegisteredTexture(texture_name, texture_name_hash, texture_name, texture_name_hash, cluster_name, cluster_name_hash);
 
@@ -183,7 +183,7 @@ void ChangeAnimPlaying(const char *pose, const char *anim, bool8 forwards, int32
 	// Remake raj filename
 	raj_name_hash = NULL_HASH;
 
-	sprintf(raj_name, "%s\\%s.raj", weapon_name, anim);
+	Common::sprintf_s(raj_name, "%s\\%s.raj", weapon_name, anim);
 
 	// Change animation to use
 	anim_name = const_cast<char *>(anim);
@@ -402,10 +402,10 @@ void DrawFrame(const int32 frame) {
 	g_av_actor->truePos.z = 0;
 	g_av_actor->trueRot = g_av_actor->rot;
 
-	sprintf(pose_name, "%s\\pose.rap", weapon_name);
-	sprintf(bone_name, "%s\\%s.rab", weapon_name, anim_name);
-	sprintf(mesh_name, "mesh.rap");
-	sprintf(smesh_name, "mesh_shadow.rap");
+	Common::sprintf_s(pose_name, "%s\\pose.rap", weapon_name);
+	Common::sprintf_s(bone_name, "%s\\%s.rab", weapon_name, anim_name);
+	Common::sprintf_s(mesh_name, "mesh.rap");
+	Common::sprintf_s(smesh_name, "mesh_shadow.rap");
 
 	uint32 mesh_hash = HashString(mesh_name);
 	RapAPI *mesh = (RapAPI *)rs_anims->Res_open(mesh_name, mesh_hash, cluster_name, cluster_name_hash);
diff --git a/engines/icb/animation_mega_set.cpp b/engines/icb/animation_mega_set.cpp
index baead831ac0..589042f80fd 100644
--- a/engines/icb/animation_mega_set.cpp
+++ b/engines/icb/animation_mega_set.cpp
@@ -183,7 +183,7 @@ void _vox_image::___init(const char *chr, const char *set, __weapon weapon) {
 	HashFile(set, set_hash);
 
 	// Make the cluster name "\c\<#character>\<#outfit>\outfit.clu"
-	len = sprintf(base_path, CHR_PATH, chr_hash, set_hash);
+	len = Common::sprintf_s(base_path, CHR_PATH, chr_hash, set_hash);
 	if (len > BASE_PATH_STR_LEN)
 		Fatal_error("_vox_image::___init base_path string too long");
 	base_path_hash = NULL_HASH;
@@ -192,15 +192,15 @@ void _vox_image::___init(const char *chr, const char *set, __weapon weapon) {
 
 	// In the clustered version the image path is the path inside the cluster
 
-	len = sprintf(image_path, "%s\\", weapon_text[weapon]);
+	len = Common::sprintf_s(image_path, "%s\\", weapon_text[weapon]);
 	if (len > IMAGE_PATH_STR_LEN)
 		Fatal_error("_vox_image::___init image_path [%s] string too long", image_path);
 
-	len = sprintf(shadow_mesh_name, "%s", "mesh_shadow.rap");
+	len = Common::sprintf_s(shadow_mesh_name, "%s", "mesh_shadow.rap");
 	if (len > IMAGE_PATH_STR_LEN)
 		Fatal_error("_vox_image::___init shadow_mesh_name [%s] string too long", shadow_mesh_name);
 
-	len = sprintf(pose_name, "%s\\pose.rap", weapon_text[weapon]);
+	len = Common::sprintf_s(pose_name, "%s\\pose.rap", weapon_text[weapon]);
 	if (len > IMAGE_PATH_STR_LEN)
 		Fatal_error("_vox_image::___init pose_name [%s] string too long", pose_name);
 
@@ -283,20 +283,20 @@ bool8 _vox_image::Init_custom_animation(const char *anim) {
 	if (custom == FALSE8 /*__NONE*/) {
 // custom must be in the current weapon set - bah, shouldnt have done it like this - its daft
 		// rav (or equiverlant always come from pcp directory...
-		len = sprintf(custom_image_path_rav, "%s\\", weapon_text[MS->Fetch_cur_megas_pose()]);
+		len = Common::sprintf_s(custom_image_path_rav, "%s\\", weapon_text[MS->Fetch_cur_megas_pose()]);
 
 		// rai (or equiverlant always come from base path...
-		len = sprintf(custom_image_path_rai, "%s\\", weapon_text[MS->Fetch_cur_megas_pose()]);
+		len = Common::sprintf_s(custom_image_path_rai, "%s\\", weapon_text[MS->Fetch_cur_megas_pose()]);
 
 		// pose mesh name
-		len = sprintf(custom_pose_name, "%s\\pose.rap", weapon_text[MS->Fetch_cur_megas_pose()]);
+		len = Common::sprintf_s(custom_pose_name, "%s\\pose.rap", weapon_text[MS->Fetch_cur_megas_pose()]);
 
 		custom_pose_hash = HashString(custom_pose_name);
 	} else {
 // we have specified a custom type - i.e. the anim is not part of the current weapon set, but instead sits parallel to weapon directory
-		len = sprintf(custom_image_path_rav, "%s\\", MS->Fetch_cur_megas_custom_text());
-		len = sprintf(custom_image_path_rai, "%s\\", MS->Fetch_cur_megas_custom_text());
-		len = sprintf(custom_pose_name, "%s\\pose.rap", MS->Fetch_cur_megas_custom_text());
+		len = Common::sprintf_s(custom_image_path_rav, "%s\\", MS->Fetch_cur_megas_custom_text());
+		len = Common::sprintf_s(custom_image_path_rai, "%s\\", MS->Fetch_cur_megas_custom_text());
+		len = Common::sprintf_s(custom_pose_name, "%s\\pose.rap", MS->Fetch_cur_megas_custom_text());
 
 		if (len > 128)
 			Fatal_error("Init_custom_animation string error");
@@ -304,13 +304,13 @@ bool8 _vox_image::Init_custom_animation(const char *anim) {
 
 	}
 
-	len = sprintf(anim_name[__NON_GENERIC], "%s%s.rab", (const char *)custom_image_path_rav, (const char *)anim);
+	len = Common::sprintf_s(anim_name[__NON_GENERIC], "%s%s.rab", (const char *)custom_image_path_rav, (const char *)anim);
 
 	if (len > ANIM_NAME_STR_LEN)
 		Fatal_error("Init_custom_animation string error");
 	anim_name_hash[__NON_GENERIC] = HashString(anim_name[__NON_GENERIC]);
 
-	len = sprintf(info_name[__NON_GENERIC], "%s%s.raj", (const char *)custom_image_path_rai, (const char *)anim);
+	len = Common::sprintf_s(info_name[__NON_GENERIC], "%s%s.raj", (const char *)custom_image_path_rai, (const char *)anim);
 	if (len > ANIM_NAME_STR_LEN)
 		Fatal_error("Init_custom_animation string error");
 	info_name_hash[__NON_GENERIC] = HashString(info_name[__NON_GENERIC]);
@@ -406,7 +406,7 @@ void PreRegisterTexture(const char *, uint32, const char *, uint32, const char *
 bool8 _vox_image::Set_texture(const char *tex_name) {
 	int32 len;
 
-	len = sprintf(texture_name, "%s.revtex", tex_name);
+	len = Common::sprintf_s(texture_name, "%s.revtex", tex_name);
 
 	if (len > IMAGE_PATH_STR_LEN)
 		Fatal_error("_vox_image::Set_texture [%s] string too long", tex_name);
@@ -431,7 +431,7 @@ bool8 _vox_image::Set_mesh(const char *m_name) {
 	Common::strcpy_s(name, m_name);
 	Common::strcat_s(name, ".rap");
 
-	len = sprintf(mesh_name, "%s", name);
+	len = Common::sprintf_s(mesh_name, "%s", name);
 	if (len > IMAGE_PATH_STR_LEN)
 		Fatal_error("_vox_image::___init mesh_name [%s] string too long", mesh_name);
 
@@ -448,7 +448,7 @@ bool8 _vox_image::Set_palette(const char *pal_name) {
 
 	int32 len;
 
-	len = sprintf(palette_name, "%s.revtex", pal_name);
+	len = Common::sprintf_s(palette_name, "%s.revtex", pal_name);
 
 	if (len > IMAGE_PATH_STR_LEN)
 		Fatal_error("_vox_image::Set_palette [%s] string too long", pal_name);
@@ -462,7 +462,7 @@ bool8 _vox_image::Set_palette(const char *pal_name) {
 }
 
 bool8 _vox_image::Set_override_pose(const char *p_name) {
-	int len = sprintf(override_pose_name, "%s\\pose.rap", p_name);
+	int len = Common::sprintf_s(override_pose_name, "%s\\pose.rap", p_name);
 
 	if (len > IMAGE_PATH_STR_LEN)
 		Fatal_error("_vox_image::Set_override_pose [%s] string too long", override_pose_name);
@@ -484,7 +484,7 @@ bool8 _vox_image::Cancel_override_pose() {
 // Return 1 - file is in memory
 int _vox_image::Preload_file(const char *file) {
 	char file_name[ENGINE_STRING_LEN];
-	int len = sprintf(file_name, "%s", file);
+	int len = Common::sprintf_s(file_name, "%s", file);
 
 	if (len > IMAGE_PATH_STR_LEN)
 		Fatal_error("_vox_image::Preload_file [%s] string too long", file_name);
diff --git a/engines/icb/barriers.cpp b/engines/icb/barriers.cpp
index b3294394494..8cf9f7eabf6 100644
--- a/engines/icb/barriers.cpp
+++ b/engines/icb/barriers.cpp
@@ -496,7 +496,7 @@ void _barrier_handler::___init() {
 
 	// load the raw barrier file for this session
 	// When clustered the session files have the base stripped
-	len = sprintf(temp_buf, "%s", PX_FILENAME_BARRIERLIST);
+	len = Common::sprintf_s(temp_buf, "%s", PX_FILENAME_BARRIERLIST);
 	if (len > ENGINE_STRING_LEN)
 		Fatal_error("_barrier_handler::___init string len error");
 
@@ -513,7 +513,7 @@ void _barrier_handler::___init() {
 
 	// load in the routing wrapper
 	// When clustered the session files have the base stripped
-	len = sprintf(temp_buf, "%s", PX_FILENAME_ROUTING);
+	len = Common::sprintf_s(temp_buf, "%s", PX_FILENAME_ROUTING);
 	if (len > ENGINE_STRING_LEN)
 		Fatal_error("_barrier_handler::___init string len error");
 
diff --git a/engines/icb/camera.cpp b/engines/icb/camera.cpp
index 6d07b45962d..4ce2b990b5f 100644
--- a/engines/icb/camera.cpp
+++ b/engines/icb/camera.cpp
@@ -496,7 +496,7 @@ mcodeFunctionReturnCodes _game_session::fn_switch_to_manual_camera(int32 &, int3
 
 	manual_camera = TRUE8;
 
-	len = sprintf(manual_camera_name, "%s\\pc\\%s", room_name, camera_name);
+	len = Common::sprintf_s(manual_camera_name, "%s\\pc\\%s", room_name, camera_name);
 	if (len > ENGINE_STRING_LEN)
 		Fatal_error("fn_switch_to_manual_camera string len error");
 
@@ -538,7 +538,7 @@ mcodeFunctionReturnCodes _game_session::fn_is_current_location(int32 &result, in
 
 	Message_box("is %s current location?", location_name);
 
-	len = sprintf(manual_camera_name, "%s\\pc\\%s", location_name, set.GetSetName());
+	len = Common::sprintf_s(manual_camera_name, "%s\\pc\\%s", location_name, set.GetSetName());
 	if (len > ENGINE_STRING_LEN)
 		Fatal_error("fn_is_current_location string len error");
 
diff --git a/engines/icb/floors.cpp b/engines/icb/floors.cpp
index 9e726bedbf5..c9dc86d6ac1 100644
--- a/engines/icb/floors.cpp
+++ b/engines/icb/floors.cpp
@@ -55,7 +55,7 @@ void _floor_world::___init() {
 
 	// load the file for this session
 	// When clustered the session files have the base stripped
-	len = sprintf(temp_buf, "%s", PX_FILENAME_FLOOR_MAP);
+	len = Common::sprintf_s(temp_buf, "%s", PX_FILENAME_FLOOR_MAP);
 	if (len > ENGINE_STRING_LEN)
 		Fatal_error("_floor_world::___init string len error");
 
diff --git a/engines/icb/fn_icon_functions.cpp b/engines/icb/fn_icon_functions.cpp
index cd4fdf70d78..c769b42dc0b 100644
--- a/engines/icb/fn_icon_functions.cpp
+++ b/engines/icb/fn_icon_functions.cpp
@@ -127,7 +127,7 @@ mcodeFunctionReturnCodes _game_session::fn_add_inventory_item(int32 &, int32 *pa
 	g_oIconListManager->AddIconToList(ICON_LIST_INVENTORY, item_name);
 
 	// Preload the icon for PSX smoothing.
-	sprintf(pcIconPath, ICON_PATH);
+	Common::sprintf_s(pcIconPath, ICON_PATH);
 	g_oIconMenu->PreloadIcon(pcIconPath, item_name);
 
 	// Calling script can continue.
@@ -166,7 +166,7 @@ mcodeFunctionReturnCodes _game_session::fn_add_medipacks(int32 &result, int32 *p
 	player.AddMediPacks(1, bFlashIcons);
 
 	// Preload the icon for PSX smoothing.
-	sprintf(pcIconPath, ICON_PATH);
+	Common::sprintf_s(pcIconPath, ICON_PATH);
 	g_oIconMenu->PreloadIcon(pcIconPath, ARMS_HEALTH_NAME);
 	// Calling script can continue.
 
@@ -212,7 +212,7 @@ mcodeFunctionReturnCodes _game_session::fn_add_ammo_clips(int32 &result, int32 *
 	}
 
 	// Preload the icon for PSX smoothing.
-	sprintf(pcIconPath, ICON_PATH);
+	Common::sprintf_s(pcIconPath, ICON_PATH);
 	g_oIconMenu->PreloadIcon(pcIconPath, ARMS_AMMO_NAME);
 
 	// Calling script can continue.
@@ -237,7 +237,7 @@ mcodeFunctionReturnCodes _game_session::fn_add_icon_to_icon_list(int32 &, int32
 	g_oIconListManager->AddIconToList(list_name, icon_name);
 
 	// Preload the icon for PSX smoothing.
-	sprintf(pcIconPath, ICON_PATH);
+	Common::sprintf_s(pcIconPath, ICON_PATH);
 	g_oIconMenu->PreloadIcon(pcIconPath, icon_name);
 
 	// Calling script can continue.
diff --git a/engines/icb/fn_remora_functions.cpp b/engines/icb/fn_remora_functions.cpp
index a7ca10b42b1..8f0d9833d8a 100644
--- a/engines/icb/fn_remora_functions.cpp
+++ b/engines/icb/fn_remora_functions.cpp
@@ -211,7 +211,7 @@ mcodeFunctionReturnCodes _game_session::fn_remora_add_icon(int32 &, int32 *param
 	g_oIconListManager->AddIconToList(ICON_LIST_REMORA, icon_name);
 
 	// Preload the icon for PSX smoothing.
-	sprintf(pcIconPath, ICON_PATH);
+	Common::sprintf_s(pcIconPath, ICON_PATH);
 	g_oIconMenu->PreloadIcon(pcIconPath, icon_name);
 
 	// Calling script can continue.
diff --git a/engines/icb/function.cpp b/engines/icb/function.cpp
index ca50c136e60..2858bcb888c 100644
--- a/engines/icb/function.cpp
+++ b/engines/icb/function.cpp
@@ -351,7 +351,7 @@ mcodeFunctionReturnCodes _game_session::fn_test(int32 & /*result*/, int32 * /*pa
 #if 0
 	char buf[256];
 
-	sprintf(buf, "z_%s.txt", object->GetName());
+	Common::sprintf_s(buf, "z_%s.txt", object->GetName());
 
 	if (params[0] < 256)
 		Tdebug(buf, "%d", params[0]);
@@ -1624,9 +1624,9 @@ mcodeFunctionReturnCodes _game_session::fn_message_var(int32 &, int32 *params) {
 	char txt[100];
 
 	if (CGameObject::IsVariableString(object, var))
-		sprintf(txt, "%s=\"%s\"", var_name, CGameObject::GetStringVariable(object, var));
+		Common::sprintf_s(txt, "%s=\"%s\"", var_name, CGameObject::GetStringVariable(object, var));
 	else
-		sprintf(txt, "%s=%d", var_name, CGameObject::GetIntegerVariable(object, var));
+		Common::sprintf_s(txt, "%s=%d", var_name, CGameObject::GetIntegerVariable(object, var));
 
 	Message_box(txt);
 
diff --git a/engines/icb/game_script.cpp b/engines/icb/game_script.cpp
index 6d52a19ab1c..f1fd06b2afc 100644
--- a/engines/icb/game_script.cpp
+++ b/engines/icb/game_script.cpp
@@ -57,8 +57,8 @@ bool8 _game_script::Init_game_script() {
 
 	// build name
 
-	sprintf(fname, GAMESCRIPT_PATH);
-	sprintf(cluster, GLOBAL_CLUSTER_PATH);
+	Common::sprintf_s(fname, GAMESCRIPT_PATH);
+	Common::sprintf_s(cluster, GLOBAL_CLUSTER_PATH);
 	fn_hash = HashString(fname);
 	cluster_hash = HashString(cluster);
 
diff --git a/engines/icb/global_vars.cpp b/engines/icb/global_vars.cpp
index ee8019ce768..7d5a849329c 100644
--- a/engines/icb/global_vars.cpp
+++ b/engines/icb/global_vars.cpp
@@ -67,8 +67,8 @@ void Init_globals() {
 	uint32 i;
 	uint32 nVars = 0;
 
-	sprintf(buf, GLOBAL_VAR_PATH);
-	sprintf(cluster, GLOBAL_CLUSTER_PATH);
+	Common::sprintf_s(buf, GLOBAL_VAR_PATH);
+	Common::sprintf_s(cluster, GLOBAL_CLUSTER_PATH);
 	uint32 fn_hash = HashString(buf);
 	uint32 cluster_hash = HashString(cluster);
 
diff --git a/engines/icb/icon_menu.cpp b/engines/icb/icon_menu.cpp
index 35d48f509e5..c3fe77f205d 100644
--- a/engines/icb/icon_menu.cpp
+++ b/engines/icb/icon_menu.cpp
@@ -309,7 +309,7 @@ void _icon_menu::PreloadIcon(const char *pcIconPath, const char *pcIconName) {
 
 	// Make the full URL for the icon.
 	char pcFullIconName[MAXLEN_URL];
-	sprintf(pcFullIconName, "%s%s.%s", pcIconPath, pcIconName, PX_BITMAP_EXT);
+	Common::sprintf_s(pcFullIconName, "%s%s.%s", pcIconPath, pcIconName, PX_BITMAP_EXT);
 
 	// Open the icon resource.
 	nFullIconNameHash = NULL_HASH;
diff --git a/engines/icb/mission.cpp b/engines/icb/mission.cpp
index 0b257955dc1..a13d99d21cc 100644
--- a/engines/icb/mission.cpp
+++ b/engines/icb/mission.cpp
@@ -130,7 +130,7 @@ bool8 Setup_new_mission(const char *mission_name, const char *session_name) {
 		h_session_name[i] = (char)tolower(h_session_name[i]);
 	}
 
-	sprintf(temp_buf, SESSION_TEST_PATH, h_mission_name, h_session_name);
+	Common::sprintf_s(temp_buf, SESSION_TEST_PATH, h_mission_name, h_session_name);
 
 #if 1 // was #ifdef FROM_PC_CD
 	// Need the mission data present on hard-disk for it to destruct properly
diff --git a/engines/icb/options_manager_pc.cpp b/engines/icb/options_manager_pc.cpp
index bc8ba341542..468a033c467 100644
--- a/engines/icb/options_manager_pc.cpp
+++ b/engines/icb/options_manager_pc.cpp
@@ -149,12 +149,12 @@ void InitialiseGlobalColours() {
 
 void MakeFullSaveFilename(uint32 slot_id, char *buff) {
 	// Construct full actual filename
-	sprintf(buff, "saves/ICBgame%02d.index", slot_id);
+	Common::sprintf_s(buff, 128, "saves/ICBgame%02d.index", slot_id);
 }
 
 void MakeFullThumbFilename(uint32 slot_id, char *buff) {
 	// Construct full actual filename
-	sprintf(buff, "saves/ICBgame%02d.thumb", slot_id);
+	Common::sprintf_s(buff, 128, "saves/ICBgame%02d.thumb", slot_id);
 }
 
 void InitialiseMovieLibrary() {
@@ -326,9 +326,9 @@ void LoadAMovieShot(uint32 slot_id, uint32 to_surface_id) {
 
 	// Make the correct filename for this pic when clustered up
 	if (slot_id < 10)
-		sprintf(thbFile, "images\\pc\\movie0%d.thb", slot_id);
+		Common::sprintf_s(thbFile, "images\\pc\\movie0%d.thb", slot_id);
 	else
-		sprintf(thbFile, "images\\pc\\movie%d.thb", slot_id);
+		Common::sprintf_s(thbFile, "images\\pc\\movie%d.thb", slot_id);
 
 	uint32 fo, fs;
 
@@ -340,7 +340,7 @@ void LoadAMovieShot(uint32 slot_id, uint32 to_surface_id) {
 	}
 
 	// Set this up for resman and open the thb file
-	sprintf(art2DCluster, ICON_CLUSTER_PATH);
+	Common::sprintf_s(art2DCluster, ICON_CLUSTER_PATH);
 	uint8 *data = (uint8 *)rs1->Res_open(thbFile, thbFileHash, art2DCluster, art2DClusterHash);
 
 	// First off, check the thumb surface is valid
@@ -737,7 +737,7 @@ void OptionsManager::StartGameOverOptions() {
 	if (g_missionNumber < 9)
 		ds = GetDeathText();
 
-	sprintf(deathSpeech, "player_death%d", ds);
+	Common::sprintf_s(deathSpeech, "player_death%d", ds);
 
 	SayLineOfSpeech(HashString(deathSpeech));
 
@@ -4802,7 +4802,7 @@ void OptionsManager::DrawVideoSettings() {
 		temp = CalculateStringWidth(msg);
 		DisplayText(ad, pitch, msg, halfScreen - temp - 10, hite, (m_VIDEO_selected == FRAMELIMITER) ? SELECTEDFONT : NORMALFONT, FALSE8);
 		char msg2[6];
-		sprintf(msg2, "%d%%", g_stub->cycle_speed);
+		Common::sprintf_s(msg2, "%d%%", g_stub->cycle_speed);
 		DisplayText(ad, pitch, msg2, halfScreen, hite, NORMALFONT, FALSE8);
 	}
 
@@ -5591,7 +5591,7 @@ const char *OptionsManager::GetTextFromReference(uint32 hashRef) {
 }
 
 void OptionsManager::LoadBitmapFont() {
-	sprintf(m_fontName, FONT_PATH, OPTIONS_FONT_NAME);
+	Common::sprintf_s(m_fontName, FONT_PATH, OPTIONS_FONT_NAME);
 	uint32 hashedname = NULL_HASH;
 
 	pxString font_cluster = FONT_CLUSTER_PATH;
@@ -5606,14 +5606,14 @@ void OptionsManager::LoadBitmapFont() {
 void OptionsManager::LoadGlobalTextFile() {
 	// Set this up for resman
 	char globalClusterFile[MAXLEN_CLUSTER_URL];
-	sprintf(globalClusterFile, GLOBAL_CLUSTER_PATH);
+	Common::sprintf_s(globalClusterFile, GLOBAL_CLUSTER_PATH);
 	uint32 globalClusterHash = NULL_HASH;
 
 	char textFileName[100];
 	uint32 buf_hash = NULL_HASH;
 
 	// Has a language been specified
-	sprintf(textFileName, GLOBAL_TEXT_FILE);
+	Common::sprintf_s(textFileName, GLOBAL_TEXT_FILE);
 
 	// Special text loading code so the translators can test their stuff
 
@@ -6001,8 +6001,8 @@ void OptionsManager::DoCredits() {
 		char textFileName[128];
 		char movieFileName[128];
 
-		sprintf(textFileName, "%s.crd", gamelanguage);
-		sprintf(movieFileName, "gmovies\\title.bik");
+		Common::sprintf_s(textFileName, "%s.crd", gamelanguage);
+		Common::sprintf_s(movieFileName, "gmovies\\title.bik");
 
 		// Free the sequence manager
 		UnloadTitleScreenMovie();
@@ -6044,9 +6044,9 @@ void OptionsManager::DoScrollingText() {
 bool8 IsAValidSlide(uint32 num, char *slideFile) {
 	// Make the correct filename for this pic when clustered up
 	if (num < 10)
-		sprintf(slideFile, "images\\pc\\slide_0%d.bink", num);
+		Common::sprintf_s(slideFile, 128, "images\\pc\\slide_0%d.bink", num);
 	else
-		sprintf(slideFile, "images\\pc\\slide_%d.bink", num);
+		Common::sprintf_s(slideFile, 128, "images\\pc\\slide_%d.bink", num);
 
 	uint32 fo, fs;
 
@@ -6175,7 +6175,7 @@ void OptionsManager::DrawSlideShow() {
 			Fatal_error("Trying to display a non-existent slide image!");
 
 		// Set this up for resman and open the thb file
-		sprintf(art2DCluster, ICON_CLUSTER_PATH);
+		Common::sprintf_s(art2DCluster, ICON_CLUSTER_PATH);
 
 		uint8 *slideptr = rs1->Res_open(slideFile, slideFileHash, art2DCluster, art2DClusterHash);
 		uint32 slideLen = rs_bg->Fetch_size(slideFile, slideFileHash, art2DCluster, art2DClusterHash);
@@ -6286,10 +6286,10 @@ void LoadLogo(uint32 to_surface_id) {
 	uint32 art2DClusterHash = NULL_HASH;
 
 	// Make the correct filename for this pic when clustered up
-	sprintf(thbFile, "images\\pc\\binklogo.thb");
+	Common::sprintf_s(thbFile, "images\\pc\\binklogo.thb");
 
 	// Set this up for resman and open the thb file
-	sprintf(art2DCluster, ICON_CLUSTER_PATH);
+	Common::sprintf_s(art2DCluster, ICON_CLUSTER_PATH);
 	uint8 *data = (uint8 *)rs1->Res_open(thbFile, thbFileHash, art2DCluster, art2DClusterHash);
 
 	// First off, check the thumb surface is valid
@@ -6358,7 +6358,7 @@ void Crediter::Initialise(const char *textFileName, const char *movieFileName, b
 
 	// Set this up for resman and open the file
 	char globalClusterFile[MAXLEN_CLUSTER_URL];
-	sprintf(globalClusterFile, GLOBAL_CLUSTER_PATH);
+	Common::sprintf_s(globalClusterFile, GLOBAL_CLUSTER_PATH);
 	uint32 globalClusterHash = NULL_HASH;
 	uint32 buf_hash = NULL_HASH;
 
diff --git a/engines/icb/p4_pc.cpp b/engines/icb/p4_pc.cpp
index f1fa80e6e19..222dc751572 100644
--- a/engines/icb/p4_pc.cpp
+++ b/engines/icb/p4_pc.cpp
@@ -101,9 +101,9 @@ void ReadConfigFromIniFile() {
 	uint32 temp;
 
 	if (g_icb->getGameType() == GType_ICB)
-		sprintf(configFile, "engine\\icb.ini");
+		Common::sprintf_s(configFile, "engine\\icb.ini");
 	else if (g_icb->getGameType() == GType_ELDORADO)
-		sprintf(configFile, "engine\\eldorado.ini");
+		Common::sprintf_s(configFile, "engine\\eldorado.ini");
 	else
 		assert(false);
 
@@ -171,7 +171,7 @@ void Save_config_file() {
 		// Only write a setting when it's been achieved
 		if (g_movieLibrary[i].visible) {
 			char temp[1024];
-			sprintf(temp, "%X", HashString(g_movieLibrary[i].filename));
+			Common::sprintf_s(temp, "%X", HashString(g_movieLibrary[i].filename));
 			Common::String movie = Common::String("movie_") + temp;
 			ConfMan.setBool(movie, true);
 		}
diff --git a/engines/icb/remora_pc.h b/engines/icb/remora_pc.h
index 12d37104d3d..08c342bcf5c 100644
--- a/engines/icb/remora_pc.h
+++ b/engines/icb/remora_pc.h
@@ -146,7 +146,7 @@ inline uint32 GetPen(uint8 nPalette, int32 eCI, uint8 nAlpha = 255) {
 inline const char *_remora::MakeRemoraGraphicsPath(const char *pcBitmapName) const {
 	static char pcRemoraGraphicsPath[MAXLEN_URL];
 
-	sprintf(pcRemoraGraphicsPath, REMORA_GRAPHICS_PATH);
+	Common::sprintf_s(pcRemoraGraphicsPath, REMORA_GRAPHICS_PATH);
 	Common::strcat_s(pcRemoraGraphicsPath, pcBitmapName);
 	Common::strcat_s(pcRemoraGraphicsPath, ".");
 	Common::strcat_s(pcRemoraGraphicsPath, PX_BITMAP_EXT);
diff --git a/engines/icb/session.cpp b/engines/icb/session.cpp
index c9ab4688b13..d725f66fcce 100644
--- a/engines/icb/session.cpp
+++ b/engines/icb/session.cpp
@@ -106,16 +106,16 @@ void _game_session::___init(const char *mission, const char *new_session_name) {
 	char h_mission_name[8];
 	HashFile(mission, h_mission_name);
 
-	sprintf(speech_font_one, FONT_PATH, "font.pcfont");
-	sprintf(remora_font, FONT_PATH, "futura.pcfont");
+	Common::sprintf_s(speech_font_one, FONT_PATH, "font.pcfont");
+	Common::sprintf_s(remora_font, FONT_PATH, "futura.pcfont");
 
-	if (sprintf(session_name, "%s\\%s\\", mission, new_session_name) > ENGINE_STRING_LEN)
+	if (Common::sprintf_s(session_name, "%s\\%s\\", mission, new_session_name) > ENGINE_STRING_LEN)
 		Fatal_error("_game_session::_game_session [%s] string overflow", session_name);
 
-	if (sprintf(h_session_name, "%s\\%s", h_mission_name, session_h_name) > ENGINE_STRING_LEN)
+	if (Common::sprintf_s(h_session_name, "%s\\%s", h_mission_name, session_h_name) > ENGINE_STRING_LEN)
 		Fatal_error("_game_session::_game_session [%s] string overflow", h_session_name);
 
-	if (sprintf(session_cluster, SESSION_CLUSTER_PATH, h_mission_name, session_h_name) > ENGINE_STRING_LEN)
+	if (Common::sprintf_s(session_cluster, SESSION_CLUSTER_PATH, h_mission_name, session_h_name) > ENGINE_STRING_LEN)
 		Fatal_error("_game_session::_game_session [%s] string overflow", session_cluster);
 
 	session_cluster_hash = HashString(session_cluster);
@@ -266,7 +266,7 @@ void _game_session::___init(const char *mission, const char *new_session_name) {
 
 	uint32 global_cluster_hash = HashString(global_cluster);
 
-	sprintf(textFileName, GLOBAL_TEXT_FILE);
+	Common::sprintf_s(textFileName, GLOBAL_TEXT_FILE);
 
 	buf_hash = HashString(textFileName);
 
diff --git a/engines/icb/set_pc.cpp b/engines/icb/set_pc.cpp
index c973ff732e4..735d53b01f7 100644
--- a/engines/icb/set_pc.cpp
+++ b/engines/icb/set_pc.cpp
@@ -601,7 +601,7 @@ bool8 _set::Init(const char *camera_name, const char *clustered_camera_name) {
 	Reset();
 
 	// Create the new set cluster path
-	sprintf(set_cluster, SET_PATH, MS->Fetch_h_session_name(), clustered_camera_name);
+	Common::sprintf_s(set_cluster, SET_PATH, MS->Fetch_h_session_name(), clustered_camera_name);
 	set_cluster_hash = HashString(set_cluster);
 
 	// And the name of the set file within the cluster
@@ -649,7 +649,7 @@ void _set::Reset() {
 bool8 _set::DoesCameraExist(const char * /*camera_name*/, const char *camera_cluster_name) {
 	// Compute the set_cluster name, which is:
 	// <#mission>/<#session>/<#camera_name>.clu
-	sprintf(set_cluster, SET_PATH, MS->Fetch_h_session_name(), camera_cluster_name);
+	Common::sprintf_s(set_cluster, SET_PATH, MS->Fetch_h_session_name(), camera_cluster_name);
 	set_cluster_hash = HashString(set_cluster);
 
 	pxString rvcam = "p.rcvf";
diff --git a/engines/icb/speech.cpp b/engines/icb/speech.cpp
index 63fb148889e..7474c8b292d 100644
--- a/engines/icb/speech.cpp
+++ b/engines/icb/speech.cpp
@@ -162,7 +162,7 @@ mcodeFunctionReturnCodes _game_session::fn_request_speech(int32 &result, int32 *
 
 	// find the speech script
 	// form name of speech script
-	sprintf(temp_buf, "scenes::%s", scene_script_name);
+	Common::sprintf_s(temp_buf, "scenes::%s", scene_script_name);
 
 	S.script_pc = (char *)LinkedDataObject::Try_fetch_item_by_name(scripts, temp_buf); // run init script
 
@@ -1088,7 +1088,7 @@ mcodeFunctionReturnCodes _game_session::speak_new_menu(int32 &, int32 *) {
 
 	g_oIconListManager->ResetList(menu_name_list[menu_number]);
 
-	sprintf(menu_name_list[menu_number], "m%02d", menu_number); // create a unique name
+	Common::sprintf_s(menu_name_list[menu_number], "m%02d", menu_number); // create a unique name
 	choosing[menu_number] = FALSE8;
 	item_count[menu_number] = 0;
 
diff --git a/engines/icb/surface_manager.cpp b/engines/icb/surface_manager.cpp
index 2cf785014cb..177ecb8cf62 100644
--- a/engines/icb/surface_manager.cpp
+++ b/engines/icb/surface_manager.cpp
@@ -101,7 +101,7 @@ void _surface_manager::PrintTimer(char label, uint32 time, uint32 limit) {
 		if (percIndex > 5)
 			percIndex = 5;
 		char message[64];
-		sprintf(message, "%c%3.1f", label, perc);
+		Common::sprintf_s(message, "%c%3.1f", label, perc);
 		/*      Get_surface_DC( working_buffer_id, dc );
 		        SetBkColor( dc, colours[percIndex] );
 		        SetTextColor( dc, 0x01010101 );


Commit: dbe47a28ba1e74001f91ad5408977d25735acc87
    https://github.com/scummvm/scummvm/commit/dbe47a28ba1e74001f91ad5408977d25735acc87
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
KYRA: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/kyra/engine/kyra_hof.cpp
    engines/kyra/engine/kyra_v1.cpp
    engines/kyra/gui/gui_hof.cpp
    engines/kyra/gui/gui_lol.cpp
    engines/kyra/resource/resource_intern.cpp
    engines/kyra/script/script_hof.cpp


diff --git a/engines/kyra/engine/kyra_hof.cpp b/engines/kyra/engine/kyra_hof.cpp
index fab81e38fd2..425074f6dd4 100644
--- a/engines/kyra/engine/kyra_hof.cpp
+++ b/engines/kyra/engine/kyra_hof.cpp
@@ -1412,7 +1412,7 @@ void KyraEngine_HoF::openTalkFile(int newFile) {
 void KyraEngine_HoF::snd_playVoiceFile(int id) {
 	char vocFile[9];
 	assert(id >= 0 && id <= 9999999);
-	sprintf(vocFile, "%07d", id);
+	Common::sprintf_s(vocFile, "%07d", id);
 	if (_sound->isVoicePresent(vocFile)) {
 		// Unlike the original I have added a timeout here. I have chosen a size that makes sure that it
 		// won't get triggered in bug #11309 or similiar situations, but still avoids infinite hangups
diff --git a/engines/kyra/engine/kyra_v1.cpp b/engines/kyra/engine/kyra_v1.cpp
index f027738331d..be0bda4e691 100644
--- a/engines/kyra/engine/kyra_v1.cpp
+++ b/engines/kyra/engine/kyra_v1.cpp
@@ -264,7 +264,7 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
 					breakLoop = true;
 				} else {
 					char savegameName[14];
-					sprintf(savegameName, "Quicksave %d", event.kbd.keycode - Common::KEYCODE_0);
+					Common::sprintf_s(savegameName, "Quicksave %d", event.kbd.keycode - Common::KEYCODE_0);
 					saveGameStateIntern(saveLoadSlot, savegameName, nullptr);
 				}
 			} else if (event.kbd.hasFlags(Common::KBD_CTRL)) {
diff --git a/engines/kyra/gui/gui_hof.cpp b/engines/kyra/gui/gui_hof.cpp
index 74c7eaa9e17..0a3a316c751 100644
--- a/engines/kyra/gui/gui_hof.cpp
+++ b/engines/kyra/gui/gui_hof.cpp
@@ -449,22 +449,22 @@ void KyraEngine_HoF::loadBookBkgd() {
 void KyraEngine_HoF::showBookPage() {
 	char filename[16];
 
-	sprintf(filename, "PAGE%.01X.%s", _bookCurPage, _languageExtension[_lang]);
+	Common::sprintf_s(filename, "PAGE%.01X.%s", _bookCurPage, _languageExtension[_lang]);
 	uint8 *leftPage = _res->fileData(filename, nullptr);
 	if (!leftPage) {
 		// some floppy version use a TXT extension
-		sprintf(filename, "PAGE%.01X.TXT", _bookCurPage);
+		Common::sprintf_s(filename, "PAGE%.01X.TXT", _bookCurPage);
 		leftPage = _res->fileData(filename, nullptr);
 	}
 
 	int leftPageY = _bookPageYOffset[_bookCurPage];
 
-	sprintf(filename, "PAGE%.01X.%s", _bookCurPage+1, _languageExtension[_lang]);
+	Common::sprintf_s(filename, "PAGE%.01X.%s", _bookCurPage+1, _languageExtension[_lang]);
 	uint8 *rightPage = nullptr;
 	if (_bookCurPage != _bookMaxPage) {
 		rightPage = _res->fileData(filename, nullptr);
 		if (!rightPage) {
-			sprintf(filename, "PAGE%.01X.TXT", _bookCurPage);
+			Common::sprintf_s(filename, "PAGE%.01X.TXT", _bookCurPage);
 			rightPage = _res->fileData(filename, nullptr);
 		}
 	}
diff --git a/engines/kyra/gui/gui_lol.cpp b/engines/kyra/gui/gui_lol.cpp
index 8f68970232c..f30d6624a44 100644
--- a/engines/kyra/gui/gui_lol.cpp
+++ b/engines/kyra/gui/gui_lol.cpp
@@ -158,7 +158,7 @@ void LoLEngine::gui_displayCharInventory(int charNum) {
 
 	if (id != _lastCharInventory) {
 		char file[13];
-		sprintf(file, "invent%d.cps", inventoryTypes[id]);
+		Common::sprintf_s(file, "invent%d.cps", inventoryTypes[id]);
 		_screen->loadBitmap(file, 3, 3, 0);
 		_screen->copyRegion(0, 0, 112, 0, 208, 120, 2, 6);
 	} else {
diff --git a/engines/kyra/resource/resource_intern.cpp b/engines/kyra/resource/resource_intern.cpp
index 2c9a873f979..87bce77694a 100644
--- a/engines/kyra/resource/resource_intern.cpp
+++ b/engines/kyra/resource/resource_intern.cpp
@@ -962,7 +962,7 @@ Common::Archive *InstallerLoader::load(Resource *owner, const Common::String &fi
 	Common::SeekableReadStream *tmpFile = nullptr;
 
 	for (int8 currentFile = 1; currentFile; currentFile++) {
-		sprintf(filenameExt, extension.c_str(), currentFile);
+		Common::sprintf_s(filenameExt, extension.c_str(), currentFile);
 		filenameTemp = filenameBase + Common::String(filenameExt);
 
 		if (!(tmpFile = owner->createReadStream(filenameTemp))) {
@@ -1040,7 +1040,7 @@ Common::Archive *InstallerLoader::load(Resource *owner, const Common::String &fi
 	for (Common::List<InsArchive>::iterator a = archives.begin(); a != archives.end(); ++a) {
 		startFile = true;
 		for (uint32 i = a->firstFile; i != (a->lastFile + 1); i++) {
-			sprintf(filenameExt, extension.c_str(), i);
+			Common::sprintf_s(filenameExt, extension.c_str(), i);
 			filenameTemp = a->filename + Common::String(filenameExt);
 
 			if (!(tmpFile = owner->createReadStream(filenameTemp))) {
@@ -1115,7 +1115,7 @@ Common::Archive *InstallerLoader::load(Resource *owner, const Common::String &fi
 						}
 					}
 
-					sprintf(filenameExt, extension.c_str(), i + 1);
+					Common::sprintf_s(filenameExt, extension.c_str(), i + 1);
 					filenameTemp = a->filename + Common::String(filenameExt);
 
 					Common::SeekableReadStream *tmpFile2 = owner->createReadStream(filenameTemp);
diff --git a/engines/kyra/script/script_hof.cpp b/engines/kyra/script/script_hof.cpp
index 2140fc823a0..4af18247b72 100644
--- a/engines/kyra/script/script_hof.cpp
+++ b/engines/kyra/script/script_hof.cpp
@@ -783,16 +783,16 @@ int KyraEngine_HoF::o2_showLetter(EMCState *script) {
 	_screen->clearPage(3);
 	_screen->loadBitmap("_NOTE.CPS", 3, 3, nullptr);
 
-	sprintf(filename, "_NTEPAL%.1d.COL", letter+1);
+	Common::sprintf_s(filename, "_NTEPAL%.1d.COL", letter+1);
 	_screen->loadPalette(filename, _screen->getPalette(0));
 
 	_screen->fadeToBlack(0x14);
 
-	sprintf(filename, "LETTER%.1d.%s", letter, _languageExtension[_lang]);
+	Common::sprintf_s(filename, "LETTER%.1d.%s", letter, _languageExtension[_lang]);
 	uint8 *letterBuffer = _res->fileData(filename, nullptr);
 	if (!letterBuffer) {
 		// some floppy versions use a TXT extension
-		sprintf(filename, "LETTER%.1d.TXT", letter);
+		Common::sprintf_s(filename, "LETTER%.1d.TXT", letter);
 		letterBuffer = _res->fileData(filename, nullptr);
 	}
 


Commit: 27ba4d72c802be1755e5c5bcd3517e394e28b29d
    https://github.com/scummvm/scummvm/commit/27ba4d72c802be1755e5c5bcd3517e394e28b29d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
LASTEXPRESS: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/lastexpress/sound/sound.cpp


diff --git a/engines/lastexpress/sound/sound.cpp b/engines/lastexpress/sound/sound.cpp
index cd010cc9725..45992c53366 100644
--- a/engines/lastexpress/sound/sound.cpp
+++ b/engines/lastexpress/sound/sound.cpp
@@ -1364,7 +1364,7 @@ void SoundManager::playAmbientSound(int param) {
 			}
 
 			if (partNumber != 99)
-				sprintf(tmp, "LOOP%d%c.SND", partNumber, (char)(_engine->getRandom().getRandomNumber(numLoops[partNumber] - 1) + 'A'));
+				Common::sprintf_s(tmp, "LOOP%d%c.SND", partNumber, (char)(_engine->getRandom().getRandomNumber(numLoops[partNumber] - 1) + 'A'));
 		}
 
 		if (getFlags()->flag_3)


Commit: f4853e863d771146309e3763e47b5ae270a8b79d
    https://github.com/scummvm/scummvm/commit/f4853e863d771146309e3763e47b5ae270a8b79d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
LURE: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/lure/disk.cpp
    engines/lure/game.cpp
    engines/lure/lure.cpp
    engines/lure/room.cpp
    engines/lure/scripts.cpp


diff --git a/engines/lure/disk.cpp b/engines/lure/disk.cpp
index daeecc3ffda..571cc43954e 100644
--- a/engines/lure/disk.cpp
+++ b/engines/lure/disk.cpp
@@ -90,7 +90,7 @@ void Disk::openFile(uint8 fileNum) {
 	if (_fileNum == 0)
 		Common::strcpy_s(sFilename, SUPPORT_FILENAME);
 	else
-		sprintf(sFilename, "disk%d.%s", _fileNum, isEGA ? "ega" : "vga");
+		Common::sprintf_s(sFilename, "disk%d.%s", _fileNum, isEGA ? "ega" : "vga");
 
 	_fileHandle->open(sFilename);
 	if (!_fileHandle->isOpen())
diff --git a/engines/lure/game.cpp b/engines/lure/game.cpp
index 68162e5147d..253be974a5b 100644
--- a/engines/lure/game.cpp
+++ b/engines/lure/game.cpp
@@ -550,7 +550,7 @@ void Game::handleRightClickMenu() {
 		action = PopupMenu::Show(actions);
 
 		if (action != NONE) {
-			sprintf(statusLine, "%s ", stringList.getString(action));
+			Common::sprintf_s(statusLine, MAX_DESC_SIZE, "%s ", stringList.getString(action));
 			statusLine += strlen(statusLine);
 		}
 
@@ -664,7 +664,7 @@ void Game::handleLeftClick() {
 
 	if ((room.destRoomNumber() == 0) && (room.hotspotId() != 0)) {
 		// Handle look at hotspot
-		sprintf(room.statusLine(), "%s ", stringList.getString(LOOK_AT));
+		Common::sprintf_s(room.statusLine(), MAX_DESC_SIZE, "%s ", stringList.getString(LOOK_AT));
 		HotspotData *hotspot = res.getHotspot(room.hotspotId());
 		assert(hotspot);
 		strings.getString(hotspot->nameId, room.statusLine() + strlen(room.statusLine()));
@@ -723,7 +723,7 @@ bool Game::GetTellActions() {
 			screen.update();
 
 			switch (paramIndex) {
-			case 0:
+			case 0: {
 				// Prompt for selection of action to perform
 				action = PopupMenu::Show(0x6A07FD);
 				if (action == NONE) {
@@ -740,7 +740,8 @@ bool Game::GetTellActions() {
 				}
 
 				// Add the action to the status line
-				sprintf(statusLine + strlen(statusLine), "%s ", stringList.getString(action));
+				size_t pos = strlen(statusLine);
+				Common::sprintf_s(statusLine + pos, MAX_DESC_SIZE - (statusLine - origStatusLine) - pos, "%s ", stringList.getString(action));
 
 				// Handle any processing for the action
 				commands[_numTellCommands * 3] = (uint16) action;
@@ -748,7 +749,7 @@ bool Game::GetTellActions() {
 				commands[_numTellCommands * 3 + 2] = 0;
 				++paramIndex;
 				break;
-
+			}
 			case 1:
 				// First parameter
 				action = (Action) commands[_numTellCommands * 3];
@@ -829,13 +830,14 @@ bool Game::GetTellActions() {
 					selectionId = PopupMenu::Show(2, continueStrsList);
 
 					switch (selectionId) {
-					case 0:
+					case 0: {
 						// Get ready for next command
-						sprintf(statusLine + strlen(statusLine), " %s ", continueStrsList[0]);
+						size_t pos = strlen(statusLine);
+						Common::sprintf_s(statusLine + pos, MAX_DESC_SIZE - (statusLine - origStatusLine) - pos, " %s ", continueStrsList[0]);
 						++_numTellCommands;
 						paramIndex = 0;
 						break;
-
+					}
 					case 1:
 						// Increment for just selected command, and add a large amount
 						// to signal that the command sequence is complete
diff --git a/engines/lure/lure.cpp b/engines/lure/lure.cpp
index 15d2062d120..374f596ca35 100644
--- a/engines/lure/lure.cpp
+++ b/engines/lure/lure.cpp
@@ -185,7 +185,7 @@ void LureEngine::pauseEngineIntern(bool pause) {
 const char *LureEngine::generateSaveName(int slotNumber) {
 	static char buffer[15];
 
-	sprintf(buffer, "lure.%.3d", slotNumber);
+	Common::sprintf_s(buffer, "lure.%.3d", slotNumber);
 	return buffer;
 }
 
diff --git a/engines/lure/room.cpp b/engines/lure/room.cpp
index f05361e2b7d..d6974932e7f 100644
--- a/engines/lure/room.cpp
+++ b/engines/lure/room.cpp
@@ -292,7 +292,7 @@ void Room::addAnimation(Hotspot &h) {
 		int16 x = h.x();
 		int16 y = h.y();
 		if ((x >= 0) && (x < FULL_SCREEN_WIDTH) && (y >= 0) && (y < FULL_SCREEN_HEIGHT))
-			sprintf(buffer, "%xh", h.hotspotId());
+			Common::sprintf_s(buffer, "%xh", h.hotspotId());
 
 	}
 }
@@ -521,7 +521,7 @@ void Room::update() {
 */
 				uint16 v = tempLayer[(yctr + 1) * DECODED_PATHS_WIDTH + xctr + 1];
 				if ((v != 0) && (v < 100)) {
-					sprintf(buffer, "%d", v % 10);
+					Common::sprintf_s(buffer, "%d", v % 10);
 					s.writeString(xctr * 8, yctr * 8 + 8, buffer, true);
 //				} else if (v == 0xffff) {
 				} else if (_roomData->paths.isOccupied(xctr, yctr)) {
@@ -531,7 +531,7 @@ void Room::update() {
 		}
 
 		Mouse &m = Mouse::getReference();
-		sprintf(buffer, "Room %d Pos (%d,%d) @ (%d,%d)", _roomNumber, m.x(), m.y(),
+		Common::sprintf_s(buffer, "Room %d Pos (%d,%d) @ (%d,%d)", _roomNumber, m.x(), m.y(),
 			m.x() / RECT_SIZE, (m.y() - MENUBAR_Y_SIZE) / RECT_SIZE);
 		s.writeString(FULL_SCREEN_WIDTH / 2, 0, buffer, false, white);
 	}
diff --git a/engines/lure/scripts.cpp b/engines/lure/scripts.cpp
index f02d645492f..c50e556966e 100644
--- a/engines/lure/scripts.cpp
+++ b/engines/lure/scripts.cpp
@@ -937,7 +937,7 @@ uint16 Script::execute(uint16 startOffset) {
 			error("Script failure in script %d - invalid offset %d", startOffset, offset);
 
 		if (gDebugLevel >= ERROR_DETAILED)
-			sprintf(debugInfo, "%xh - ", offset);
+			Common::sprintf_s(debugInfo, "%xh - ", offset);
 
 		// Get opcode byte and separate into opcode and has parameter bit flag
 		opcode = scripts[offset++];
@@ -956,10 +956,12 @@ uint16 Script::execute(uint16 startOffset) {
 			param = READ_LE_UINT16(scripts + offset);
 			offset += 2;
 
-			if (gDebugLevel >= ERROR_DETAILED)
-				sprintf(debugInfo + strlen(debugInfo), " [%d]",
+			if (gDebugLevel >= ERROR_DETAILED) {
+				size_t pos = strlen(debugInfo);
+				Common::sprintf_s(debugInfo + pos, sizeof(debugInfo) - pos, " [%d]",
 					((opcode == S_OPCODE_GET_FIELD) || (opcode == S_OPCODE_SET_FIELD)) ?
 					param >> 1 : param);
+			}
 		}
 
 		if (gDebugLevel >= ERROR_DETAILED) {
@@ -977,15 +979,17 @@ uint16 Script::execute(uint16 startOffset) {
 			case S_OPCODE_AND:
 			case S_OPCODE_OR:
 			case S_OPCODE_LOGICAL_AND:
-			case S_OPCODE_LOGICAL_OR:
-				sprintf(debugInfo + strlen(debugInfo),
+			case S_OPCODE_LOGICAL_OR: {
+				size_t pos = strlen(debugInfo);
+				Common::sprintf_s(debugInfo + pos, sizeof(debugInfo) - pos,
 					" %d, %d", stack[stack.size() - 1], stack[stack.size() - 2]);
 				break;
-
-			case S_OPCODE_SET_FIELD:
-				sprintf(debugInfo + strlen(debugInfo), " <= ST (%d)", stack[stack.size() - 1]);
+			}
+			case S_OPCODE_SET_FIELD: {
+				size_t pos = strlen(debugInfo);
+				Common::sprintf_s(debugInfo + pos, sizeof(debugInfo) - pos, " <= ST (%d)", stack[stack.size() - 1]);
 				break;
-
+			}
 			default:
 				break;
 			}
@@ -1110,14 +1114,15 @@ uint16 Script::execute(uint16 startOffset) {
 				}
 
 				// Any params
+				size_t pos = strlen(debugInfo);
 				if (stack.size() >= 3)
-					sprintf(debugInfo + strlen(debugInfo), " (%d,%d,%d)",
+					Common::sprintf_s(debugInfo + pos, sizeof(debugInfo) - pos, " (%d,%d,%d)",
 						stack[stack.size()-1], stack[stack.size()-2], stack[stack.size()-3]);
-				if (stack.size() == 2)
-					sprintf(debugInfo + strlen(debugInfo), " (%d,%d)",
+				else if (stack.size() == 2)
+					Common::sprintf_s(debugInfo + pos, sizeof(debugInfo) - pos, " (%d,%d)",
 						stack[stack.size()-1], stack[stack.size()-2]);
 				else if (stack.size() == 1)
-					sprintf(debugInfo + strlen(debugInfo), " (%d)", stack[stack.size()-1]);
+					Common::sprintf_s(debugInfo + pos, sizeof(debugInfo) - pos, " (%d)", stack[stack.size()-1]);
 				Common::strcat_s(debugInfo, ")");
 
 				debugC(ERROR_DETAILED, kLureDebugScripts, "%s", debugInfo);
@@ -1178,10 +1183,11 @@ uint16 Script::execute(uint16 startOffset) {
 			case S_OPCODE_OR:
 			case S_OPCODE_LOGICAL_AND:
 			case S_OPCODE_LOGICAL_OR:
-			case S_OPCODE_GET_FIELD:
-				sprintf(debugInfo + strlen(debugInfo), " => ST (%d)", stack[stack.size()-1]);
+			case S_OPCODE_GET_FIELD: {
+				size_t pos = strlen(debugInfo);
+				Common::sprintf_s(debugInfo + pos, sizeof(debugInfo) - pos, " => ST (%d)", stack[stack.size()-1]);
 				break;
-
+			}
 			case S_OPCODE_PUSH:
 				Common::strcat_s(debugInfo, " => ST");
 				break;


Commit: 19fe3f8b9085100f52e03f39c74dc49d2d9256f2
    https://github.com/scummvm/scummvm/commit/19fe3f8b9085100f52e03f39c74dc49d2d9256f2
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
NGI: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/ngi/gameloader.cpp


diff --git a/engines/ngi/gameloader.cpp b/engines/ngi/gameloader.cpp
index 00a28e8e0fb..2c8d05782dc 100644
--- a/engines/ngi/gameloader.cpp
+++ b/engines/ngi/gameloader.cpp
@@ -647,7 +647,7 @@ bool PreloadItems::load(MfcArchive &file) {
 
 const char *getSavegameFile(int saveGameIdx) {
 	static char buffer[20];
-	sprintf(buffer, "fullpipe.s%02d", saveGameIdx);
+	Common::sprintf_s(buffer, "fullpipe.s%02d", saveGameIdx);
 	return buffer;
 }
 


Commit: 9a5f51864aaa8a5b7c00557a324fa86b9cce577b
    https://github.com/scummvm/scummvm/commit/9a5f51864aaa8a5b7c00557a324fa86b9cce577b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
PARALLACTION: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/parallaction/balloons.cpp
    engines/parallaction/debug.cpp
    engines/parallaction/disk_br.cpp
    engines/parallaction/disk_ns.cpp
    engines/parallaction/parallaction.cpp
    engines/parallaction/saveload.cpp
    engines/parallaction/sound.h


diff --git a/engines/parallaction/balloons.cpp b/engines/parallaction/balloons.cpp
index 1aaf31c4879..16c5f71ffb5 100644
--- a/engines/parallaction/balloons.cpp
+++ b/engines/parallaction/balloons.cpp
@@ -161,7 +161,7 @@ protected:
 		} else
 		if (token.compareToIgnoreCase("%s") == 0) {
 			char buf[20];
-			sprintf(buf, "%i", _vm->_score);
+			Common::sprintf_s(buf, "%i", _vm->_score);
 			return Common::String(buf);
 		}
 
diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp
index ad87f1dceee..2160571643a 100644
--- a/engines/parallaction/debug.cpp
+++ b/engines/parallaction/debug.cpp
@@ -71,7 +71,7 @@ bool Debugger::Cmd_Location(int argc, const char **argv) {
 	case 3:
 		character = const_cast<char *>(argv[2]);
 		location = const_cast<char *>(argv[1]);
-		sprintf(tmp, "%s.%s", location, character);
+		Common::sprintf_s(tmp, "%s.%s", location, character);
 		_vm->scheduleLocationSwitch(tmp);
 		break;
 
diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp
index a9f0abfccdb..87151b2dd21 100644
--- a/engines/parallaction/disk_br.cpp
+++ b/engines/parallaction/disk_br.cpp
@@ -254,10 +254,6 @@ GfxObj* DosDisk_br::loadObjects(const char *name, uint8 part) {
 	return obj;
 }
 
-void genSlidePath(char *path, const char* name) {
-	sprintf(path, "%s.bmp", name);
-}
-
 GfxObj* DosDisk_br::loadStatic(const char* name) {
 	debugC(5, kDebugDisk, "DosDisk_br::loadStatic");
 	Common::SeekableReadStream *stream = openFile("ras/" + Common::String(name), ".ras");
diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp
index 3b7df307c0f..15106eff90d 100644
--- a/engines/parallaction/disk_ns.cpp
+++ b/engines/parallaction/disk_ns.cpp
@@ -260,7 +260,7 @@ Common::SeekableReadStream *DosDisk_ns::tryOpenFile(const char* name) {
 		return stream;
 
 	char path[PATH_LEN];
-	sprintf(path, "%s.pp", name);
+	Common::sprintf_s(path, "%s.pp", name);
 	return _sset.createReadStreamForMember(path);
 }
 
@@ -274,12 +274,12 @@ Script* Disk_ns::loadLocation(const char *name) {
 	if (!strcmp(charName, "Dinor"))
 		charName = "dino";
 
-	sprintf(path, "%s%s/%s.loc", charName, _language.c_str(), name);
+	Common::sprintf_s(path, "%s%s/%s.loc", charName, _language.c_str(), name);
 	debugC(3, kDebugDisk, "Disk_ns::loadLocation(%s): trying '%s'", name, path);
 	Common::SeekableReadStream *stream = tryOpenFile(path);
 
 	if (!stream) {
-		sprintf(path, "%s/%s.loc", _language.c_str(), name);
+		Common::sprintf_s(path, "%s/%s.loc", _language.c_str(), name);
 		debugC(3, kDebugDisk, "DosDisk_ns::loadLocation(%s): trying '%s'", name, path);
 		stream = openFile(path);
 	}
@@ -289,7 +289,7 @@ Script* Disk_ns::loadLocation(const char *name) {
 Script* Disk_ns::loadScript(const char* name) {
 	debugC(1, kDebugDisk, "Disk_ns::loadScript '%s'", name);
 	char path[PATH_LEN];
-	sprintf(path, "%s.script", name);
+	Common::sprintf_s(path, "%s.script", name);
 	Common::SeekableReadStream *stream = openFile(path);
 	return new Script(stream, true);
 }
@@ -339,9 +339,9 @@ GfxObj* DosDisk_ns::loadTalk(const char *name) {
 
 	char v20[30];
 	if (g_engineFlags & kEngineTransformedDonna) {
-		sprintf(v20, "%stta.cnv", name);
+		Common::sprintf_s(v20, "%stta.cnv", name);
 	} else {
-		sprintf(v20, "%stal.cnv", name);
+		Common::sprintf_s(v20, "%stal.cnv", name);
 	}
 
 	return new GfxObj(0, loadCnv(v20), name);
@@ -350,7 +350,7 @@ GfxObj* DosDisk_ns::loadTalk(const char *name) {
 
 GfxObj* DosDisk_ns::loadHead(const char* name) {
 	char path[PATH_LEN];
-	sprintf(path, "%shead", name);
+	Common::sprintf_s(path, "%shead", name);
 	path[8] = '\0';
 	Common::strcat_s(path, ".cnv");
 	return new GfxObj(0, loadCnv(path));
@@ -359,21 +359,21 @@ GfxObj* DosDisk_ns::loadHead(const char* name) {
 
 Frames* DosDisk_ns::loadPointer(const char *name) {
 	char path[PATH_LEN];
-	sprintf(path, "%s.cnv", name);
+	Common::sprintf_s(path, "%s.cnv", name);
 	return loadCnv(path);
 }
 
 
 Font* DosDisk_ns::loadFont(const char* name) {
 	char path[PATH_LEN];
-	sprintf(path, "%scnv.cnv", name);
+	Common::sprintf_s(path, "%scnv.cnv", name);
 	return createFont(name, loadCnv(path));
 }
 
 
 GfxObj* DosDisk_ns::loadObjects(const char *name, uint8 part) {
 	char path[PATH_LEN];
-	sprintf(path, "%sobj.cnv", name);
+	Common::sprintf_s(path, "%sobj.cnv", name);
 	return new GfxObj(0, loadCnv(path), name);
 }
 
@@ -491,13 +491,13 @@ void DosDisk_ns::loadBackground(BackgroundInfo& info, const char *filename) {
 
 void DosDisk_ns::loadSlide(BackgroundInfo& info, const char *filename) {
 	char path[PATH_LEN];
-	sprintf(path, "%s.slide", filename);
+	Common::sprintf_s(path, "%s.slide", filename);
 	loadBackground(info, path);
 }
 
 void DosDisk_ns::loadScenery(BackgroundInfo& info, const char *name, const char *mask, const char* path) {
 	char filename[PATH_LEN];
-	sprintf(filename, "%s.dyn", name);
+	Common::sprintf_s(filename, "%s.dyn", name);
 
 	// load bitmap
 	loadBackground(info, filename);
@@ -508,7 +508,7 @@ void DosDisk_ns::loadScenery(BackgroundInfo& info, const char *name, const char
 
 	// load external mask and path if present (overwriting the ones loaded by loadBackground)
 	char maskPath[PATH_LEN];
-	sprintf(maskPath, "%s.msk", mask);
+	Common::sprintf_s(maskPath, "%s.msk", mask);
 
 	Common::SeekableReadStream *stream = openFile(maskPath);
 	assert(stream);
@@ -524,13 +524,13 @@ void DosDisk_ns::loadScenery(BackgroundInfo& info, const char *name, const char
 
 Table* DosDisk_ns::loadTable(const char* name) {
 	char path[PATH_LEN];
-	sprintf(path, "%s.tab", name);
+	Common::sprintf_s(path, "%s.tab", name);
 	return createTableFromStream(100, openFile(path));
 }
 
 Common::SeekableReadStream* DosDisk_ns::loadMusic(const char* name) {
 	char path[PATH_LEN];
-	sprintf(path, "%s.mid", name);
+	Common::sprintf_s(path, "%s.mid", name);
 	return openFile(path);
 }
 
@@ -868,7 +868,7 @@ Common::SeekableReadStream *AmigaDisk_ns::tryOpenFile(const char* name) {
 		return stream;
 
 	char path[PATH_LEN];
-	sprintf(path, "%s.pp", name);
+	Common::sprintf_s(path, "%s.pp", name);
 	stream = _sset.createReadStreamForMember(path);
 	if (stream) {
 		ret = new PowerPackerStream(*stream);
@@ -876,7 +876,7 @@ Common::SeekableReadStream *AmigaDisk_ns::tryOpenFile(const char* name) {
 		return ret;
 	}
 
-	sprintf(path, "%s.dd", name);
+	Common::sprintf_s(path, "%s.dd", name);
 	stream = _sset.createReadStreamForMember(path);
 	if (stream) {
 		ret = new PowerPackerStream(*stream);
@@ -952,7 +952,7 @@ void AmigaDisk_ns::loadMask_internal(BackgroundInfo& info, const char *name) {
 	debugC(5, kDebugDisk, "AmigaDisk_ns::loadMask_internal(%s)", name);
 
 	char path[PATH_LEN];
-	sprintf(path, "%s.mask", name);
+	Common::sprintf_s(path, "%s.mask", name);
 
 	Common::SeekableReadStream *s = tryOpenFile(path);
 	if (!s) {
@@ -984,7 +984,7 @@ void AmigaDisk_ns::loadMask_internal(BackgroundInfo& info, const char *name) {
 void AmigaDisk_ns::loadPath_internal(BackgroundInfo& info, const char *name) {
 
 	char path[PATH_LEN];
-	sprintf(path, "%s.path", name);
+	Common::sprintf_s(path, "%s.path", name);
 
 	Common::SeekableReadStream *s = tryOpenFile(path);
 	if (!s) {
@@ -1007,7 +1007,7 @@ void AmigaDisk_ns::loadScenery(BackgroundInfo& info, const char* background, con
 	debugC(1, kDebugDisk, "AmigaDisk_ns::loadScenery '%s', '%s'", background, mask);
 
 	char filename[PATH_LEN];
-	sprintf(filename, "%s.bkgnd", background);
+	Common::sprintf_s(filename, "%s.bkgnd", background);
 
 	loadBackground(info, filename);
 
@@ -1032,7 +1032,7 @@ Frames* AmigaDisk_ns::loadFrames(const char* name) {
 	debugC(1, kDebugDisk, "AmigaDisk_ns::loadFrames '%s'", name);
 
 	char path[PATH_LEN];
-	sprintf(path, "anims/%s", name);
+	Common::sprintf_s(path, "anims/%s", name);
 
 	Common::SeekableReadStream *s = tryOpenFile(path);
 	if (!s)
@@ -1044,7 +1044,7 @@ Frames* AmigaDisk_ns::loadFrames(const char* name) {
 GfxObj* AmigaDisk_ns::loadHead(const char* name) {
 	debugC(1, kDebugDisk, "AmigaDisk_ns::loadHead '%s'", name);
 	char path[PATH_LEN];
-	sprintf(path, "%s.head", name);
+	Common::sprintf_s(path, "%s.head", name);
 	Common::SeekableReadStream *s = openFile(path);
 	return new GfxObj(0, makeCnv(s), name);
 }
@@ -1055,9 +1055,9 @@ GfxObj* AmigaDisk_ns::loadObjects(const char *name, uint8 part) {
 
 	char path[PATH_LEN];
 	if (_vm->getFeatures() & GF_DEMO)
-		sprintf(path, "%s.objs", name);
+		Common::sprintf_s(path, "%s.objs", name);
 	else
-		sprintf(path, "objs/%s.objs", name);
+		Common::sprintf_s(path, "objs/%s.objs", name);
 
 	Common::SeekableReadStream *s = openFile(path);
 	return new GfxObj(0, makeCnv(s), name);
@@ -1069,9 +1069,9 @@ GfxObj* AmigaDisk_ns::loadTalk(const char *name) {
 
 	char path[PATH_LEN];
 	if (_vm->getFeatures() & GF_DEMO)
-		sprintf(path, "%s.talk", name);
+		Common::sprintf_s(path, "%s.talk", name);
 	else
-		sprintf(path, "talk/%s.talk", name);
+		Common::sprintf_s(path, "talk/%s.talk", name);
 
 	Common::SeekableReadStream *s = tryOpenFile(path);
 	if (!s) {
@@ -1085,12 +1085,12 @@ Table* AmigaDisk_ns::loadTable(const char* name) {
 
 	char path[PATH_LEN];
 	if (!scumm_stricmp(name, "global")) {
-		sprintf(path, "%s.table", name);
+		Common::sprintf_s(path, "%s.table", name);
 	} else {
 		if (!(_vm->getFeatures() & GF_DEMO))
-			sprintf(path, "objs/%s.table", name);
+			Common::sprintf_s(path, "objs/%s.table", name);
 		else
-			sprintf(path, "%s.table", name);
+			Common::sprintf_s(path, "%s.table", name);
 	}
 
 	return createTableFromStream(100, openFile(path));
@@ -1100,7 +1100,7 @@ Font* AmigaDisk_ns::loadFont(const char* name) {
 	debugC(1, kDebugDisk, "AmigaFullDisk::loadFont '%s'", name);
 
 	char path[PATH_LEN];
-	sprintf(path, "%sfont", name);
+	Common::sprintf_s(path, "%sfont", name);
 
 	Common::SeekableReadStream *stream = openFile(path);
 	Font *font = createFont(name, *stream);
@@ -1116,7 +1116,7 @@ Common::SeekableReadStream* AmigaDisk_ns::loadMusic(const char* name) {
 
 Common::SeekableReadStream* AmigaDisk_ns::loadSound(const char* name) {
 	char path[PATH_LEN];
-	sprintf(path, "%s.snd", name);
+	Common::sprintf_s(path, "%s.snd", name);
 
 	return tryOpenFile(path);
 }
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 0e921facbaf..2700ee47458 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -947,8 +947,8 @@ void CharacterName::bind(const char *name) {
 
 	memset(_baseName, 0, 30);
 	strncpy(_baseName, begin, end - begin);
-	sprintf(_name, "%s%s", _prefix, _baseName);
-	sprintf(_fullName, "%s%s%s", _prefix, _baseName, _suffix);
+	Common::sprintf_s(_name, "%s%s", _prefix, _baseName);
+	Common::sprintf_s(_fullName, "%s%s%s", _prefix, _baseName, _suffix);
 }
 
 const char *CharacterName::getName() const {
diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp
index c98623206c5..c7335fd72c5 100644
--- a/engines/parallaction/saveload.cpp
+++ b/engines/parallaction/saveload.cpp
@@ -45,7 +45,7 @@ Common::String SaveLoad::genSaveFileName(uint slot) {
 	assert(slot < NUM_SAVESLOTS || slot == SPECIAL_SAVESLOT);
 
 	char s[20];
-	sprintf(s, "%s.%.3u", _saveFilePrefix.c_str(), slot);
+	Common::sprintf_s(s, "%s.%.3u", _saveFilePrefix.c_str(), slot);
 
 	return Common::String(s);
 }
@@ -119,7 +119,7 @@ void SaveLoad_ns::doLoadGame(uint16 slot) {
 	Common::strcpy_s(_vm->_characterName1, "null");
 
 	char tmp[PATH_LEN];
-	sprintf(tmp, "%s.%s" , location.c_str(), character.c_str());
+	Common::sprintf_s(tmp, "%s.%s" , location.c_str(), character.c_str());
 	_vm->scheduleLocationSwitch(tmp);
 }
 
@@ -136,7 +136,7 @@ void SaveLoad_ns::doSaveGame(uint16 slot, const char* name) {
 	memset(s, 0, sizeof(s));
 
 	if (!name || name[0] == '\0') {
-		sprintf(s, "default_%i", slot);
+		Common::sprintf_s(s, "default_%i", slot);
 	} else {
 		strncpy(s, name, 199);
 	}
@@ -144,31 +144,31 @@ void SaveLoad_ns::doSaveGame(uint16 slot, const char* name) {
 	f->writeString(s);
 	f->writeString("\n");
 
-	sprintf(s, "%s\n", _vm->_char.getFullName());
+	Common::sprintf_s(s, "%s\n", _vm->_char.getFullName());
 	f->writeString(s);
 
-	sprintf(s, "%s\n", g_saveData1);
+	Common::sprintf_s(s, "%s\n", g_saveData1);
 	f->writeString(s);
-	sprintf(s, "%d\n", _vm->_char._ani->getX());
+	Common::sprintf_s(s, "%d\n", _vm->_char._ani->getX());
 	f->writeString(s);
-	sprintf(s, "%d\n", _vm->_char._ani->getY());
+	Common::sprintf_s(s, "%d\n", _vm->_char._ani->getY());
 	f->writeString(s);
-	sprintf(s, "%d\n", _vm->_score);
+	Common::sprintf_s(s, "%d\n", _vm->_score);
 	f->writeString(s);
-	sprintf(s, "%u\n", g_globalFlags);
+	Common::sprintf_s(s, "%u\n", g_globalFlags);
 	f->writeString(s);
 
-	sprintf(s, "%d\n", _vm->_numLocations);
+	Common::sprintf_s(s, "%d\n", _vm->_numLocations);
 	f->writeString(s);
 	for (uint16 _si = 0; _si < _vm->_numLocations; _si++) {
-		sprintf(s, "%s\n%u\n", _vm->_locationNames[_si], _vm->_localFlags[_si]);
+		Common::sprintf_s(s, "%s\n%u\n", _vm->_locationNames[_si], _vm->_localFlags[_si]);
 		f->writeString(s);
 	}
 
 	const InventoryItem *item;
 	for (uint16 _si = 0; _si < 30; _si++) {
 		item = _vm->getInventoryItem(_si);
-		sprintf(s, "%u\n%d\n", item->_id, item->_index);
+		Common::sprintf_s(s, "%u\n%d\n", item->_id, item->_index);
 		f->writeString(s);
 	}
 
diff --git a/engines/parallaction/sound.h b/engines/parallaction/sound.h
index 5ccb1085c8c..299573e1bde 100644
--- a/engines/parallaction/sound.h
+++ b/engines/parallaction/sound.h
@@ -56,7 +56,7 @@ public:
 	virtual ~SoundMan() { delete _impl; }
 	void execute(int command, int32 parm) {
 		char n[12];
-		sprintf(n, "%i", parm);
+		Common::sprintf_s(n, "%i", parm);
 		execute(command, n);
 	}
 	void execute(int command, const char *parm = 0) {


Commit: 1f45b787b937c14f8e9aefb5627030a33e0ed7f4
    https://github.com/scummvm/scummvm/commit/1f45b787b937c14f8e9aefb5627030a33e0ed7f4
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
QUEEN: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/queen/display.cpp
    engines/queen/graphics.cpp
    engines/queen/journal.cpp
    engines/queen/logic.cpp
    engines/queen/resource.cpp
    engines/queen/sound.cpp
    engines/queen/talk.cpp


diff --git a/engines/queen/display.cpp b/engines/queen/display.cpp
index b6b66cc09a0..768339c0cce 100644
--- a/engines/queen/display.cpp
+++ b/engines/queen/display.cpp
@@ -101,10 +101,10 @@ void Display::dynalumInit(const char *roomName, uint16 roomNum) {
 
 	if (!isPalFadingDisabled(roomNum)) {
 		char filename[20];
-		sprintf(filename, "%s.MSK", roomName);
+		Common::sprintf_s(filename, "%s.MSK", roomName);
 		if (_vm->resource()->fileExists(filename)) {
 			_dynalum.mskBuf = (uint8 *)_vm->resource()->loadFile(filename, 0, &_dynalum.mskSize);
-			sprintf(filename, "%s.LUM", roomName);
+			Common::sprintf_s(filename, "%s.LUM", roomName);
 			if (_vm->resource()->fileExists(filename)) {
 				_dynalum.lumBuf = (int8 *)_vm->resource()->loadFile(filename, 0, &_dynalum.lumSize);
 				_dynalum.valid = true;
@@ -702,7 +702,7 @@ void Display::setupPanel() {
 
 	uint32 dataSize;
 	char dataName[20];
-	sprintf(dataName, "PANEL.%s", _imageExt);
+	Common::sprintf_s(dataName, "PANEL.%s", _imageExt);
 	uint8 *data = _vm->resource()->loadFile(dataName, 0, &dataSize);
 
 	if (_vm->resource()->getPlatform() == Common::kPlatformAmiga) {
@@ -721,7 +721,7 @@ void Display::setupNewRoom(const char *name, uint16 room) {
 
 	uint32 dataSize;
 	char dataName[20];
-	sprintf(dataName, "%s.%s", name, _imageExt);
+	Common::sprintf_s(dataName, "%s.%s", name, _imageExt);
 	uint8 *data = _vm->resource()->loadFile(dataName, 0, &dataSize);
 
 	if (_vm->resource()->getPlatform() == Common::kPlatformAmiga) {
diff --git a/engines/queen/graphics.cpp b/engines/queen/graphics.cpp
index 059cf5a4d1c..ff7352118f6 100644
--- a/engines/queen/graphics.cpp
+++ b/engines/queen/graphics.cpp
@@ -672,7 +672,7 @@ void Graphics::setupNewRoom(const char *room, uint16 roomNum, int16 *furniture,
 
 	// load/setup objects associated to this room
 	char filename[20];
-	sprintf(filename, "%s.BBK", room);
+	Common::sprintf_s(filename, "%s.BBK", room);
 	_vm->bankMan()->load(filename, 15);
 
 	_numFrames = FRAMES_JOE + 1;
diff --git a/engines/queen/journal.cpp b/engines/queen/journal.cpp
index 189c0df3446..a462729f8de 100644
--- a/engines/queen/journal.cpp
+++ b/engines/queen/journal.cpp
@@ -182,7 +182,7 @@ void Journal::drawSaveDescriptions() {
 	for (int i = 0; i < NUM_SAVES_PER_PAGE; ++i) {
 		int n = _currentSavePage * 10 + i;
 		char nb[4];
-		sprintf(nb, "%d", n + 1);
+		Common::sprintf_s(nb, "%d", n + 1);
 		int y = _textField.y + i * _textField.h;
 		_vm->display()->setText(_textField.x, y, _saveDescriptions[n], false);
 		_vm->display()->setText(_textField.x - 27, y + 1, nb, false);
@@ -537,7 +537,7 @@ void Journal::drawInfoPanel() {
 		break;
 	}
 	char versionId[13];
-	sprintf(versionId, "Version %c.%c%c", ver[2], ver[3], ver[4]);
+	Common::sprintf_s(versionId, "Version %c.%c%c", ver[2], ver[3], ver[4]);
 	_vm->display()->setTextCentered(156, versionId, false);
 }
 
diff --git a/engines/queen/logic.cpp b/engines/queen/logic.cpp
index c6af9ea35dd..1b43a20ea7a 100644
--- a/engines/queen/logic.cpp
+++ b/engines/queen/logic.cpp
@@ -853,7 +853,7 @@ void Logic::makeJoeSpeak(uint16 descNum, bool objectType) {
 		descNum += JOE_RESPONSE_MAX;
 	}
 	char descFilePrefix[10];
-	sprintf(descFilePrefix, "JOE%04i", descNum);
+	Common::sprintf_s(descFilePrefix, "JOE%04i", descNum);
 	makePersonSpeak(text, nullptr, descFilePrefix);
 }
 
diff --git a/engines/queen/resource.cpp b/engines/queen/resource.cpp
index 7459161b01f..54bbf31baf2 100644
--- a/engines/queen/resource.cpp
+++ b/engines/queen/resource.cpp
@@ -254,7 +254,7 @@ void Resource::seekResourceFile(int num, uint32 offset) {
 		debug(7, "Opening resource file %d, current %d", num, _currentResourceFileNum);
 		_resourceFile.close();
 		char name[20];
-		sprintf(name, "queen.%d", num);
+		Common::sprintf_s(name, "queen.%d", num);
 		if (!_resourceFile.open(name)) {
 			error("Could not open resource file '%s'", name);
 		}
diff --git a/engines/queen/sound.cpp b/engines/queen/sound.cpp
index a0874c34366..d1ee196bb6f 100644
--- a/engines/queen/sound.cpp
+++ b/engines/queen/sound.cpp
@@ -608,7 +608,7 @@ void AmigaSound::updateMusic() {
 void AmigaSound::playSound(const char *base) {
 	debug(7, "AmigaSound::playSound(%s)", base);
 	char soundName[20];
-	sprintf(soundName, "%s.AMR", base);
+	Common::sprintf_s(soundName, "%s.AMR", base);
 
 	uint32 soundSize;
 	Common::File *f = _vm->resource()->findSound(soundName, &soundSize);
@@ -629,13 +629,13 @@ Audio::AudioStream *AmigaSound::loadModule(const char *base, int num) {
 
 	// load song/pattern data
 	uint32 sngDataSize;
-	sprintf(name, "%s.SNG", base);
+	Common::sprintf_s(name, "%s.SNG", base);
 	uint8 *sngData = _vm->resource()->loadFile(name, 0, &sngDataSize);
 	Common::MemoryReadStream sngStr(sngData, sngDataSize);
 
 	// load instruments/wave data
 	uint32 insDataSize;
-	sprintf(name, "%s.INS", base);
+	Common::sprintf_s(name, "%s.INS", base);
 	uint8 *insData = _vm->resource()->loadFile(name, 0, &insDataSize);
 	Common::MemoryReadStream insStr(insData, insDataSize);
 
diff --git a/engines/queen/talk.cpp b/engines/queen/talk.cpp
index 2c8148339d2..1484096e6a3 100644
--- a/engines/queen/talk.cpp
+++ b/engines/queen/talk.cpp
@@ -132,13 +132,13 @@ void Talk::talk(const char *filename, int personInRoom, char *cutawayFilename) {
 			findDialogueString(_person1PtrOff, head, _pMax, _talkString[0]);
 
 		if (hasTalkedTo() && head == 1)
-			sprintf(otherVoiceFilePrefix, "%2dXXXXP", _talkKey);
+			Common::sprintf_s(otherVoiceFilePrefix, "%2dXXXXP", _talkKey);
 		else
-			sprintf(otherVoiceFilePrefix, "%2d%4xP", _talkKey, head);
+			Common::sprintf_s(otherVoiceFilePrefix, "%2d%4xP", _talkKey, head);
 
 		if (_talkString[0][0] == '\0' && retval > 1) {
 			findDialogueString(_person1PtrOff, retval, _pMax, _talkString[0]);
-			sprintf(otherVoiceFilePrefix,"%2d%4xP", _talkKey, retval);
+			Common::sprintf_s(otherVoiceFilePrefix,"%2d%4xP", _talkKey, retval);
 		}
 
 		// Joe dialogue
@@ -151,7 +151,7 @@ void Talk::talk(const char *filename, int personInRoom, char *cutawayFilename) {
 			if (index < 0 && _vm->logic()->gameState(ABS(index)) != _dialogueTree[level][i].gameStateValue)
 				_talkString[i][0] = '\0';
 
-			sprintf(_joeVoiceFilePrefix[i], "%2d%4xJ", _talkKey, _dialogueTree[level][i].head);
+			Common::sprintf_s(_joeVoiceFilePrefix[i], "%2d%4xJ", _talkKey, _dialogueTree[level][i].head);
 		}
 
 		// Check to see if (all the dialogue options have been selected.
@@ -247,7 +247,7 @@ void Talk::talk(const char *filename, int personInRoom, char *cutawayFilename) {
 		if (-1 == retval) {
 			findDialogueString(_person1PtrOff, head, _pMax, _talkString[0]);
 			if (_talkString[0][0] != '\0') {
-				sprintf(otherVoiceFilePrefix, "%2d%4xP", _talkKey, head);
+				Common::sprintf_s(otherVoiceFilePrefix, "%2d%4xP", _talkKey, head);
 				speak(_talkString[0], &person, otherVoiceFilePrefix);
 			}
 		}
@@ -435,14 +435,14 @@ void Talk::initialTalk() {
 		// Not yet talked to this person
 		if (joeString[0] != '0') {
 			char voiceFilePrefix[MAX_STRING_SIZE];
-			sprintf(voiceFilePrefix, "%2dSSSSJ", _talkKey);
+			Common::sprintf_s(voiceFilePrefix, "%2dSSSSJ", _talkKey);
 			speak(joeString, nullptr, voiceFilePrefix);
 		}
 	} else {
 		// Already spoken to them, choose second response
 		if (joe2String[0] != '0') {
 			char voiceFilePrefix[MAX_STRING_SIZE];
-			sprintf(voiceFilePrefix, "%2dXXXXJ", _talkKey);
+			Common::sprintf_s(voiceFilePrefix, "%2dXXXXJ", _talkKey);
 			speak(joe2String, nullptr, voiceFilePrefix);
 		}
 	}
@@ -789,7 +789,7 @@ void Talk::speakSegment(
 	segment[length] = '\0';
 
 	char voiceFileName[MAX_STRING_SIZE];
-	sprintf(voiceFileName, "%s%1x", voiceFilePrefix, index + 1);
+	Common::sprintf_s(voiceFileName, "%s%1x", voiceFilePrefix, index + 1);
 
 	// French talkie version has a useless voice file ;	c30e_102 file is the same as c30e_101,
 	// so there is no need to play it. This voice was used in room 30 (N8) when talking to Klunk.


Commit: d5b55b667fd9cf9f28a0bab361be1a43b476bfb3
    https://github.com/scummvm/scummvm/commit/d5b55b667fd9cf9f28a0bab361be1a43b476bfb3
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SAGA: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/saga/metaengine.cpp
    engines/saga/music.cpp
    engines/saga/puzzle.cpp
    engines/saga/render.cpp
    engines/saga/resource.cpp
    engines/saga/saveload.cpp
    engines/saga/sndres.cpp


diff --git a/engines/saga/metaengine.cpp b/engines/saga/metaengine.cpp
index 42047029251..5071bae263d 100644
--- a/engines/saga/metaengine.cpp
+++ b/engines/saga/metaengine.cpp
@@ -163,7 +163,7 @@ void SagaMetaEngine::removeSaveState(const char *target, int slot) const {
 
 SaveStateDescriptor SagaMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
 	static char fileName[MAX_FILE_NAME];
-	sprintf(fileName, "%s.s%02d", target, slot);
+	Common::sprintf_s(fileName, "%s.s%02d", target, slot);
 	char title[TITLESIZE];
 
 	Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName);
diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp
index 4854299a03d..222ead0e2ec 100644
--- a/engines/saga/music.cpp
+++ b/engines/saga/music.cpp
@@ -357,8 +357,8 @@ bool Music::playDigital(uint32 resourceId, MusicFlags flags) {
 
 	// Try to open standalone digital track
 	char trackName[2][16];
-	sprintf(trackName[0], "track%d", realTrackNumber);
-	sprintf(trackName[1], "track%02d", realTrackNumber);
+	Common::sprintf_s(trackName[0], "track%d", realTrackNumber);
+	Common::sprintf_s(trackName[1], "track%02d", realTrackNumber);
 	Audio::SeekableAudioStream *stream = nullptr;
 	for (int i = 0; i < 2; ++i) {
 		stream = Audio::SeekableAudioStream::openStreamFile(trackName[i]);
diff --git a/engines/saga/puzzle.cpp b/engines/saga/puzzle.cpp
index 3fbf419bc98..d69fbf5c3ca 100644
--- a/engines/saga/puzzle.cpp
+++ b/engines/saga/puzzle.cpp
@@ -554,7 +554,7 @@ void Puzzle::giveHint() {
 		if (i >= 0) {
 			static char hintBuf[64];
 			static const char *hintPtr = hintBuf;
-			sprintf(hintBuf, optionsStr[_lang][kROHint], pieceNames[_lang][piece]);
+			Common::sprintf_s(hintBuf, optionsStr[_lang][kROHint], pieceNames[_lang][piece]);
 
 			_vm->_actor->nonActorSpeech(_hintBox, &hintPtr, 1, PUZZLE_TOOL_SOUNDS + _hintSpeaker + piece * 3, 0);
 		} else {
diff --git a/engines/saga/render.cpp b/engines/saga/render.cpp
index 14ee09a1f83..bf10535c3e4 100644
--- a/engines/saga/render.cpp
+++ b/engines/saga/render.cpp
@@ -170,7 +170,7 @@ void Render::drawScene() {
 	// Display rendering information
 	if (_flags & RF_SHOW_FPS) {
 		char txtBuffer[20];
-		sprintf(txtBuffer, "%d", _fps);
+		Common::sprintf_s(txtBuffer, "%d", _fps);
 		textPoint.x = _vm->_gfx->getBackBufferWidth() - _vm->_font->getStringWidth(kKnownFontSmall, txtBuffer, 0, kFontOutline);
 		textPoint.y = 2;
 
diff --git a/engines/saga/resource.cpp b/engines/saga/resource.cpp
index 66459092ea9..8de7718101a 100644
--- a/engines/saga/resource.cpp
+++ b/engines/saga/resource.cpp
@@ -238,7 +238,7 @@ bool Resource::createContexts() {
 			!scumm_stricmp(curSoundFile->fileName, "voicess.cmp")) {
 				// IHNM has multiple voice files
 				for (size_t i = 1; i <= 6; i++) { // voices1-voices6
-					sprintf(_voicesFileName[i], "voices%i.%s", (uint)i, curSoundFile->isCompressed ? "cmp" : "res");
+					Common::sprintf_s(_voicesFileName[i], "voices%i.%s", (uint)i, curSoundFile->isCompressed ? "cmp" : "res");
 					if (i == 4) {
 						// The German and French versions of IHNM don't have Nimdok's chapter,
 						// therefore the voices file for that chapter is missing
diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp
index 3c08c95e3b7..577af0aa729 100644
--- a/engines/saga/saveload.cpp
+++ b/engines/saga/saveload.cpp
@@ -43,7 +43,7 @@ static SaveFileData emptySlot = {
 
 char* SagaEngine::calcSaveFileName(uint slotNumber) {
 	static char name[MAX_FILE_NAME];
-	sprintf(name, "%s.s%02u", _targetName.c_str(), slotNumber);
+	Common::sprintf_s(name, "%s.s%02u", _targetName.c_str(), slotNumber);
 	return name;
 }
 
diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp
index 6d0bbe1a5f0..f7bb03d4fae 100644
--- a/engines/saga/sndres.cpp
+++ b/engines/saga/sndres.cpp
@@ -207,12 +207,12 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
 
 		if ((context->fileType() & GAME_VOICEFILE) != 0) {
 			if (_voiceSerial == 0) {
-				sprintf(soundFileName, "Voices/VoicesS/Voices%d/VoicesS%03x", dirIndex, resourceId);
+				Common::sprintf_s(soundFileName, "Voices/VoicesS/Voices%d/VoicesS%03x", dirIndex, resourceId);
 			} else {
-				sprintf(soundFileName, "Voices/Voices%d/Voices%d/Voices%d%03x", _voiceSerial, dirIndex, _voiceSerial, resourceId);
+				Common::sprintf_s(soundFileName, "Voices/Voices%d/Voices%d/Voices%d%03x", _voiceSerial, dirIndex, _voiceSerial, resourceId);
 			}
 		} else {
-			sprintf(soundFileName, "SFX/SFX%d/SFX%03x", dirIndex, resourceId);
+			Common::sprintf_s(soundFileName, "SFX/SFX%d/SFX%03x", dirIndex, resourceId);
 		}
 
 		file = new Common::File();


Commit: 707c71ecf93475581840c43b292fc0084b6ab18e
    https://github.com/scummvm/scummvm/commit/707c71ecf93475581840c43b292fc0084b6ab18e
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SAGA2: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/saga2/contain.cpp
    engines/saga2/document.cpp
    engines/saga2/gamerate.h
    engines/saga2/grequest.cpp
    engines/saga2/intrface.cpp
    engines/saga2/main.cpp
    engines/saga2/mapfeatr.cpp
    engines/saga2/messager.cpp
    engines/saga2/mouseimg.cpp
    engines/saga2/msgbox.cpp
    engines/saga2/objects.cpp
    engines/saga2/speech.cpp
    engines/saga2/uidialog.cpp


diff --git a/engines/saga2/contain.cpp b/engines/saga2/contain.cpp
index 134aa1661b1..8a913c94b86 100644
--- a/engines/saga2/contain.cpp
+++ b/engines/saga2/contain.cpp
@@ -399,7 +399,7 @@ void ContainerView::drawSelector(gPort &port, Point16 &pos) {
 	drawCompressedImage(port, pos, g_vm->_cnm->_selImage);
 
 	// draw the number of items selected thus far
-	num = sprintf(buf, " %d ", g_vm->_cnm->_numPicked);
+	num = Common::sprintf_s(buf, " %d ", g_vm->_cnm->_numPicked);
 
 	port.moveTo(Point16(pos.x - ((3 * (num - 3)) + 1),  pos.y + 7));
 	port.setFont(&Helv11Font);
@@ -428,7 +428,7 @@ void ContainerView::drawQuantity(
 		char buf[8];
 
 		// draw the number of items selected thus far
-		sprintf(buf, "%d", quantity);
+		Common::sprintf_s(buf, "%d", quantity);
 
 		port.moveTo(x - 1,  y + 22);
 		port.setFont(&Helv11Font);
@@ -1837,15 +1837,15 @@ APPFUNC(cmdMindContainerFunc) {
 
 			switch (_mindType) {
 			case 0:
-				sprintf(textBuffer, IDEAS_MENTAL);
+				Common::sprintf_s(textBuffer, IDEAS_MENTAL);
 				break;
 
 			case 1:
-				sprintf(textBuffer, SPELL_MENTAL);
+				Common::sprintf_s(textBuffer, SPELL_MENTAL);
 				break;
 
 			case 2:
-				sprintf(textBuffer, SKILL_MENTAL);
+				Common::sprintf_s(textBuffer, SKILL_MENTAL);
 				break;
 
 			case -1:
diff --git a/engines/saga2/document.cpp b/engines/saga2/document.cpp
index febc26bdfce..c75d28a2924 100644
--- a/engines/saga2/document.cpp
+++ b/engines/saga2/document.cpp
@@ -711,7 +711,7 @@ void buildText(uint16 textScript) {
 		//  Run the script
 		runScript(textScript, scf);
 	} else {
-		sprintf(bookText, "Invalid textScript: %d", textScript);
+		Common::sprintf_s(bookText, "Invalid textScript: %d", textScript);
 	}
 }
 
diff --git a/engines/saga2/gamerate.h b/engines/saga2/gamerate.h
index 52478f52350..bc07374990f 100644
--- a/engines/saga2/gamerate.h
+++ b/engines/saga2/gamerate.h
@@ -60,11 +60,6 @@ public:
 	virtual float frameStat(int statID = grFramesPerSecond) {
 		return _instantFrameCount;
 	}
-
-	virtual void whatDoYouKnow(char *buf) {
-		sprintf(buf, "FPS: %02.2f", frameStat());
-	}
-
 };
 
 
@@ -206,18 +201,6 @@ public:
 			return frameCounter::frameStat(statID);
 		}
 	}
-
-	virtual void whatDoYouKnow(char *buf) {
-		float f[15];
-		for (int i = 0; i < 15; i++) {
-			f[i] = MAX((float) -99, MIN((float)99, (float)(((float) frameStat(i + 1)) / ((float) 1000))));
-		}
-		sprintf(buf, "Imm: %02.2f  1 Sec %02.2f | %02.2f  5 Sec %02.2f | %02.2f"
-		        //"  -(%2.2f  %2.2f  %2.2f,%2.2f,%2.2f,%2.2f,%2.2f)",
-		        , f[0],  f[1], f[8], f[6], f[13]);
-		//, f[3], f[4], f[5],
-		//                  f[13],f[14], f[8],f[9],f[10],f[11],f[12]);
-	}
 };
 
 frameSmoother::frameSmoother(int32 fps, uint32 perSec, uint32 now)
diff --git a/engines/saga2/grequest.cpp b/engines/saga2/grequest.cpp
index 98254a425b6..2f1cae92807 100644
--- a/engines/saga2/grequest.cpp
+++ b/engines/saga2/grequest.cpp
@@ -121,7 +121,7 @@ void ModalDialogWindow::positionText(
 		int16   fontHeight = mainFont->height;
 
 		// make a copy of the window text string
-		vsprintf(_titleBuf, windowText, args);
+		Common::vsprintf_s(_titleBuf, windowText, args);
 
 		//  break up the title text string
 		_titleCount = SplitString(_titleBuf, _titleStrings, maxLines, '\n');
diff --git a/engines/saga2/intrface.cpp b/engines/saga2/intrface.cpp
index cf48710e187..7b16ddd7e02 100644
--- a/engines/saga2/intrface.cpp
+++ b/engines/saga2/intrface.cpp
@@ -1348,7 +1348,7 @@ void writePlaqText(gPort            &port,
 	gFont           *_oldFont = port._font;
 
 	va_start(argptr, msg);
-	cnt = vsprintf(lineBuf, msg, argptr);
+	cnt = Common::vsprintf_s(lineBuf, msg, argptr);
 	va_end(argptr);
 
 	SAVE_GPORT_STATE(port);
@@ -1399,7 +1399,7 @@ void writePlaqTextPos(gPort         &port,
 	gFont           *_oldFont = port._font;
 
 	va_start(argptr, msg);
-	vsprintf(lineBuf, msg, argptr);
+	Common::vsprintf_s(lineBuf, msg, argptr);
 	va_end(argptr);
 
 	SAVE_GPORT_STATE(port);
@@ -2155,13 +2155,13 @@ APPFUNC(cmdPortrait) {
 
 				switch (brotherID) {
 				case uiJulian:
-					sprintf(buf, "%s %s", JULIAN_BROSTATE, state);
+					Common::sprintf_s(buf, "%s %s", JULIAN_BROSTATE, state);
 					break;
 				case uiPhillip:
-					sprintf(buf, "%s %s", PHILLIP_BROSTATE, state);
+					Common::sprintf_s(buf, "%s %s", PHILLIP_BROSTATE, state);
 					break;
 				case uiKevin:
-					sprintf(buf, "%s %s", KEVIN_BROSTATE, state);
+					Common::sprintf_s(buf, "%s %s", KEVIN_BROSTATE, state);
 					break;
 				}
 				// set the text in the cursor
@@ -2241,7 +2241,7 @@ APPFUNC(cmdArmor) {
 			        &&  gai->_attr.defenseBonus == 0) {
 				g_vm->_mouseInfo->setText(NO_ARMOR);
 			} else {
-				sprintf(buf,
+				Common::sprintf_s(buf,
 				        DESC_ARMOR,
 				        gai->_attr.damageAbsorbtion,
 				        gai->_attr.damageDivider,
@@ -2345,13 +2345,13 @@ APPFUNC(cmdBroChange) {
 
 			switch (brotherID) {
 			case uiJulian:
-				sprintf(buf, "%s %s", JULIAN_BROSTATE, state);
+				Common::sprintf_s(buf, "%s %s", JULIAN_BROSTATE, state);
 				break;
 			case uiPhillip:
-				sprintf(buf, "%s %s", PHILLIP_BROSTATE, state);
+				Common::sprintf_s(buf, "%s %s", PHILLIP_BROSTATE, state);
 				break;
 			case uiKevin:
-				sprintf(buf, "%s %s", KEVIN_BROSTATE, state);
+				Common::sprintf_s(buf, "%s %s", KEVIN_BROSTATE, state);
 				break;
 			}
 			// set the text in the cursor
@@ -2381,7 +2381,7 @@ APPFUNC(cmdHealthStar) {
 
 		char buf[40];
 
-		sprintf(buf, "%s %d/%d", HEALTH_HINT, currVitality, baseVitality);
+		Common::sprintf_s(buf, "%s %d/%d", HEALTH_HINT, currVitality, baseVitality);
 		g_vm->_mouseInfo->setText(buf);
 	}
 }
@@ -2413,7 +2413,7 @@ APPFUNC(cmdMassInd) {
 			curWeight = getWeightRatio(_containerObject, baseWeight);
 
 			if (baseWeight != unlimitedCapacity) {
-				sprintf(buf, "%s %d/%d", WEIGHT_HINT, curWeight, baseWeight);
+				Common::sprintf_s(buf, "%s %d/%d", WEIGHT_HINT, curWeight, baseWeight);
 				g_vm->_mouseInfo->setText(buf);
 			} else
 				g_vm->_mouseInfo->setText(UNK_WEIGHT_HINT);
@@ -2451,7 +2451,7 @@ APPFUNC(cmdBulkInd) {
 			curBulk = getBulkRatio(_containerObject, baseBulk);
 
 			if (baseBulk != unlimitedCapacity) {
-				sprintf(buf, "%s %d/%d", BULK_HINT, curBulk, baseBulk);
+				Common::sprintf_s(buf, "%s %d/%d", BULK_HINT, curBulk, baseBulk);
 				g_vm->_mouseInfo->setText(buf);
 			} else
 				g_vm->_mouseInfo->setText(UNK_BULK_HINT);
@@ -2494,27 +2494,27 @@ APPFUNC(cmdManaInd) {
 
 			switch (manaType) {
 			case 0:
-				sprintf(textBuffer, "%s %d/%d", "Red Mana:", curMana, baseMana);
+				Common::sprintf_s(textBuffer, "%s %d/%d", "Red Mana:", curMana, baseMana);
 				break;
 
 			case 1:
-				sprintf(textBuffer, "%s %d/%d", "Orange Mana:", curMana, baseMana);
+				Common::sprintf_s(textBuffer, "%s %d/%d", "Orange Mana:", curMana, baseMana);
 				break;
 
 			case 2:
-				sprintf(textBuffer, "%s %d/%d", "Yellow Mana:", curMana, baseMana);
+				Common::sprintf_s(textBuffer, "%s %d/%d", "Yellow Mana:", curMana, baseMana);
 				break;
 
 			case 3:
-				sprintf(textBuffer, "%s %d/%d", "Green Mana:", curMana, baseMana);
+				Common::sprintf_s(textBuffer, "%s %d/%d", "Green Mana:", curMana, baseMana);
 				break;
 
 			case 4:
-				sprintf(textBuffer, "%s %d/%d", "Blue Mana:", curMana, baseMana);
+				Common::sprintf_s(textBuffer, "%s %d/%d", "Blue Mana:", curMana, baseMana);
 				break;
 
 			case 5:
-				sprintf(textBuffer, "%s %d/%d", "Purple Mana:", curMana, baseMana);
+				Common::sprintf_s(textBuffer, "%s %d/%d", "Purple Mana:", curMana, baseMana);
 				break;
 
 			case -1:
@@ -2618,17 +2618,17 @@ void gArmorIndicator::drawClipped(gPort &port,
 			port.setMode(drawModeMatte);
 
 			if (_attr.damageAbsorbtion == 0 && _attr.defenseBonus == 0)
-				sprintf(buf, "-");
+				Common::sprintf_s(buf, "-");
 			else if (_attr.damageDivider > 1)
-				sprintf(buf, "%d/%d", _attr.damageAbsorbtion, _attr.damageDivider);
-			else sprintf(buf, "%d", _attr.damageAbsorbtion);
+				Common::sprintf_s(buf, "%d/%d", _attr.damageAbsorbtion, _attr.damageDivider);
+			else Common::sprintf_s(buf, "%d", _attr.damageAbsorbtion);
 
 			port.drawTextInBox(buf, -1, Rect16(pos.x, pos.y, _extent.width, _extent.height),
 			                   textPosRight | textPosHigh, Point16(0,  2));
 
 			if (_attr.damageAbsorbtion == 0 && _attr.defenseBonus == 0)
-				sprintf(buf, "-");
-			else sprintf(buf, "%d", _attr.defenseBonus);
+				Common::sprintf_s(buf, "-");
+			else Common::sprintf_s(buf, "%d", _attr.defenseBonus);
 			port.drawTextInBox(buf, -1, Rect16(pos.x, pos.y, _extent.width, _extent.height),
 			                   textPosRight | textPosLow, Point16(0,  2));
 		}
@@ -2671,8 +2671,8 @@ void gEnchantmentDisplay::pointerMove(gPanelMessage &msg) {
 					char    buf[128];
 
 					if (_iconFlags[i] == 255)
-						sprintf(buf, "%s", enchantmentNames[i]);
-					else sprintf(buf, "%s : %d", enchantmentNames[i], _iconFlags[i]);
+						Common::sprintf_s(buf, "%s", enchantmentNames[i]);
+					else Common::sprintf_s(buf, "%s : %d", enchantmentNames[i], _iconFlags[i]);
 					g_vm->_mouseInfo->setText(buf);
 					return;
 				}
@@ -2954,7 +2954,7 @@ void StatusMsg(const char *msg, ...) { // frametime def
 
 	if (StatusLine) {
 		va_start(argptr, msg);
-		vsprintf(buffer, msg, argptr);
+		Common::vsprintf_s(buffer, msg, argptr);
 		va_end(argptr);
 
 		StatusLine->setLine(buffer, 500);
diff --git a/engines/saga2/main.cpp b/engines/saga2/main.cpp
index 4451ab92c34..e42927ac786 100644
--- a/engines/saga2/main.cpp
+++ b/engines/saga2/main.cpp
@@ -736,11 +736,11 @@ bool initGUIMessagers() {
 	initUserDialog();
 	for (int i = 0; i < 10; i++) {
 		char debItem[16];
-		sprintf(debItem, "Status%1.1d", i);
+		Common::sprintf_s(debItem, "Status%1.1d", i);
 		Status[i] = new StatusLineMessager(debItem, i, &g_vm->_mainPort);
 		if (Status[i] == nullptr)
 			return false;
-		sprintf(debItem, "Status%2.2d", i + 10);
+		Common::sprintf_s(debItem, "Status%2.2d", i + 10);
 		Status2[i] = new StatusLineMessager(debItem, i, &g_vm->_mainPort, 20, 21 + (11 * i));
 	}
 	for (int j = 0; j < 3; j++)
diff --git a/engines/saga2/mapfeatr.cpp b/engines/saga2/mapfeatr.cpp
index 66087ad650d..fbdfb830f69 100644
--- a/engines/saga2/mapfeatr.cpp
+++ b/engines/saga2/mapfeatr.cpp
@@ -337,12 +337,12 @@ void CMapFeature::draw(TileRegion viewRegion,
 #ifdef DEBUG_FEATUREPOS
 	else {
 		char msg[256];
-		sprintf(msg, "Hide: ");
+		Common::sprintf_s(msg, "Hide: ");
 		if (!visible) Common::strcat_s(msg, "not visible");
-		if (!(fCoords.u >= viewRegion.min.u)) sprintf(msg + strlen(msg), "U lo %d,%d ", fCoords.u, viewRegion.min.u);
-		if (!(fCoords.u <= viewRegion.max.u)) sprintf(msg + strlen(msg), "U hi %d,%d ", fCoords.u, viewRegion.max.u);
-		if (!(fCoords.v >= viewRegion.min.v)) sprintf(msg + strlen(msg), "V lo %d,%d ", fCoords.v, viewRegion.min.v);
-		if (!(fCoords.v <= viewRegion.max.v)) sprintf(msg + strlen(msg), "V hi %d,%d ", fCoords.v, viewRegion.max.v);
+		if (!(fCoords.u >= viewRegion.min.u)) Common::sprintf_s(msg + strlen(msg), "U lo %d,%d ", fCoords.u, viewRegion.min.u);
+		if (!(fCoords.u <= viewRegion.max.u)) Common::sprintf_s(msg + strlen(msg), "U hi %d,%d ", fCoords.u, viewRegion.max.u);
+		if (!(fCoords.v >= viewRegion.min.v)) Common::sprintf_s(msg + strlen(msg), "V lo %d,%d ", fCoords.v, viewRegion.min.v);
+		if (!(fCoords.v <= viewRegion.max.v)) Common::sprintf_s(msg + strlen(msg), "V hi %d,%d ", fCoords.v, viewRegion.max.v);
 		WriteStatusF(12, "%s", msg);
 	}
 #endif
diff --git a/engines/saga2/messager.cpp b/engines/saga2/messager.cpp
index 67fb584e1f8..152e22ef9e7 100644
--- a/engines/saga2/messager.cpp
+++ b/engines/saga2/messager.cpp
@@ -34,10 +34,11 @@ size_t Messager::va(const char *format, va_list argptr) {
 		char tempBuf[256];
 		size_t size;
 
-		size = vsprintf((char *) tempBuf, format, argptr);
+		size = Common::vsprintf_s(tempBuf, format, argptr);
 
 		if (size) {
-			if (tempBuf[size - 1] != '\n') {
+			if ((size < sizeof(tempBuf) - 2) &&
+				tempBuf[size - 1] != '\n') {
 				tempBuf[size++] = '\n';
 				tempBuf[size] = '\0';
 			}
diff --git a/engines/saga2/mouseimg.cpp b/engines/saga2/mouseimg.cpp
index 9eea9d68c15..f328482f524 100644
--- a/engines/saga2/mouseimg.cpp
+++ b/engines/saga2/mouseimg.cpp
@@ -360,7 +360,7 @@ void setMouseTextF(char *format, ...) {
 		va_list     argptr;
 
 		va_start(argptr, format);
-		vsprintf(lineBuf, format, argptr);
+		Common::vsprintf_s(lineBuf, format, argptr);
 		va_end(argptr);
 
 		setMouseText(lineBuf);
diff --git a/engines/saga2/msgbox.cpp b/engines/saga2/msgbox.cpp
index 135e0903523..63ae2821ff6 100644
--- a/engines/saga2/msgbox.cpp
+++ b/engines/saga2/msgbox.cpp
@@ -277,7 +277,7 @@ void SimpleWindow::writeWrappedPlaqText(gPort           &port,
 	Rect16          r2 = r;
 
 	va_start(argptr, msg);
-	int cnt = vsprintf(textBuf, msg, argptr);
+	int cnt = Common::vsprintf_s(textBuf, msg, argptr);
 	va_end(argptr);
 
 	char *text = &textBuf[0];
diff --git a/engines/saga2/objects.cpp b/engines/saga2/objects.cpp
index a47514a0d7f..8402c136cc7 100644
--- a/engines/saga2/objects.cpp
+++ b/engines/saga2/objects.cpp
@@ -624,9 +624,9 @@ void GameObject::objCursorText(char nameBuf[], const int8 size, int16 count) {
 			uint16 charges = _data.bParam;
 
 			if (charges == 1) {
-				sprintf(nameBuf, SINGLE_CHARGE, objName(), charges);
+				Common::sprintf_s(nameBuf, size, SINGLE_CHARGE, objName(), charges);
 			} else {
-				sprintf(nameBuf, MULTI_CHARGE, objName(), charges);      // get the count
+				Common::sprintf_s(nameBuf, size, MULTI_CHARGE, objName(), charges);      // get the count
 			}
 		}
 
@@ -637,10 +637,10 @@ void GameObject::objCursorText(char nameBuf[], const int8 size, int16 count) {
 			if (_data.massCount != 1) {
 				if (count != -1) {
 					if (count != 1) {
-						sprintf(nameBuf, PLURAL_DESC, count, objName());     // get the count
+						Common::sprintf_s(nameBuf, size, PLURAL_DESC, count, objName());     // get the count
 					}
 				} else {
-					sprintf(nameBuf, PLURAL_DESC, _data.massCount, objName());     // get the count
+					Common::sprintf_s(nameBuf, size, PLURAL_DESC, _data.massCount, objName());     // get the count
 				}
 			}
 		}
@@ -674,7 +674,7 @@ void GameObject::objCursorText(char nameBuf[], const int8 size, int16 count) {
 				level = g_vm->_playerList[brotherID - ActorBaseID]->getSkillLevel(sProto);
 
 				// normalize and output
-				sprintf(nameBuf, "%s-%d", objName(), ++level);
+				Common::sprintf_s(nameBuf, size, "%s-%d", objName(), ++level);
 			}
 		} else if (manaColor >= sManaIDRed
 		           &&  manaColor <= sManaIDViolet  //  A spell
@@ -690,7 +690,7 @@ void GameObject::objCursorText(char nameBuf[], const int8 size, int16 count) {
 
 				manaAmount      = player->getEffStats()->mana(manaColor);
 
-				sprintf(nameBuf, "%s [x%d]", objName(), manaAmount / manaCost);
+				Common::sprintf_s(nameBuf, size, "%s [x%d]", objName(), manaAmount / manaCost);
 			}
 		}
 	}
diff --git a/engines/saga2/speech.cpp b/engines/saga2/speech.cpp
index a50386a8cdb..b164c51d434 100644
--- a/engines/saga2/speech.cpp
+++ b/engines/saga2/speech.cpp
@@ -118,7 +118,7 @@ extern gPanelList   *speakButtonControls;   // controls for embedded speech butt
 static char convBuf[5];
 
 inline uint32 extendID(int16 smallID) {
-	sprintf(convBuf, "%4.4d", smallID);
+	Common::sprintf_s(convBuf, "%4.4d", smallID);
 	return smallID ? MKTAG(convBuf[0] + 'A' - '0', convBuf[1], convBuf[2], convBuf[3]) : 0 ;
 }
 
diff --git a/engines/saga2/uidialog.cpp b/engines/saga2/uidialog.cpp
index 056b6f21f13..b1e6e373c7a 100644
--- a/engines/saga2/uidialog.cpp
+++ b/engines/saga2/uidialog.cpp
@@ -1274,7 +1274,7 @@ void CPlacardWindow::positionText(
 		int16   fontHeight = _textFont->height;
 
 		// make a copy of the window text string
-		sprintf(_titleBuf, "%s", windowText);
+		Common::sprintf_s(_titleBuf, "%s", windowText);
 
 		//  break up the title text string
 		_titleCount = SplitString(_titleBuf, _titleStrings, maxLines, '\n');
@@ -1385,7 +1385,7 @@ void CPlacardPanel::positionText(const char *windowText, const Rect16 &textArea)
 		int16   fontHeight = _buttonFont->height;
 
 		// make a copy of the window text string
-		sprintf(_titleBuf, "%s", windowText);
+		Common::sprintf_s(_titleBuf, "%s", windowText);
 
 		//  break up the title text string
 		_titleCount = SplitString(_titleBuf, _titleStrings, maxLines, '\n');


Commit: f54bdf989a1153ddba81653da7ff1a02fa7514f4
    https://github.com/scummvm/scummvm/commit/f54bdf989a1153ddba81653da7ff1a02fa7514f4
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SCI: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/sci/console.cpp
    engines/sci/engine/kstring.cpp


diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index dee07f95154..4bb14bc0d07 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -600,7 +600,7 @@ bool Console::cmdSelectors(int argc, const char **argv) {
 	uint seeker = 0;
 	while (seeker < totalSize) {
 		selName = "\"" + _engine->getKernel()->getSelectorName(seeker) + "\"";
-		sprintf(buf, "%15s, ", selName.c_str());
+		Common::sprintf_s(buf, "%15s, ", selName.c_str());
 		outFile->writeString(buf);
 
 		if (!((seeker + 1) % 5) && seeker)
@@ -793,7 +793,7 @@ void Console::cmdDiskDumpWorker(ResourceType resourceType, int resourceNumber, u
 	case kResourceTypeSync36: {
 		resourceId = ResourceId(resourceType, resourceNumber, resourceTuple);
 		resource = _engine->getResMan()->findResource(resourceId, 0);
-		sprintf(outFileName, "%s", resourceId.toPatchNameBase36().c_str());
+		Common::sprintf_s(outFileName, "%s", resourceId.toPatchNameBase36().c_str());
 		// patch filename is: [type:1 char] [map:3 chars] [noun:2 chars] [verb:2 chars] "." [cond: 2 chars] [seq:1 char]
 		//  e.g. "@5EG0000.014"
 		break;
@@ -801,7 +801,7 @@ void Console::cmdDiskDumpWorker(ResourceType resourceType, int resourceNumber, u
 	default:
 		resourceId = ResourceId(resourceType, resourceNumber);
 		resource = _engine->getResMan()->findResource(resourceId, 0);
-		sprintf(outFileName, "%s.%03d", resourceTypeName, resourceNumber);
+		Common::sprintf_s(outFileName, "%s.%03d", resourceTypeName, resourceNumber);
 		// patch filename is: [resourcetype].[resourcenumber]
 		//  e.g. "Script.0"
 		break;
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 083d5ee2a8c..802d4c40916 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -388,7 +388,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
 				if (!unsignedVar)
 					val = (int16)arguments[paramindex];
 
-				target += sprintf(target, format_string, val);
+				target += Common::sprintf_s(target, sizeof(targetbuf) - (target - targetbuf), format_string, val);
 				paramindex++;
 				assert((target - targetbuf) <= maxsize);
 


Commit: 137b51d7ac6704cdb6b9e41246f81cf7822ace6d
    https://github.com/scummvm/scummvm/commit/137b51d7ac6704cdb6b9e41246f81cf7822ace6d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SCUMM: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/scumm/charset.cpp
    engines/scumm/he/script_v72he.cpp
    engines/scumm/he/script_v80he.cpp
    engines/scumm/imuse_digi/dimuse_sndmgr.cpp
    engines/scumm/input.cpp
    engines/scumm/insane/insane_scenes.cpp
    engines/scumm/object.cpp
    engines/scumm/resource.cpp
    engines/scumm/resource_v3.cpp
    engines/scumm/resource_v4.cpp
    engines/scumm/room.cpp
    engines/scumm/saveload.cpp
    engines/scumm/script_v4.cpp
    engines/scumm/smush/smush_player.cpp
    engines/scumm/sound.cpp
    engines/scumm/string.cpp


diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index b8931d1b0a9..7183b144385 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -2072,7 +2072,7 @@ void CharsetRendererNut::setCurID(int32 id) {
 	_curId = id;
 	if (!_fr[id]) {
 		char fontname[11];
-		sprintf(fontname, "font%d.nut", id);
+		Common::sprintf_s(fontname, "font%d.nut", id);
 		_fr[id] = new NutRenderer(_vm, fontname);
 	}
 	_current = _fr[id];
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index b12acea0205..0c2d5394465 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -349,13 +349,13 @@ void ScummEngine_v72he::decodeScriptString(byte *dst, bool scriptString) {
 			chr = string[num++];
 			switch (chr) {
 			case 'b':
-				//dst += sprintf((char *)dst, "%b", args[val++]);
+				//dst += Common::sprintf_s((char *)dst, "%b", args[val++]);
 				break;
 			case 'c':
 				*dst++ = args[val++];
 				break;
 			case 'd':
-				dst += sprintf((char *)dst, "%d", args[val++]);
+				dst += Common::sprintf_s((char *)dst, sizeof(string) - (dst - dst0), "%d", args[val++]);
 				break;
 			case 's':
 				src = getStringAddress(args[val++]);
@@ -365,7 +365,7 @@ void ScummEngine_v72he::decodeScriptString(byte *dst, bool scriptString) {
 				}
 				break;
 			case 'x':
-				dst += sprintf((char *)dst, "%x", args[val++]);
+				dst += Common::sprintf_s((char *)dst, sizeof(string) - (dst - dst0), "%x", args[val++]);
 				break;
 			default:
 				*dst++ = '%';
diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp
index cd8a8661673..7a8d8c3123c 100644
--- a/engines/scumm/he/script_v80he.cpp
+++ b/engines/scumm/he/script_v80he.cpp
@@ -216,7 +216,7 @@ void ScummEngine_v80he::o80_writeConfigFile() {
 	case 43: // HE 100
 	case 6: // number
 		value = pop();
-		sprintf((char *)string, "%d", value);
+		Common::sprintf_s(string, "%d", value);
 		copyScriptString(option, sizeof(option));
 		copyScriptString(section, sizeof(section));
 		copyScriptString(filename, sizeof(filename));
diff --git a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
index 4a87027fe8e..93cf727ddd1 100644
--- a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
@@ -81,7 +81,7 @@ bool ImuseDigiSndMgr::openMusicBundle(SoundDesc *sound, int &disk) {
 			char musicfile[20];
 			if (disk == -1)
 				disk = _vm->VAR(_vm->VAR_CURRENTDISK);
-			sprintf(musicfile, "musdisk%d.bun", disk);
+			Common::sprintf_s(musicfile, "musdisk%d.bun", disk);
 //			if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
 //				_vm->_DiMUSE_v1->parseScriptCmds(0x1000, 0, 0, 0, 0, 0, 0, 0);
 //				_vm->_DiMUSE_v1->parseScriptCmds(0x2000, 0, 0, 0, 0, 0, 0, 0);
@@ -117,7 +117,7 @@ bool ImuseDigiSndMgr::openVoiceBundle(SoundDesc *sound, int &disk) {
 			char voxfile[20];
 			if (disk == -1)
 				disk = _vm->VAR(_vm->VAR_CURRENTDISK);
-			sprintf(voxfile, "voxdisk%d.bun", disk);
+			Common::sprintf_s(voxfile, "voxdisk%d.bun", disk);
 //			if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
 //				_vm->_DiMUSE_v1->parseScriptCmds(0x1000, 0, 0, 0, 0, 0, 0, 0);
 //				_vm->_DiMUSE_v1->parseScriptCmds(0x2000, 0, 0, 0, 0, 0, 0, 0);
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index b9d36092f5d..10c6250ec52 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -831,7 +831,7 @@ void ScummEngine_v3::processKeyboard(Common::KeyState lastKeyHit) {
 
 		updateIQPoints();
 
-		sprintf(text, "IQ Points: Episode = %d, Series = %d", _scummVars[244], _scummVars[245]);
+		Common::sprintf_s(text, "IQ Points: Episode = %d, Series = %d", _scummVars[244], _scummVars[245]);
 		Indy3IQPointsDialog indy3IQPointsDialog(this, text);
 		runDialog(indy3IQPointsDialog);
 	}
diff --git a/engines/scumm/insane/insane_scenes.cpp b/engines/scumm/insane/insane_scenes.cpp
index 067d75aac98..d8dd53e871c 100644
--- a/engines/scumm/insane/insane_scenes.cpp
+++ b/engines/scumm/insane/insane_scenes.cpp
@@ -1055,17 +1055,17 @@ void Insane::postCase16(byte *renderBitmap, int32 codecparam, int32 setupsan12,
 	int32 tmp;
 
 	turnBen(true);
-	sprintf(buf, "^f01%02o", curFrame & 0x3f);
+	Common::sprintf_s(buf, "^f01%02o", curFrame & 0x3f);
 	smlayer_showStatusMsg(-1, renderBitmap, codecparam, 180, 168, 1, 2, 0, "%s", buf);
 	tmp = 400-curFrame;
 
 	if (tmp < 0)
 		tmp += 1300;
 
-	sprintf(buf, "^f01%04d", tmp);
+	Common::sprintf_s(buf, "^f01%04d", tmp);
 	smlayer_showStatusMsg(-1, renderBitmap, codecparam, 202, 168, 1, 2, 0, "%s", buf);
 
-	sprintf(buf, "^f01%02o", curFrame & 0xff);
+	Common::sprintf_s(buf, "^f01%02o", curFrame & 0xff);
 	smlayer_showStatusMsg(-1, renderBitmap, codecparam, 240, 168, 1, 2, 0, "%s", buf);
 	smlayer_showStatusMsg(-1, renderBitmap, codecparam, 170, 43, 1, 2, 0, "%s", buf);
 
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index 57f686f4d6d..aa9875c39e9 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -863,7 +863,7 @@ void ScummEngine::resetRoomObjects() {
 
 		if (_dumpScripts) {
 			char buf[32];
-			sprintf(buf, "roomobj-%d-", _roomResource);
+			Common::sprintf_s(buf, "roomobj-%d-", _roomResource);
 			ptr = findResource(MKTAG('V','E','R','B'), ptr);
 			dumpResource(buf, od->obj_nr, ptr);
 		}
@@ -928,7 +928,7 @@ void ScummEngine_v3old::resetRoomObjects() {
 
 		if (_dumpScripts) {
 			char buf[32];
-			sprintf(buf, "roomobj-%d-", _roomResource);
+			Common::sprintf_s(buf, "roomobj-%d-", _roomResource);
 			dumpResource(buf, od->obj_nr, room + od->OBCDoffset);
 		}
 	}
@@ -962,7 +962,7 @@ void ScummEngine_v4::resetRoomObjects() {
 		od->obj_nr = READ_LE_UINT16(ptr + 6);
 		if (_dumpScripts) {
 			char buf[32];
-			sprintf(buf, "roomobj-%d-", _roomResource);
+			Common::sprintf_s(buf, "roomobj-%d-", _roomResource);
 			dumpResource(buf, od->obj_nr, ptr);
 		}
 	}
@@ -1981,7 +1981,7 @@ void ScummEngine::loadFlObject(uint object, uint room) {
 	if (_dumpScripts) {
 		char buf[32];
 		const byte *ptr = foir.obcd;
-		sprintf(buf, "roomobj-%u-", room);
+		Common::sprintf_s(buf, "roomobj-%u-", room);
 		ptr = findResource(MKTAG('V','E','R','B'), ptr);
 		dumpResource(buf, object, ptr);
 	}
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 3eb18d2543b..f310739b25b 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -221,9 +221,9 @@ void ScummEngine::askForDisk(const char *filename, int disknum) {
 		_imuseDigital->stopAllSounds();
 
 #ifdef MACOSX
-		sprintf(buf, "Cannot find file: '%s'\nPlease insert disc %d.\nPress OK to retry, Quit to exit", filename, disknum);
+		Common::sprintf_s(buf, "Cannot find file: '%s'\nPlease insert disc %d.\nPress OK to retry, Quit to exit", filename, disknum);
 #else
-		sprintf(buf, "Cannot find file: '%s'\nInsert disc %d into drive %s\nPress OK to retry, Quit to exit", filename, disknum, ConfMan.get("path").c_str());
+		Common::sprintf_s(buf, "Cannot find file: '%s'\nInsert disc %d into drive %s\nPress OK to retry, Quit to exit", filename, disknum, ConfMan.get("path").c_str());
 #endif
 
 		result = displayMessage("Quit", "%s", buf);
@@ -232,7 +232,7 @@ void ScummEngine::askForDisk(const char *filename, int disknum) {
 		}
 #endif
 	} else {
-		sprintf(buf, "Cannot find file: '%s'", filename);
+		Common::sprintf_s(buf, "Cannot find file: '%s'", filename);
 		InfoDialog dialog(this, Common::U32String(buf));
 		runDialog(dialog);
 		error("Cannot find file: '%s'", filename);
@@ -1445,7 +1445,7 @@ void ScummEngine::dumpResource(const char *tag, int id, const byte *ptr, int len
 	else
 		size = READ_BE_UINT32(ptr + 4);
 
-	sprintf(buf, "dumps/%s%d.dmp", tag, id);
+	Common::sprintf_s(buf, "dumps/%s%d.dmp", tag, id);
 
 	out.open(buf);
 	if (out.isOpen() == false)
@@ -1662,7 +1662,7 @@ const char *nameOfResType(ResType type) {
 	case rtSpoolBuffer:
 		return "SpoolBuffer";
 	default:
-		sprintf(buf, "rt%d", type);
+		Common::sprintf_s(buf, "rt%d", type);
 		return buf;
 	}
 }
diff --git a/engines/scumm/resource_v3.cpp b/engines/scumm/resource_v3.cpp
index 47364495633..782e33877aa 100644
--- a/engines/scumm/resource_v3.cpp
+++ b/engines/scumm/resource_v3.cpp
@@ -108,7 +108,7 @@ void ScummEngine_v3::loadCharset(int no) {
 	Common::File file;
 	char buf[20];
 
-	sprintf(buf, "%02d.LFL", 99 - no);
+	Common::sprintf_s(buf, "%02d.LFL", 99 - no);
 	file.open(buf);
 
 	if (file.isOpen() == false) {
diff --git a/engines/scumm/resource_v4.cpp b/engines/scumm/resource_v4.cpp
index e35205f851f..4713358fdd4 100644
--- a/engines/scumm/resource_v4.cpp
+++ b/engines/scumm/resource_v4.cpp
@@ -163,7 +163,7 @@ void ScummEngine_v4::loadCharset(int no) {
 	char buf[20];
 	byte *data;
 
-	sprintf(buf, "%03d.LFL", 900 + no);
+	Common::sprintf_s(buf, "%03d.LFL", 900 + no);
 	file.open(buf);
 
 	if (file.isOpen() == false) {
diff --git a/engines/scumm/room.cpp b/engines/scumm/room.cpp
index b911710fec2..71766e5aab1 100644
--- a/engines/scumm/room.cpp
+++ b/engines/scumm/room.cpp
@@ -360,7 +360,7 @@ void ScummEngine::setupRoomSubBlocks() {
 
 			if (_dumpScripts) {
 				char buf[32];
-				sprintf(buf, "room-%d-", _roomResource);
+				Common::sprintf_s(buf, "room-%d-", _roomResource);
 				dumpResource(buf, id, ptr - _resourceHeaderSize);
 			}
 
@@ -380,7 +380,7 @@ void ScummEngine::setupRoomSubBlocks() {
 
 			if (_dumpScripts) {
 				char buf[32];
-				sprintf(buf, "room-%d-", _roomResource);
+				Common::sprintf_s(buf, "room-%d-", _roomResource);
 				dumpResource(buf, id, ptr - _resourceHeaderSize);
 			}
 		}
@@ -396,7 +396,7 @@ void ScummEngine::setupRoomSubBlocks() {
 
 			if (_dumpScripts) {
 				char buf[32];
-				sprintf(buf, "room-%d-", _roomResource);
+				Common::sprintf_s(buf, "room-%d-", _roomResource);
 				dumpResource(buf, id, ptr - _resourceHeaderSize);
 			}
 		}
@@ -423,7 +423,7 @@ void ScummEngine::setupRoomSubBlocks() {
 
 			if (_dumpScripts) {
 				char buf[32];
-				sprintf(buf, "room-%d-", _roomResource);
+				Common::sprintf_s(buf, "room-%d-", _roomResource);
 				dumpResource(buf, id, ptr - _resourceHeaderSize);
 			}
 		}
@@ -733,7 +733,7 @@ void ScummEngine_v3old::setupRoomSubBlocks() {
 
 			if (_dumpScripts) {
 				char buf[32];
-				sprintf(buf, "room-%d-", _roomResource);
+				Common::sprintf_s(buf, "room-%d-", _roomResource);
 
 				// HACK: to determine the sizes of the local scripts, we assume that
 				// a) their order in the data file is the same as in the index
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 936e56f5b86..c12407b8f2e 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -1431,8 +1431,8 @@ void ScummEngine::saveLoadWithSerializer(Common::Serializer &s) {
 	if (s.isLoading()) {
 		char md5str1[32+1], md5str2[32+1];
 		for (i = 0; i < 16; i++) {
-			sprintf(md5str1 + i*2, "%02x", (int)_gameMD5[i]);
-			sprintf(md5str2 + i*2, "%02x", (int)md5Backup[i]);
+			Common::sprintf_s(md5str1 + i*2, 3, "%02x", (int)_gameMD5[i]);
+			Common::sprintf_s(md5str2 + i*2, 3, "%02x", (int)md5Backup[i]);
 		}
 
 		debug(2, "Save version: %d", s.getVersion());
diff --git a/engines/scumm/script_v4.cpp b/engines/scumm/script_v4.cpp
index 4d3896d9ba5..62052370855 100644
--- a/engines/scumm/script_v4.cpp
+++ b/engines/scumm/script_v4.cpp
@@ -418,7 +418,7 @@ void ScummEngine_v4::o4_saveLoadGame() {
 			char name[32];
 			if (_game.version <= 2) {
 				// use generic name
-				sprintf(name, "Game %c", 'A'+slot-1);
+				Common::sprintf_s(name, "Game %c", 'A'+slot-1);
 			} else {
 				// use name entered by the user
 				char* ptr;
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 589500c6e61..d6c18592de6 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -982,7 +982,7 @@ SmushFont *SmushPlayer::getFont(int font) {
 	} else {
 		int numFonts = (_vm->_game.id == GID_CMI && !(_vm->_game.features & GF_DEMO)) ? 5 : 4;
 		assert(font >= 0 && font < numFonts);
-		sprintf(file_font, "font%d.nut", font);
+		Common::sprintf_s(file_font, "font%d.nut", font);
 		_sf[font] = new SmushFont(_vm, file_font, _vm->_game.id == GID_DIG && font != 0);
 	}
 
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index bca8581cc30..70072425529 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -752,14 +752,14 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
 		if (!file)
 			error("startTalkSound: Out of memory");
 
-		sprintf(filename, "audio/%s.%u/%u.voc", roomname, offset, b);
+		Common::sprintf_s(filename, "audio/%s.%u/%u.voc", roomname, offset, b);
 		if (!_vm->openFile(*file, filename)) {
-			sprintf(filename, "audio/%s_%u/%u.voc", roomname, offset, b);
+			Common::sprintf_s(filename, "audio/%s_%u/%u.voc", roomname, offset, b);
 			_vm->openFile(*file, filename);
 		}
 
 		if (!file->isOpen()) {
-			sprintf(filename, "%u.%u.voc", offset, b);
+			Common::sprintf_s(filename, "%u.%u.voc", offset, b);
 			_vm->openFile(*file, filename);
 		}
 
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index d868eb9ca9d..c0139fef4fc 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -1656,7 +1656,7 @@ void ScummEngine_v7::loadLanguageBundle() {
 				}
 
 				// The tag is the basetag, followed by a dot and then the index
-				sprintf(_languageIndex[_languageIndexSize].tag, "%s.%03d", baseTag, idx);
+				Common::sprintf_s(_languageIndex[_languageIndexSize].tag, "%s.%03d", baseTag, idx);
 
 				// That was another index entry
 				_languageIndexSize++;


Commit: a858fd57f06a2227f51799a71050437a838fbf1d
    https://github.com/scummvm/scummvm/commit/a858fd57f06a2227f51799a71050437a838fbf1d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SHERLOCK: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/sherlock/scalpel/scalpel.cpp


diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp
index cbd63fcc549..e396c498aec 100644
--- a/engines/sherlock/scalpel/scalpel.cpp
+++ b/engines/sherlock/scalpel/scalpel.cpp
@@ -941,7 +941,7 @@ bool ScalpelEngine::showOfficeCutscene3DO() {
 
 		for (int nr = 1; finished && nr <= 4; nr++) {
 			char filename[15];
-			sprintf(filename, "credits%d.cel", nr);
+			Common::sprintf_s(filename, "credits%d.cel", nr);
 			ImageFile3DO *creditsImage = new ImageFile3DO(filename, kImageFile3DOType_Cel);
 			ImageFrame *creditsFrame = &(*creditsImage)[0];
 			for (int i = 0; finished && i < 200 + creditsFrame->_height; i++) {


Commit: 3fa310340e92c412d0b4baf45ed2810d4e5e4a46
    https://github.com/scummvm/scummvm/commit/3fa310340e92c412d0b4baf45ed2810d4e5e4a46
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SKY: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/sky/control.cpp
    engines/sky/debug.cpp
    engines/sky/disk.cpp
    engines/sky/metaengine.cpp


diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp
index f00ab4fbb1e..9ab0a4a9c3b 100644
--- a/engines/sky/control.cpp
+++ b/engines/sky/control.cpp
@@ -1074,10 +1074,10 @@ void Control::setUpGameSprites(const Common::StringArray &saveGameNames, DataFil
 		char nameBuf[MAX_TEXT_LEN + 10];
 
 		if (firstNum + cnt == selectedGame) {
-			sprintf(nameBuf, "%3d: %s", firstNum + cnt + 1, dirtyString.c_str());
+			Common::sprintf_s(nameBuf, "%3d: %s", firstNum + cnt + 1, dirtyString.c_str());
 			textSpr = _skyText->displayText(nameBuf, NULL, false, PAN_LINE_WIDTH, 0);
 		} else {
-			sprintf(nameBuf, "%3d: %s", firstNum + cnt + 1, saveGameNames[firstNum + cnt].c_str());
+			Common::sprintf_s(nameBuf, "%3d: %s", firstNum + cnt + 1, saveGameNames[firstNum + cnt].c_str());
 			textSpr = _skyText->displayText(nameBuf, NULL, false, PAN_LINE_WIDTH, 37);
 		}
 		nameSprites[cnt] = (DataFileHeader *)textSpr.textData;
@@ -1180,7 +1180,7 @@ void Control::saveDescriptions(const Common::StringArray &list) {
 uint16 Control::saveGameToFile(bool fromControlPanel, const char *filename, bool isAutosave) {
 	char fName[20];
 	if (!filename) {
-		sprintf(fName,"SKY-VM.%03d", isAutosave ? 0 : _selectedGame + 1);
+		Common::sprintf_s(fName,"SKY-VM.%03d", isAutosave ? 0 : _selectedGame + 1);
 		filename = fName;
 	}
 
diff --git a/engines/sky/debug.cpp b/engines/sky/debug.cpp
index 002d7fb76c7..0f59986bcb8 100644
--- a/engines/sky/debug.cpp
+++ b/engines/sky/debug.cpp
@@ -1196,13 +1196,14 @@ bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
 								debugPrintf("%s\n", line);
 								linePos = line;
 							} else
-								linePos += sprintf(linePos, ", ");
+								linePos += Common::sprintf_s(linePos, sizeof(line) - (linePos - line), ", ");
 						}
 						uint16 cptId = (uint16)((sec << 12) | cpt);
 						uint16 type, size;
 						char name[256];
 						_skyCompact->fetchCptInfo(cptId, &size, &type, name, sizeof(name));
-						linePos += sprintf(linePos, "%04X: %10s %22s", cptId, _skyCompact->nameForType(type), name);
+						linePos += Common::sprintf_s(linePos, sizeof(line) - (linePos - line),
+								"%04X: %10s %22s", cptId, _skyCompact->nameForType(type), name);
 					}
 					if (linePos != line)
 						debugPrintf("%s\n", line);
diff --git a/engines/sky/disk.cpp b/engines/sky/disk.cpp
index 48c27b37157..35fad54772f 100644
--- a/engines/sky/disk.cpp
+++ b/engines/sky/disk.cpp
@@ -319,7 +319,7 @@ void Disk::dumpFile(uint16 fileNr) {
 	byte* filePtr;
 
 	filePtr = loadFile(fileNr);
-	sprintf(buf, "dumps/file-%d.dmp", fileNr);
+	Common::sprintf_s(buf, "dumps/file-%d.dmp", fileNr);
 
 	if (!Common::File::exists(buf)) {
 		if (out.open(buf))
diff --git a/engines/sky/metaengine.cpp b/engines/sky/metaengine.cpp
index 215723ba4db..66d5c1591a1 100644
--- a/engines/sky/metaengine.cpp
+++ b/engines/sky/metaengine.cpp
@@ -207,7 +207,7 @@ void SkyMetaEngine::removeSaveState(const char *target, int slot) const {
 
 	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
 	char fName[20];
-	sprintf(fName,"SKY-VM.%03d", slot);
+	Common::sprintf_s(fName,"SKY-VM.%03d", slot);
 	saveFileMan->removeSavefile(fName);
 
 	// Load current save game descriptions
@@ -275,7 +275,7 @@ SaveStateDescriptor SkyMetaEngine::querySaveMetaInfos(const char *target, int sl
 		// Make sure the file exists
 		// Note: there can be valid saved file names with empty savename
 		char fName[20];
-		sprintf(fName,"SKY-VM.%03d", slot);
+		Common::sprintf_s(fName,"SKY-VM.%03d", slot);
 		Common::InSaveFile *in = saveFileMan->openForLoading(fName);
 		if (in) {
 			delete in;


Commit: 95d5bafb57c70b9533333a53c210fc4aa52afbc2
    https://github.com/scummvm/scummvm/commit/95d5bafb57c70b9533333a53c210fc4aa52afbc2
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SLUDGE: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/sludge/event.cpp


diff --git a/engines/sludge/event.cpp b/engines/sludge/event.cpp
index 84cf64bceae..a6680177c8b 100644
--- a/engines/sludge/event.cpp
+++ b/engines/sludge/event.cpp
@@ -286,7 +286,7 @@ bool EventManager::handleInput() {
 		default:
 			if (_input.keyPressed >= 256) {
 				char tmp[7] = "ABCDEF";
-				sprintf(tmp, "%i", _input.keyPressed);
+				Common::sprintf_s(tmp, "%i", _input.keyPressed);
 				tempString = tmp;
 				//}
 			} else {


Commit: 5987c9f8ffa34aac7a09748ebe909410f4ecdc4d
    https://github.com/scummvm/scummvm/commit/5987c9f8ffa34aac7a09748ebe909410f4ecdc4d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SUPERNOVA: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/supernova/resman.cpp


diff --git a/engines/supernova/resman.cpp b/engines/supernova/resman.cpp
index 5b6e3b3a1d5..d087595a273 100644
--- a/engines/supernova/resman.cpp
+++ b/engines/supernova/resman.cpp
@@ -486,7 +486,7 @@ static Common::MemoryReadStream *convertToMod(const char *filename, int version)
 		// iname is not stored in the mod file. Just set it to 'instrument#'
 		// finetune is not stored either. Assume 0.
 		memset(instr[i].iname, 0, 22);
-		sprintf(instr[i].iname, "instrument%d", i+1);
+		Common::sprintf_s(instr[i].iname, "instrument%d", i+1);
 		instr[i].length = 0;
 		instr[i].finetune = 0;
 		instr[i].volume = 0;


Commit: b2ecd531a619e4eb516d895adb37d2126bd2aa13
    https://github.com/scummvm/scummvm/commit/b2ecd531a619e4eb516d895adb37d2126bd2aa13
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SWORD1: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/sword1/control.cpp
    engines/sword1/resman.cpp
    engines/sword1/sound.cpp
    engines/sword1/sword1.cpp


diff --git a/engines/sword1/control.cpp b/engines/sword1/control.cpp
index 80df1a40b1c..fb36d0be71b 100644
--- a/engines/sword1/control.cpp
+++ b/engines/sword1/control.cpp
@@ -262,8 +262,8 @@ void Control::askForCd() {
 
 	char fName[10];
 	uint8 textA[50];
-	sprintf(fName, "cd%d.id", SwordEngine::_systemVars.currentCD);
-	sprintf((char *)textA, "%s%d", _lStrings[STR_INSERT_CD_A], SwordEngine::_systemVars.currentCD);
+	Common::sprintf_s(fName, "cd%d.id", SwordEngine::_systemVars.currentCD);
+	Common::sprintf_s(textA, "%s%d", _lStrings[STR_INSERT_CD_A], SwordEngine::_systemVars.currentCD);
 	bool notAccepted = true;
 	bool refreshText = true;
 	do {
@@ -1114,7 +1114,7 @@ void Control::renderVolumeBar(uint8 id, uint8 volL, uint8 volR) {
 void Control::saveGameToFile(uint8 slot) {
 	char fName[15];
 	uint16 cnt;
-	sprintf(fName, "sword1.%03d", slot);
+	Common::sprintf_s(fName, "sword1.%03d", slot);
 	uint16 liveBuf[TOTAL_SECTIONS];
 	Common::OutSaveFile *outf;
 	outf = _saveFileMan->openForSaving(fName);
@@ -1175,7 +1175,7 @@ void Control::saveGameToFile(uint8 slot) {
 bool Control::restoreGameFromFile(uint8 slot) {
 	char fName[15];
 	uint16 cnt;
-	sprintf(fName, "sword1.%03d", slot);
+	Common::sprintf_s(fName, "sword1.%03d", slot);
 	Common::InSaveFile *inf;
 	inf = _saveFileMan->openForLoading(fName);
 	if (!inf) {
@@ -1246,8 +1246,8 @@ bool Control::restoreGameFromFile(uint8 slot) {
 bool Control::convertSaveGame(uint8 slot, char *desc) {
 	char oldFileName[15];
 	char newFileName[40];
-	sprintf(oldFileName, "SAVEGAME.%03d", slot);
-	sprintf(newFileName, "sword1.%03d", slot);
+	Common::sprintf_s(oldFileName, "SAVEGAME.%03d", slot);
+	Common::sprintf_s(newFileName, "sword1.%03d", slot);
 	uint8 *saveData;
 	int dataSize;
 
diff --git a/engines/sword1/resman.cpp b/engines/sword1/resman.cpp
index 7b25fd189c0..690df258e00 100644
--- a/engines/sword1/resman.cpp
+++ b/engines/sword1/resman.cpp
@@ -82,7 +82,7 @@ void ResMan::loadCluDescript(const char *fileName) {
 
 	if (!file.isOpen()) {
 		char msg[512];
-		sprintf(msg, "Couldn't open CLU description '%s'\n\nIf you are running from CD, please ensure you have read the ScummVM documentation regarding multi-cd games.", fileName);
+		Common::sprintf_s(msg, "Couldn't open CLU description '%s'\n\nIf you are running from CD, please ensure you have read the ScummVM documentation regarding multi-cd games.", fileName);
 		guiFatalError(msg);
 	}
 
@@ -203,7 +203,7 @@ void *ResMan::openFetchRes(uint32 id) {
 
 void ResMan::dumpRes(uint32 id) {
 	char outn[30];
-	sprintf(outn, "DUMP%08X.BIN", id);
+	Common::sprintf_s(outn, "DUMP%08X.BIN", id);
 	Common::DumpFile outf;
 	if (outf.open(outn)) {
 		resOpen(id);
@@ -311,13 +311,13 @@ Common::File *ResMan::resFile(uint32 id) {
 		// Supposes that big endian means mac cluster file and little endian means PC cluster file.
 		// This works, but we may want to separate the file name from the endianess or try .CLM extension if opening.clu file fail.
 		if (_isBigEndian)
-			sprintf(fileName, "%s.CLM", _prj.clu[(id >> 24) - 1].label);
+			Common::sprintf_s(fileName, "%s.CLM", _prj.clu[(id >> 24) - 1].label);
 		else
-			sprintf(fileName, "%s.CLU", _prj.clu[(id >> 24) - 1].label);
+			Common::sprintf_s(fileName, "%s.CLU", _prj.clu[(id >> 24) - 1].label);
 		cluster->file->open(fileName);
 		if (!cluster->file->isOpen()) {
 			char msg[512];
-			sprintf(msg, "Couldn't open game cluster file '%s'\n\nIf you are running from CD, please ensure you have read the ScummVM documentation regarding multi-cd games.", fileName);
+			Common::sprintf_s(msg, "Couldn't open game cluster file '%s'\n\nIf you are running from CD, please ensure you have read the ScummVM documentation regarding multi-cd games.", fileName);
 			guiFatalError(msg);
 		}
 		while (_openClus > MAX_OPEN_CLUS) {
diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp
index 8c40b28e91a..4781fa17722 100644
--- a/engines/sword1/sound.cpp
+++ b/engines/sword1/sound.cpp
@@ -607,7 +607,7 @@ void Sound::initCowSystem() {
 	*/
 #ifdef USE_FLAC
 	if (!_cowFile.isOpen()) {
-		sprintf(cowName, "SPEECH%d.CLF", SwordEngine::_systemVars.currentCD);
+		Common::sprintf_s(cowName, "SPEECH%d.CLF", SwordEngine::_systemVars.currentCD);
 		_cowFile.open(cowName);
 		if (_cowFile.isOpen()) {
 			debug(1, "Using FLAC compressed Speech Cluster");
@@ -617,7 +617,7 @@ void Sound::initCowSystem() {
 #endif
 #ifdef USE_VORBIS
 	if (!_cowFile.isOpen()) {
-		sprintf(cowName, "SPEECH%d.CLV", SwordEngine::_systemVars.currentCD);
+		Common::sprintf_s(cowName, "SPEECH%d.CLV", SwordEngine::_systemVars.currentCD);
 		_cowFile.open(cowName);
 		if (_cowFile.isOpen()) {
 			debug(1, "Using Vorbis compressed Speech Cluster");
@@ -627,7 +627,7 @@ void Sound::initCowSystem() {
 #endif
 #ifdef USE_MAD
 	if (!_cowFile.isOpen()) {
-		sprintf(cowName, "SPEECH%d.CL3", SwordEngine::_systemVars.currentCD);
+		Common::sprintf_s(cowName, "SPEECH%d.CL3", SwordEngine::_systemVars.currentCD);
 		_cowFile.open(cowName);
 		if (_cowFile.isOpen()) {
 			debug(1, "Using MP3 compressed Speech Cluster");
@@ -636,7 +636,7 @@ void Sound::initCowSystem() {
 	}
 #endif
 	if (!_cowFile.isOpen()) {
-		sprintf(cowName, "SPEECH%d.CLU", SwordEngine::_systemVars.currentCD);
+		Common::sprintf_s(cowName, "SPEECH%d.CLU", SwordEngine::_systemVars.currentCD);
 		_cowFile.open(cowName);
 		if (!_cowFile.isOpen()) {
 			_cowFile.open("speech.clu");
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index f72e0319b05..4727c1eee67 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -369,16 +369,17 @@ void SwordEngine::showFileErrorMsg(uint8 type, bool *fileExists) {
 		warning("%d files missing", missCnt);
 		int msgId = (type == TYPE_IMMED) ? 0 : 2;
 		if (missCnt == 1) {
-			sprintf(msg, errorMsgs[msgId],
+			Common::sprintf_s(msg, errorMsgs[msgId],
 			        _macCdFileList[missNum].name, (_macCdFileList[missNum].flags & FLAG_CD2) ? 2 : 1);
 			warning("%s", msg);
 		} else {
-			char *pos = msg + sprintf(msg, errorMsgs[msgId + 1], missCnt);
+			char *pos = msg + Common::sprintf_s(msg, errorMsgs[msgId + 1], missCnt);
 			warning("%s", msg);
 			for (int i = 0; i < ARRAYSIZE(_macCdFileList); i++)
 				if (!fileExists[i]) {
 					warning("\"%s\" (CD %d)", _macCdFileList[i].name, (_macCdFileList[i].flags & FLAG_CD2) ? 2 : 1);
-					pos += sprintf(pos, "\"%s\" (CD %d)\n", _macCdFileList[i].name, (_macCdFileList[i].flags & FLAG_CD2) ? 2 : 1);
+					pos += Common::sprintf_s(pos, sizeof(msg) - (pos - msg),
+						"\"%s\" (CD %d)\n", _macCdFileList[i].name, (_macCdFileList[i].flags & FLAG_CD2) ? 2 : 1);
 				}
 		}
 	} else if (SwordEngine::isPsx()) {
@@ -391,15 +392,16 @@ void SwordEngine::showFileErrorMsg(uint8 type, bool *fileExists) {
 		warning("%d files missing", missCnt);
 		int msgId = (type == TYPE_IMMED) ? 0 : 2;
 		if (missCnt == 1) {
-			sprintf(msg, errorMsgs[msgId], _psxCdFileList[missNum].name, 1);
+			Common::sprintf_s(msg, errorMsgs[msgId], _psxCdFileList[missNum].name, 1);
 			warning("%s", msg);
 		} else {
-			char *pos = msg + sprintf(msg, errorMsgs[msgId + 1], missCnt);
+			char *pos = msg + Common::sprintf_s(msg, errorMsgs[msgId + 1], missCnt);
 			warning("%s", msg);
 			for (int i = 0; i < ARRAYSIZE(_psxCdFileList); i++)
 				if (!fileExists[i]) {
 					warning("\"%s\"", _macCdFileList[i].name);
-					pos += sprintf(pos, "\"%s\"\n", _macCdFileList[i].name);
+					pos += Common::sprintf_s(pos, sizeof(msg) - (pos - msg),
+						"\"%s\"\n", _macCdFileList[i].name);
 				}
 		}
 	} else {
@@ -412,16 +414,17 @@ void SwordEngine::showFileErrorMsg(uint8 type, bool *fileExists) {
 		warning("%d files missing", missCnt);
 		int msgId = (type == TYPE_IMMED) ? 0 : 2;
 		if (missCnt == 1) {
-			sprintf(msg, errorMsgs[msgId],
+			Common::sprintf_s(msg, errorMsgs[msgId],
 			        _pcCdFileList[missNum].name, (_pcCdFileList[missNum].flags & FLAG_CD2) ? 2 : 1);
 			warning("%s", msg);
 		} else {
-			char *pos = msg + sprintf(msg, errorMsgs[msgId + 1], missCnt);
+			char *pos = msg + Common::sprintf_s(msg, errorMsgs[msgId + 1], missCnt);
 			warning("%s", msg);
 			for (int i = 0; i < ARRAYSIZE(_pcCdFileList); i++)
 				if (!fileExists[i]) {
 					warning("\"%s\" (CD %d)", _pcCdFileList[i].name, (_pcCdFileList[i].flags & FLAG_CD2) ? 2 : 1);
-					pos += sprintf(pos, "\"%s\" (CD %d)\n", _pcCdFileList[i].name, (_pcCdFileList[i].flags & FLAG_CD2) ? 2 : 1);
+					pos += Common::sprintf_s(pos, sizeof(msg) - (pos - msg),
+						"\"%s\" (CD %d)\n", _pcCdFileList[i].name, (_pcCdFileList[i].flags & FLAG_CD2) ? 2 : 1);
 				}
 		}
 	}


Commit: 027be5b7c0987978ad455f40bf80dca07abf6b97
    https://github.com/scummvm/scummvm/commit/027be5b7c0987978ad455f40bf80dca07abf6b97
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
SWORD2: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/sword2/controls.cpp
    engines/sword2/debug.cpp
    engines/sword2/music.cpp
    engines/sword2/protocol.cpp
    engines/sword2/resman.cpp
    engines/sword2/screen.cpp


diff --git a/engines/sword2/controls.cpp b/engines/sword2/controls.cpp
index ff718ddb920..178718082c0 100644
--- a/engines/sword2/controls.cpp
+++ b/engines/sword2/controls.cpp
@@ -1095,9 +1095,9 @@ public:
 	void setText(FontRendererGui *fr, int slot, byte *text) {
 		_fr = fr;
 		if (text)
-			sprintf((char *)_text, "%d.  %s", slot, text);
+			Common::sprintf_s(_text, "%d.  %s", slot, text);
 		else
-			sprintf((char *)_text, "%d.  ", slot);
+			Common::sprintf_s(_text, "%d.  ", slot);
 	}
 
 	byte *getText() {
diff --git a/engines/sword2/debug.cpp b/engines/sword2/debug.cpp
index 838d7832504..ca8b5666397 100644
--- a/engines/sword2/debug.cpp
+++ b/engines/sword2/debug.cpp
@@ -82,7 +82,7 @@ void Debugger::buildDebugText() {
 
 		_vm->_mouse->getPos(mouseX, mouseY);
 
-		sprintf(buf, "%d,%d", mouseX + screenInfo->scroll_offset_x, mouseY + screenInfo->scroll_offset_y);
+		Common::sprintf_s(buf, "%d,%d", mouseX + screenInfo->scroll_offset_x, mouseY + screenInfo->scroll_offset_y);
 		if (mouseX > 560)
 			makeDebugTextBlock(buf, mouseX - 50, mouseY - 15);
 		else
@@ -96,23 +96,23 @@ void Debugger::buildDebugText() {
 		// so we can see what's behind the lines
 		_rectFlicker = !_rectFlicker;
 
-		sprintf(buf, "x1=%d", _rectX1);
+		Common::sprintf_s(buf, "x1=%d", _rectX1);
 		makeDebugTextBlock(buf, 0, 120);
 
-		sprintf(buf, "y1=%d", _rectY1);
+		Common::sprintf_s(buf, "y1=%d", _rectY1);
 		makeDebugTextBlock(buf, 0, 135);
 
-		sprintf(buf, "x2=%d", _rectX2);
+		Common::sprintf_s(buf, "x2=%d", _rectX2);
 		makeDebugTextBlock(buf, 0, 150);
 
-		sprintf(buf, "y2=%d", _rectY2);
+		Common::sprintf_s(buf, "y2=%d", _rectY2);
 		makeDebugTextBlock(buf, 0, 165);
 	}
 
 	// testingSnR indicator
 
 	if (_testingSnR) {		// see fnAddHuman()
-		sprintf(buf, "TESTING LOGIC STABILITY!");
+		Common::sprintf_s(buf, "TESTING LOGIC STABILITY!");
 		makeDebugTextBlock(buf, 0, 105);
 	}
 
@@ -125,9 +125,9 @@ void Debugger::buildDebugText() {
 			_startTime = time;
 
 		time -= _startTime;
-		sprintf(buf, "Time %.2d:%.2d:%.2d.%.3d", (time / 3600000) % 60, (time / 60000) % 60, (time / 1000) % 60, time % 1000);
+		Common::sprintf_s(buf, "Time %.2d:%.2d:%.2d.%.3d", (time / 3600000) % 60, (time / 60000) % 60, (time / 1000) % 60, time % 1000);
 		makeDebugTextBlock(buf, 500, 360);
-		sprintf(buf, "Game %d", _vm->_gameCycle);
+		Common::sprintf_s(buf, "Game %d", _vm->_gameCycle);
 		makeDebugTextBlock(buf, 500, 380);
 	}
 
@@ -137,20 +137,20 @@ void Debugger::buildDebugText() {
 		if (_textNumber) {
 			if (_vm->_logic->readVar(SYSTEM_TESTING_TEXT)) {
 				if (_vm->_logic->readVar(SYSTEM_WANT_PREVIOUS_LINE))
-					sprintf(buf, "backwards");
+					Common::sprintf_s(buf, "backwards");
 				else
-					sprintf(buf, "forwards");
+					Common::sprintf_s(buf, "forwards");
 
 				makeDebugTextBlock(buf, 0, 340);
 			}
 
-			sprintf(buf, "res: %d", _textNumber / SIZE);
+			Common::sprintf_s(buf, "res: %d", _textNumber / SIZE);
 			makeDebugTextBlock(buf, 0, 355);
 
-			sprintf(buf, "pos: %d", _textNumber & 0xffff);
+			Common::sprintf_s(buf, "pos: %d", _textNumber & 0xffff);
 			makeDebugTextBlock(buf, 0, 370);
 
-			sprintf(buf, "TEXT: %d", _vm->_logic->_officialTextNumber);
+			Common::sprintf_s(buf, "TEXT: %d", _vm->_logic->_officialTextNumber);
 			makeDebugTextBlock(buf, 0, 385);
 		}
 	}
@@ -158,7 +158,7 @@ void Debugger::buildDebugText() {
 	// resource number currently being checking for animation
 
 	if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) {
-		sprintf(buf, "trying resource %d", _vm->_logic->readVar(SYSTEM_TESTING_ANIMS));
+		Common::sprintf_s(buf, "trying resource %d", _vm->_logic->readVar(SYSTEM_TESTING_ANIMS));
 		makeDebugTextBlock(buf, 0, 90);
 	}
 
@@ -167,20 +167,20 @@ void Debugger::buildDebugText() {
 	if (_displayDebugText) {
 /*
 		// CD in use
-		sprintf(buf, "CD-%d", currentCD);
+		Common::sprintf_s(buf, "CD-%d", currentCD);
 		makeDebugTextBlock(buf, 0, 0);
 */
 
 		// mouse coords & object pointed to
 
 		if (_vm->_logic->readVar(CLICKED_ID))
-			sprintf(buf, "last click at %d,%d (id %d: %s)",
+			Common::sprintf_s(buf, "last click at %d,%d (id %d: %s)",
 				_vm->_logic->readVar(MOUSE_X),
 				_vm->_logic->readVar(MOUSE_Y),
 				_vm->_logic->readVar(CLICKED_ID),
 				_vm->_resman->fetchName(_vm->_logic->readVar(CLICKED_ID)));
 		else
-			sprintf(buf, "last click at %d,%d (---)",
+			Common::sprintf_s(buf, "last click at %d,%d (---)",
 				_vm->_logic->readVar(MOUSE_X),
 				_vm->_logic->readVar(MOUSE_Y));
 
@@ -193,13 +193,13 @@ void Debugger::buildDebugText() {
 		_vm->_mouse->getPos(mouseX, mouseY);
 
 		if (mouseTouching)
-			sprintf(buf, "mouse %d,%d (id %d: %s)",
+			Common::sprintf_s(buf, "mouse %d,%d (id %d: %s)",
 				mouseX + screenInfo->scroll_offset_x,
 				mouseY + screenInfo->scroll_offset_y,
 				mouseTouching,
 				_vm->_resman->fetchName(mouseTouching));
 		else
-			sprintf(buf, "mouse %d,%d (not touching)",
+			Common::sprintf_s(buf, "mouse %d,%d (not touching)",
 				mouseX + screenInfo->scroll_offset_x,
 				mouseY + screenInfo->scroll_offset_y);
 
@@ -209,7 +209,7 @@ void Debugger::buildDebugText() {
 		// if player objct has a graphic
 
 		if (_graphAnimRes)
-			sprintf(buf, "player %d,%d %s (%d) #%d/%d",
+			Common::sprintf_s(buf, "player %d,%d %s (%d) #%d/%d",
 				screenInfo->player_feet_x,
 				screenInfo->player_feet_y,
 				_vm->_resman->fetchName(_graphAnimRes),
@@ -217,7 +217,7 @@ void Debugger::buildDebugText() {
 				_graphAnimPc,
 				_graphNoFrames);
 		else
-			sprintf(buf, "player %d,%d --- %d",
+			Common::sprintf_s(buf, "player %d,%d --- %d",
 				screenInfo->player_feet_x,
 				screenInfo->player_feet_y,
 				_graphAnimPc);
@@ -226,45 +226,45 @@ void Debugger::buildDebugText() {
 
 		// frames-per-second counter
 
-		sprintf(buf, "fps %d", _vm->_screen->getFps());
+		Common::sprintf_s(buf, "fps %d", _vm->_screen->getFps());
 		makeDebugTextBlock(buf, 440, 0);
 
 		// location number
 
-		sprintf(buf, "location=%d", _vm->_logic->readVar(LOCATION));
+		Common::sprintf_s(buf, "location=%d", _vm->_logic->readVar(LOCATION));
 		makeDebugTextBlock(buf, 440, 15);
 
 		// "result" variable
 
-		sprintf(buf, "result=%d", _vm->_logic->readVar(RESULT));
+		Common::sprintf_s(buf, "result=%d", _vm->_logic->readVar(RESULT));
 		makeDebugTextBlock(buf, 440, 30);
 
 		// no. of events in event list
 
-		sprintf(buf, "events=%d", _vm->_logic->countEvents());
+		Common::sprintf_s(buf, "events=%d", _vm->_logic->countEvents());
 		makeDebugTextBlock(buf, 440, 45);
 
 		// sprite list usage
 
-		sprintf(buf, "bgp0: %d/%d", _vm->_screen->getCurBgp0(), MAX_bgp0_sprites);
+		Common::sprintf_s(buf, "bgp0: %d/%d", _vm->_screen->getCurBgp0(), MAX_bgp0_sprites);
 		makeDebugTextBlock(buf, 560, 0);
 
-		sprintf(buf, "bgp1: %d/%d", _vm->_screen->getCurBgp1(), MAX_bgp1_sprites);
+		Common::sprintf_s(buf, "bgp1: %d/%d", _vm->_screen->getCurBgp1(), MAX_bgp1_sprites);
 		makeDebugTextBlock(buf, 560, 15);
 
-		sprintf(buf, "back: %d/%d", _vm->_screen->getCurBack(), MAX_back_sprites);
+		Common::sprintf_s(buf, "back: %d/%d", _vm->_screen->getCurBack(), MAX_back_sprites);
 		makeDebugTextBlock(buf, 560, 30);
 
-		sprintf(buf, "sort: %d/%d", _vm->_screen->getCurSort(), MAX_sort_sprites);
+		Common::sprintf_s(buf, "sort: %d/%d", _vm->_screen->getCurSort(), MAX_sort_sprites);
 		makeDebugTextBlock(buf, 560, 45);
 
-		sprintf(buf, "fore: %d/%d", _vm->_screen->getCurFore(), MAX_fore_sprites);
+		Common::sprintf_s(buf, "fore: %d/%d", _vm->_screen->getCurFore(), MAX_fore_sprites);
 		makeDebugTextBlock(buf, 560, 60);
 
-		sprintf(buf, "fgp0: %d/%d", _vm->_screen->getCurFgp0(), MAX_fgp0_sprites);
+		Common::sprintf_s(buf, "fgp0: %d/%d", _vm->_screen->getCurFgp0(), MAX_fgp0_sprites);
 		makeDebugTextBlock(buf, 560, 75);
 
-		sprintf(buf, "fgp1: %d/%d", _vm->_screen->getCurFgp1(), MAX_fgp1_sprites);
+		Common::sprintf_s(buf, "fgp1: %d/%d", _vm->_screen->getCurFgp1(), MAX_fgp1_sprites);
 		makeDebugTextBlock(buf, 560, 90);
 
 		// largest layer & sprite
@@ -277,7 +277,7 @@ void Debugger::buildDebugText() {
 		// fnTheyDoWeWait
 
 		if (_speechScriptWaiting) {
-			sprintf(buf, "script waiting for %s (%d)",
+			Common::sprintf_s(buf, "script waiting for %s (%d)",
 				_vm->_resman->fetchName(_speechScriptWaiting),
 				_speechScriptWaiting);
 			makeDebugTextBlock(buf, 0, 90);
@@ -294,7 +294,7 @@ void Debugger::buildDebugText() {
 			// anyway because it changes throughout the logic loop
 
 			if (varNo) {
-				sprintf(buf, "var(%d) = %d", varNo, _vm->_logic->readVar(varNo));
+				Common::sprintf_s(buf, "var(%d) = %d", varNo, _vm->_logic->readVar(varNo));
 				makeDebugTextBlock(buf, 530, showVarPos);
 				showVarPos += 15;	// next line down
 			}
@@ -307,11 +307,11 @@ void Debugger::buildDebugText() {
 		int16 numBlocks = _vm->_memory->getNumBlocks();
 
 		if (totAlloc < 1024)
-			sprintf(buf, "%u bytes in %d memory blocks", totAlloc, numBlocks);
+			Common::sprintf_s(buf, "%u bytes in %d memory blocks", totAlloc, numBlocks);
 		else if (totAlloc < 1024 * 1024)
-			sprintf(buf, "%uK in %d memory blocks", totAlloc / 1024, numBlocks);
+			Common::sprintf_s(buf, "%uK in %d memory blocks", totAlloc / 1024, numBlocks);
 		else
-			sprintf(buf, "%.02fM in %d memory blocks", totAlloc / 1048576., numBlocks);
+			Common::sprintf_s(buf, "%.02fM in %d memory blocks", totAlloc / 1048576., numBlocks);
 
 		makeDebugTextBlock(buf, 0, 0);
 	}
diff --git a/engines/sword2/music.cpp b/engines/sword2/music.cpp
index 6b44a9d8b97..e9897b06741 100644
--- a/engines/sword2/music.cpp
+++ b/engines/sword2/music.cpp
@@ -79,13 +79,13 @@ static Audio::AudioStream *getAudioStream(SoundFileHandle *fh, const char *base,
 		char filename[20];
 
 		for (int i = 0; i < ARRAYSIZE(file_types); i++) {
-			sprintf(filename, "%s%d.%s", base, cd, file_types[i].ext);
+			Common::sprintf_s(filename, "%s%d.%s", base, cd, file_types[i].ext);
 			if (Common::File::exists(filename)) {
 				soundMode = file_types[i].mode;
 				break;
 			}
 
-			sprintf(filename, "%s.%s", base, file_types[i].ext);
+			Common::sprintf_s(filename, "%s.%s", base, file_types[i].ext);
 			if (Common::File::exists(filename)) {
 				soundMode = file_types[i].mode;
 				break;
diff --git a/engines/sword2/protocol.cpp b/engines/sword2/protocol.cpp
index 1c31f6835de..8af22401563 100644
--- a/engines/sword2/protocol.cpp
+++ b/engines/sword2/protocol.cpp
@@ -275,7 +275,7 @@ byte *Sword2Engine::fetchTextLine(byte *file, uint32 text_line) {
 	text_header.read(file + ResHeader::size());
 
 	if (text_line >= text_header.noOfLines) {
-		sprintf((char *)errorLine, "xxMissing line %d of %s (only 0..%d)", text_line, _resman->fetchName(file), text_header.noOfLines - 1);
+		Common::sprintf_s(errorLine, "xxMissing line %d of %s (only 0..%d)", text_line, _resman->fetchName(file), text_header.noOfLines - 1);
 
 		// first 2 chars are NULL so that actor-number comes out as '0'
 		errorLine[0] = 0;
diff --git a/engines/sword2/resman.cpp b/engines/sword2/resman.cpp
index 949c41da207..c4116a3fb36 100644
--- a/engines/sword2/resman.cpp
+++ b/engines/sword2/resman.cpp
@@ -366,7 +366,7 @@ byte *ResourceManager::openResource(uint32 res, bool dump) {
 				break;
 			}
 
-			sprintf(buf, "dumps/%s-%d.dmp", tag, res);
+			Common::sprintf_s(buf, "dumps/%s-%d.dmp", tag, res);
 
 			if (!Common::File::exists(buf)) {
 				Common::DumpFile out;
diff --git a/engines/sword2/screen.cpp b/engines/sword2/screen.cpp
index a33939f1b60..2ac4cfa6f60 100644
--- a/engines/sword2/screen.cpp
+++ b/engines/sword2/screen.cpp
@@ -537,7 +537,7 @@ void Screen::processLayer(byte *file, uint32 layer_number) {
 
 	if (current_layer_area > _largestLayerArea) {
 		_largestLayerArea = current_layer_area;
-		sprintf(_largestLayerInfo,
+		Common::sprintf_s(_largestLayerInfo,
 			"largest layer:  %s layer(%d) is %dx%d",
 			_vm->_resman->fetchName(_thisScreen.background_layer_id),
 			layer_number, layer_head.width, layer_head.height);
@@ -642,7 +642,7 @@ void Screen::processImage(BuildUnit *build_unit) {
 
 	if (current_sprite_area > _largestSpriteArea) {
 		_largestSpriteArea = current_sprite_area;
-		sprintf(_largestSpriteInfo,
+		Common::sprintf_s(_largestSpriteInfo,
 			"largest sprite: %s frame(%d) is %dx%d",
 			_vm->_resman->fetchName(build_unit->anim_resource),
 			build_unit->anim_pc,


Commit: 5ad311fbaa3de7ed8e82e28fd67bba925fefd733
    https://github.com/scummvm/scummvm/commit/5ad311fbaa3de7ed8e82e28fd67bba925fefd733
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
TINSEL: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/tinsel/music.cpp
    engines/tinsel/pdisplay.cpp
    engines/tinsel/polygons.cpp
    engines/tinsel/strres.cpp


diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index 6bfa3a015ec..7bc00726c43 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -397,7 +397,7 @@ void dumpMusic() {
 		if (midiOffsets[i] == 0)
 			break;
 
-		sprintf(outName, "track%03d.xmi", i + 1);
+		Common::sprintf_s(outName, "track%03d.xmi", i + 1);
 		outFile.open(outName);
 
 		if (i < total - 1)
diff --git a/engines/tinsel/pdisplay.cpp b/engines/tinsel/pdisplay.cpp
index c95777a8e8c..84665f55d83 100644
--- a/engines/tinsel/pdisplay.cpp
+++ b/engines/tinsel/pdisplay.cpp
@@ -139,7 +139,7 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
 	int aniX, aniY;			// cursor/lead actor position
 	int Loffset, Toffset;		// Screen top left
 
-	char PositionString[64];	// sprintf() things into here
+	char PositionString[64];	// Common::sprintf_s() things into here
 
 	MOVER *pActor;		// Lead actor
 
@@ -164,15 +164,15 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
 			}
 
 			// New text objects
-			sprintf(PositionString, "%d %d", aniX + Loffset, aniY + Toffset);
+			Common::sprintf_s(PositionString, "%d %d", aniX + Loffset, aniY + Toffset);
 			_ctx->cpText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), PositionString,
 						0, CPOSX, POSY, _vm->_font->GetTagFontHandle(), TXT_CENTER);
 			if (g_DispPath) {
 				HPOLYGON hp = InPolygon(aniX + Loffset, aniY + Toffset, PATH);
 				if (hp == NOPOLY)
-					sprintf(PositionString, "No path");
+					Common::sprintf_s(PositionString, "No path");
 				else
-					sprintf(PositionString, "%d,%d %d,%d %d,%d %d,%d",
+					Common::sprintf_s(PositionString, "%d,%d %d,%d %d,%d %d,%d",
 						PolyCornerX(hp, 0), PolyCornerY(hp, 0),
 						PolyCornerX(hp, 1), PolyCornerY(hp, 1),
 						PolyCornerX(hp, 2), PolyCornerY(hp, 2),
@@ -196,7 +196,7 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
 				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->opText);
 			}
 
-			sprintf(PositionString, "%d", Overrun);
+			Common::sprintf_s(PositionString, "%d", Overrun);
 			_ctx->opText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), PositionString,
 						0, OPOSX, POSY, GetTagFontHandle(), TXT_CENTER);
 
@@ -222,7 +222,7 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
 				}
 
 				// create new text object list
-				sprintf(PositionString, "%d %d", aniX, aniY);
+				Common::sprintf_s(PositionString, "%d %d", aniX, aniY);
 				_ctx->rpText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), PositionString,
 								0, LPOSX, POSY,	_vm->_font->GetTagFontHandle(), TXT_CENTER);
 
@@ -241,7 +241,7 @@ void CursorPositionProcess(CORO_PARAM, const void *) {
 				MultiDeleteObject(_vm->_bg->GetPlayfieldList(FIELD_STATUS), _ctx->spText);
 			}
 
-			sprintf(PositionString, "String: %d", g_newestString);
+			Common::sprintf_s(PositionString, "String: %d", g_newestString);
 			_ctx->spText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS), PositionString,
 						0, SPOSX, POSY+10, _vm->_font->GetTalkFontHandle(), TXT_CENTER);
 
diff --git a/engines/tinsel/polygons.cpp b/engines/tinsel/polygons.cpp
index c615e284adb..1ec55014426 100644
--- a/engines/tinsel/polygons.cpp
+++ b/engines/tinsel/polygons.cpp
@@ -1470,7 +1470,7 @@ void CheckNPathIntegrity() {
 			hp = PolygonIndex(rp);
 			for (j = 0; j <= n; j++) {
 				if (!IsInPolygon(cp.getNodeX(j), cp.getNodeY(j), hp)) {
-					sprintf(_vm->_font->TextBufferAddr(), "Node (%d, %d) is not in its own path (starting (%d, %d))",
+					Common::sprintf_s(_vm->_font->TextBufferAddr(), "Node (%d, %d) is not in its own path (starting (%d, %d))",
 						 cp.getNodeX(j), cp.getNodeY(j), rp->cx[0], rp->cy[0]);
 					error(_vm->_font->TextBufferAddr());
 				}
@@ -1482,12 +1482,12 @@ void CheckNPathIntegrity() {
 					break;
 
 				if (IsInPolygon(cp.getNodeX(0), cp.getNodeY(0), PolygonIndex(rp->adjpaths[j]))) {
-					sprintf(_vm->_font->TextBufferAddr(), "Node (%d, %d) is in another path (starting (%d, %d))",
+					Common::sprintf_s(_vm->_font->TextBufferAddr(), "Node (%d, %d) is in another path (starting (%d, %d))",
 						 cp.getNodeX(0), cp.getNodeY(0), rp->adjpaths[j]->cx[0], rp->adjpaths[j]->cy[0]);
 					error(_vm->_font->TextBufferAddr());
 				}
 				if (IsInPolygon(cp.getNodeX(n), cp.getNodeY(n), PolygonIndex(rp->adjpaths[j]))) {
-					sprintf(_vm->_font->TextBufferAddr(), "Node (%d, %d) is in another path (starting (%d, %d))",
+					Common::sprintf_s(_vm->_font->TextBufferAddr(), "Node (%d, %d) is in another path (starting (%d, %d))",
 						 cp.getNodeX(n), cp.getNodeY(n), rp->adjpaths[j]->cx[0], rp->adjpaths[j]->cy[0]);
 					error(_vm->_font->TextBufferAddr());
 				}
@@ -1703,7 +1703,7 @@ static void PseudoCenter(POLYGON *p) {
 #ifdef DEBUG
 	//	assert(IsInPolygon(p->pcenterx, p->pcentery, PolygonIndex(p)));  // Pseudo-center is not in path
 	if (!IsInPolygon(p->pcenterx, p->pcentery, PolygonIndex(p))) {
-		sprintf(_vm->_font->TextBufferAddr(), "Pseudo-center is not in path (starting (%d, %d)) - polygon reversed?",
+		Common::sprintf_s(_vm->_font->TextBufferAddr(), "Pseudo-center is not in path (starting (%d, %d)) - polygon reversed?",
 			p->cx[0], p->cy[0]);
 		error(_vm->_font->TextBufferAddr());
 	}
diff --git a/engines/tinsel/strres.cpp b/engines/tinsel/strres.cpp
index dd3582dd1d1..f5a37869290 100644
--- a/engines/tinsel/strres.cpp
+++ b/engines/tinsel/strres.cpp
@@ -97,7 +97,7 @@ void ChangeLanguage(LANGUAGE newLang) {
 	if (!f.open(_vm->getTextFile(newLang))) {
 		if ((newLang == TXT_ENGLISH) || !f.open(_vm->getTextFile(TXT_ENGLISH))) {
 			char buf[50];
-			sprintf(buf, CANNOT_FIND_FILE, _vm->getTextFile(newLang));
+			Common::sprintf_s(buf, CANNOT_FIND_FILE, _vm->getTextFile(newLang));
 			GUI::MessageDialog dialog(buf, "OK");
 			dialog.runModal();
 


Commit: 87f40c8edc10588eb696e5bedbad01f70da2744f
    https://github.com/scummvm/scummvm/commit/87f40c8edc10588eb696e5bedbad01f70da2744f
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
TOLTECS: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/toltecs/saveload.cpp


diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index b5884c5be24..4d13499d82b 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -220,7 +220,7 @@ Common::String ToltecsEngine::getSavegameFilename(const Common::String &target,
 	assert(num >= 0 && num <= 999);
 
 	char extension[5];
-	sprintf(extension, "%03d", num);
+	Common::sprintf_s(extension, "%03d", num);
 
 	return target + "." + extension;
 }


Commit: ae898f331661e4aabd393870e2c7758d90e45a09
    https://github.com/scummvm/scummvm/commit/ae898f331661e4aabd393870e2c7758d90e45a09
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
TOON: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/toon/subtitles.cpp


diff --git a/engines/toon/subtitles.cpp b/engines/toon/subtitles.cpp
index 660756fd166..332c70654c1 100644
--- a/engines/toon/subtitles.cpp
+++ b/engines/toon/subtitles.cpp
@@ -43,7 +43,7 @@ void SubtitleRenderer::render(const Graphics::Surface &frame, uint32 frameNumber
 
 	_subSurface->copyFrom(frame);
 	// char strf[384] = {0};
-	// sprintf(strf, "Time passed: %d", frameNumber);
+	// Common::sprintf_s(strf, "Time passed: %d", frameNumber);
 	// _vm->drawCostumeLine(0, 0, strf, _subSurface);
 	// _vm->_system->copyRectToScreen(_subSurface->getBasePtr(0, 0), _subSurface->pitch, 0, 0, _subSurface->w,  _subSurface->h);
 


Commit: 86bb6a215f8d044e0ca6e20581954c8404aecfae
    https://github.com/scummvm/scummvm/commit/86bb6a215f8d044e0ca6e20581954c8404aecfae
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
TUCKER: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/tucker/tucker.cpp


diff --git a/engines/tucker/tucker.cpp b/engines/tucker/tucker.cpp
index 279c89e35ab..d3192c653bf 100644
--- a/engines/tucker/tucker.cpp
+++ b/engines/tucker/tucker.cpp
@@ -2983,7 +2983,7 @@ void TuckerEngine::drawStringInteger(int num, int x, int y, int digits) {
 	const int xStart = x;
 	char numStr[4];
 	assert(num < 1000);
-	sprintf(numStr, "%03d", num);
+	Common::sprintf_s(numStr, "%03d", num);
 	int i = (digits > 2) ? 0 : 1;
 	for (; i < 3; ++i) {
 		Graphics::drawStringChar(_locationBackgroundGfxBuf, _scrollOffset + x, y, 640, numStr[i], 102, _charsetGfxBuf);


Commit: ebe46dcf6eb868e259e0efd57e07c7f9bc8e1ecf
    https://github.com/scummvm/scummvm/commit/ebe46dcf6eb868e259e0efd57e07c7f9bc8e1ecf
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
TWINE: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/twine/renderer/redraw.cpp


diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp
index 1aafddebab2..f39cdf62e3e 100644
--- a/engines/twine/renderer/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -696,7 +696,7 @@ void Redraw::renderOverlays() {
 				const int32 range = _engine->_collision->clampedLerp(overlay->info1, overlay->info0, 100, overlay->lifeTime - _engine->_lbaTime - 50);
 
 				char text[10];
-				sprintf(text, "%d", range);
+				Common::sprintf_s(text, "%d", range);
 
 				const int32 textLength = _engine->_text->getTextSize(text);
 				const int32 textHeight = 48;


Commit: 34cf68b3181a8ad3375abf2f7c08c9cb7e54d854
    https://github.com/scummvm/scummvm/commit/34cf68b3181a8ad3375abf2f7c08c9cb7e54d854
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
ULTIMA: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/ultima/nuvie/core/converse_speech.cpp
    engines/ultima/nuvie/core/events.cpp
    engines/ultima/nuvie/core/game_clock.cpp
    engines/ultima/nuvie/core/tile_manager.cpp
    engines/ultima/nuvie/fonts/font_manager.cpp
    engines/ultima/nuvie/gui/gui_dialog.cpp
    engines/ultima/nuvie/gui/widgets/gui_widget.h
    engines/ultima/nuvie/menus/audio_dialog.cpp
    engines/ultima/nuvie/menus/cheats_dialog.cpp
    engines/ultima/nuvie/sound/adplug/mid.cpp
    engines/ultima/nuvie/sound/custom_sfx_manager.cpp
    engines/ultima/nuvie/usecode/u6_usecode.cpp
    engines/ultima/nuvie/views/actor_view.cpp
    engines/ultima/nuvie/views/container_widget.cpp
    engines/ultima/nuvie/views/inventory_widget.cpp
    engines/ultima/nuvie/views/party_view.cpp
    engines/ultima/nuvie/views/spell_view_gump.cpp
    engines/ultima/nuvie/views/sun_moon_ribbon.cpp
    engines/ultima/nuvie/views/view_manager.cpp
    engines/ultima/ultima4/controllers/intro_controller.cpp
    engines/ultima/ultima4/core/utils.cpp
    engines/ultima/ultima4/game/portal.cpp
    engines/ultima/ultima8/games/game_data.cpp
    engines/ultima/ultima8/games/game_info.cpp
    engines/ultima/ultima8/gumps/paperdoll_gump.cpp
    engines/ultima/ultima8/gumps/shape_viewer_gump.cpp
    engines/ultima/ultima8/gumps/slider_gump.cpp


diff --git a/engines/ultima/nuvie/core/converse_speech.cpp b/engines/ultima/nuvie/core/converse_speech.cpp
index 8464ce57c31..a76e60d48d9 100644
--- a/engines/ultima/nuvie/core/converse_speech.cpp
+++ b/engines/ultima/nuvie/core/converse_speech.cpp
@@ -83,7 +83,7 @@ void ConverseSpeech::play_speech(uint16 actor_num, uint16 sample_num) {
 
 	sample_num--;
 
-	sprintf(filename, "speech%cchar%u.sam", U6PATH_DELIMITER, actor_num);
+	Common::sprintf_s(filename, "speech%cchar%u.sam", U6PATH_DELIMITER, actor_num);
 
 	config->pathFromValue("config/townsdir", filename, sample_file);
 
diff --git a/engines/ultima/nuvie/core/events.cpp b/engines/ultima/nuvie/core/events.cpp
index 5ae51b18b8c..3ec732aa2bf 100644
--- a/engines/ultima/nuvie/core/events.cpp
+++ b/engines/ultima/nuvie/core/events.cpp
@@ -1837,7 +1837,7 @@ void Events::alt_code_infostring() {
 	hour = clock->get_hour();
 	minute = clock->get_minute();
 
-	sprintf(buf, "%02d%02d%02d%03X%03X%x", karma, hour, minute, x, y, z);
+	Common::sprintf_s(buf, "%02d%02d%02d%03X%03X%x", karma, hour, minute, x, y, z);
 
 	scroll->display_string(buf);
 	scroll->display_string("\n");
diff --git a/engines/ultima/nuvie/core/game_clock.cpp b/engines/ultima/nuvie/core/game_clock.cpp
index a5edfc23fa2..e19e7ed461c 100644
--- a/engines/ultima/nuvie/core/game_clock.cpp
+++ b/engines/ultima/nuvie/core/game_clock.cpp
@@ -295,7 +295,7 @@ uint8 GameClock::get_day_of_week() {
 
 char *GameClock::get_date_string() {
 
-	sprintf(date_string, "%2u-%02u-%04u", month, day, year);
+	Common::sprintf_s(date_string, "%2u-%02u-%04u", month, day, year);
 
 	return date_string;
 }
@@ -318,7 +318,7 @@ char *GameClock::get_time_string() {
 			tmp_hour = hour;
 	}
 
-	sprintf(time_string, "%0u:%02u %c.M.", tmp_hour, minute, c);
+	Common::sprintf_s(time_string, "%0u:%02u %c.M.", tmp_hour, minute, c);
 
 	return time_string;
 }
diff --git a/engines/ultima/nuvie/core/tile_manager.cpp b/engines/ultima/nuvie/core/tile_manager.cpp
index 85a733c52ae..1ff0fb8d50c 100644
--- a/engines/ultima/nuvie/core/tile_manager.cpp
+++ b/engines/ultima/nuvie/core/tile_manager.cpp
@@ -334,9 +334,9 @@ const char *TileManager::lookAtTile(uint16 tile_num, uint16 qty, bool show_prefi
 
 	if (qty > 0 &&
 	        (plural || Game::get_game()->get_game_type() == NUVIE_GAME_SE))
-		sprintf(desc_buf, "%u %s", qty, desc);
+		Common::sprintf_s(desc_buf, look->get_max_len() + 6, "%u %s", qty, desc);
 	else
-		sprintf(desc_buf, "%s%s", article_tbl[tileP->article_n], desc);
+		Common::sprintf_s(desc_buf, look->get_max_len() + 6, "%s%s", article_tbl[tileP->article_n], desc);
 
 	DEBUG(0, LEVEL_DEBUGGING, "%s (%x): flags1:", desc_buf, tile_num);
 	print_b(LEVEL_INFORMATIONAL, tileP->flags1);
diff --git a/engines/ultima/nuvie/fonts/font_manager.cpp b/engines/ultima/nuvie/fonts/font_manager.cpp
index d0a1d71fcce..359f1a185d4 100644
--- a/engines/ultima/nuvie/fonts/font_manager.cpp
+++ b/engines/ultima/nuvie/fonts/font_manager.cpp
@@ -163,7 +163,7 @@ bool FontManager::initConvFonts(nuvie_game_t game_type) {
 	datadir = path;
 
 	Std::string imagefile;
-	sprintf(filename, "%s.bmp", get_game_tag(Game::get_game()->get_game_type()));
+	Common::sprintf_s(filename, "%s.bmp", get_game_tag(Game::get_game()->get_game_type()));
 
 	build_path(datadir, filename, imagefile);
 
@@ -174,7 +174,7 @@ bool FontManager::initConvFonts(nuvie_game_t game_type) {
 	conv_font_data = bmp.getRawIndexedDataCopy();
 
 	Std::string widthfile;
-	sprintf(filename, "%s.dat", get_game_tag(Game::get_game()->get_game_type()));
+	Common::sprintf_s(filename, "%s.dat", get_game_tag(Game::get_game()->get_game_type()));
 
 	build_path(datadir, filename, widthfile);
 
diff --git a/engines/ultima/nuvie/gui/gui_dialog.cpp b/engines/ultima/nuvie/gui/gui_dialog.cpp
index 0d6280ee303..b1a28284b9d 100644
--- a/engines/ultima/nuvie/gui/gui_dialog.cpp
+++ b/engines/ultima/nuvie/gui/gui_dialog.cpp
@@ -60,7 +60,7 @@ void GUI_Dialog::loadBorderImages() {
 	Std::string imagefile;
 
 	for (i = 0; i < 8; i++) {
-		sprintf(filename, "Border%s_%d.bmp", "U6", i + 1);
+		Common::sprintf_s(filename, "Border%s_%d.bmp", "U6", i + 1);
 		build_path(datadir, filename, imagefile);
 		border[i] = SDL_LoadBMP(imagefile.c_str());
 		if (border[i] == NULL) {
diff --git a/engines/ultima/nuvie/gui/widgets/gui_widget.h b/engines/ultima/nuvie/gui/widgets/gui_widget.h
index c47f2428316..3c7ea1c801a 100644
--- a/engines/ultima/nuvie/gui/widgets/gui_widget.h
+++ b/engines/ultima/nuvie/gui/widgets/gui_widget.h
@@ -217,7 +217,7 @@ protected:
 		va_list ap;
 
 		va_start(ap, fmt);
-		vsprintf(errbuf, fmt, ap);
+		Common::vsprintf_s(errbuf, fmt, ap);
 		va_end(ap);
 		error = errbuf;
 	}
diff --git a/engines/ultima/nuvie/menus/audio_dialog.cpp b/engines/ultima/nuvie/menus/audio_dialog.cpp
index 3fe10daf470..a8beb037ee4 100644
--- a/engines/ultima/nuvie/menus/audio_dialog.cpp
+++ b/engines/ultima/nuvie/menus/audio_dialog.cpp
@@ -96,7 +96,7 @@ bool AudioDialog::init() {
 	const char *const yes_no_text[] = { "no", "yes" };
 
 	uint8 music_percent = round(sm->get_music_volume() / 2.55); // round needed for 10%, 30%, etc.
-	sprintf(musicBuff, "%u%%", music_percent);
+	Common::sprintf_s(musicBuff, "%u%%", music_percent);
 	const char *const musicVol_text[] = { "0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%", musicBuff };
 
 	if (music_percent % 10 == 0) {
@@ -108,7 +108,7 @@ bool AudioDialog::init() {
 	}
 
 	uint8 sfx_percent = round(sm->get_sfx_volume() / 2.55); // round needed for 10%, 30%, etc.
-	sprintf(sfxBuff, "%u%%", sfx_percent);
+	Common::sprintf_s(sfxBuff, "%u%%", sfx_percent);
 	const char *const sfxVol_text[] = { "0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%", sfxBuff };
 
 	if (sfx_percent % 10 == 0) {
diff --git a/engines/ultima/nuvie/menus/cheats_dialog.cpp b/engines/ultima/nuvie/menus/cheats_dialog.cpp
index 7c0b4a7baaf..441afc320b4 100644
--- a/engines/ultima/nuvie/menus/cheats_dialog.cpp
+++ b/engines/ultima/nuvie/menus/cheats_dialog.cpp
@@ -92,7 +92,7 @@ bool CheatsDialog::init() {
 	} else {
 		num_of_brightness = 9;
 		brightness_selection = 8; // manually edited setting or old 128
-		sprintf(buff, "%d", min_brightness);
+		Common::sprintf_s(buff, "%d", min_brightness);
 	}
 	const char *const brightness_text[] = { "0", "20", "40", "60", "80", "100", "120", "255", buff };
 
diff --git a/engines/ultima/nuvie/sound/adplug/mid.cpp b/engines/ultima/nuvie/sound/adplug/mid.cpp
index 696e5d218d7..188f01f4fab 100644
--- a/engines/ultima/nuvie/sound/adplug/mid.cpp
+++ b/engines/ultima/nuvie/sound/adplug/mid.cpp
@@ -522,8 +522,8 @@ void CmidPlayer::rewind(int subsong) {
 	}
 
 
-	/*        sprintf(info,"%s\r\nTicks/Quarter Note: %ld\r\n",info,deltas);
-	        sprintf(info,"%sms/Quarter Note: %ld",info,msqtr); */
+	/*        Common::sprintf_s(info,"%s\r\nTicks/Quarter Note: %ld\r\n",info,deltas);
+	        Common::sprintf_s(info,"%sms/Quarter Note: %ld",info,msqtr); */
 
 	for (i = 0; i < 16; i++)
 		if (track[i].on) {
diff --git a/engines/ultima/nuvie/sound/custom_sfx_manager.cpp b/engines/ultima/nuvie/sound/custom_sfx_manager.cpp
index 1825e8f13a4..05baaf7f05e 100644
--- a/engines/ultima/nuvie/sound/custom_sfx_manager.cpp
+++ b/engines/ultima/nuvie/sound/custom_sfx_manager.cpp
@@ -101,7 +101,7 @@ void CustomSfxManager::playSoundSample(uint16 sample_num, Audio::SoundHandle *lo
 	Std::string filename;
 	char wavefile[10]; // "nnnnn.wav\0"
 
-	sprintf(wavefile, "%d.wav", sample_num);
+	Common::sprintf_s(wavefile, "%d.wav", sample_num);
 
 	build_path(custom_filepath, wavefile, filename);
 
diff --git a/engines/ultima/nuvie/usecode/u6_usecode.cpp b/engines/ultima/nuvie/usecode/u6_usecode.cpp
index be75ff0248e..b236c4d839c 100644
--- a/engines/ultima/nuvie/usecode/u6_usecode.cpp
+++ b/engines/ultima/nuvie/usecode/u6_usecode.cpp
@@ -2348,7 +2348,7 @@ bool U6UseCode::use_sextant(Obj *obj, UseCodeEvent ev) {
 			lat = 'N';
 		}
 
-		sprintf(buf, "\n%d{%c, %d{%c\n", y, lat, x, lon);
+		Common::sprintf_s(buf, "\n%d{%c, %d{%c\n", y, lat, x, lon);
 		scroll->display_string(buf);
 	} else
 		scroll->display_string("\nNot usable\n");
diff --git a/engines/ultima/nuvie/views/actor_view.cpp b/engines/ultima/nuvie/views/actor_view.cpp
index 55f9dc2c9c6..1615684ee2e 100644
--- a/engines/ultima/nuvie/views/actor_view.cpp
+++ b/engines/ultima/nuvie/views/actor_view.cpp
@@ -212,46 +212,46 @@ void ActorView::display_actor_stats() {
 
 	hp_text_color = actor->get_hp_text_color();
 
-	sprintf(buf, "%d", Game::get_game()->get_script()->call_actor_str_adj(actor)); //actor->get_strength());
+	Common::sprintf_s(buf, "%d", Game::get_game()->get_script()->call_actor_str_adj(actor)); //actor->get_strength());
 	uint8 str_len = font->drawString(screen, "STR:", area.left + 5 * 16 + x_off, area.top + y_off + 16);
 	font->drawString(screen, buf, area.left + 5 * 16 + x_off + str_len, area.top + y_off + 16, actor->get_str_text_color(), 0);
 
-	sprintf(buf, "%d", Game::get_game()->get_script()->call_actor_dex_adj(actor));
+	Common::sprintf_s(buf, "%d", Game::get_game()->get_script()->call_actor_dex_adj(actor));
 	str_len = font->drawString(screen, "DEX:", area.left + 5 * 16 + x_off, area.top + y_off + 16 + 8);
 	font->drawString(screen, buf, area.left + 5 * 16 + x_off + str_len, area.top + y_off + 16 + 8, actor->get_dex_text_color(), 0);
 
-	sprintf(buf, "INT:%d", Game::get_game()->get_script()->call_actor_int_adj(actor));
+	Common::sprintf_s(buf, "INT:%d", Game::get_game()->get_script()->call_actor_int_adj(actor));
 	font->drawString(screen, buf, area.left + 5 * 16 + x_off, area.top + y_off + 16 + 2 * 8);
 
 	if (MD || Game::get_game()->get_game_type() == NUVIE_GAME_SE) {
-		sprintf(buf, "%3d", actor->get_hp());
+		Common::sprintf_s(buf, "%3d", actor->get_hp());
 		str_len = font->drawString(screen, "HP:", area.left + 5 * 16 + x_off, area.top + y_off + 16 + 3 * 8);
 		font->drawString(screen, buf, strlen(buf), area.left + 5 * 16 + x_off + str_len, area.top + y_off + 16 + 3 * 8, hp_text_color, 0);
 
-		sprintf(buf, "HM:%3d", actor->get_maxhp());
+		Common::sprintf_s(buf, "HM:%3d", actor->get_maxhp());
 		font->drawString(screen, buf, area.left + 5 * 16 + x_off, area.top + y_off + 16 + 4 * 8);
 
-		sprintf(buf, "Lev:%2d", actor->get_level());
+		Common::sprintf_s(buf, "Lev:%2d", actor->get_level());
 		font->drawString(screen, buf, area.left + 5 * 16 + x_off, area.top + y_off + 16 + 5 * 8);
 
 		font->drawString(screen, "Exper:", area.left + 5 * 16 + x_off, area.top + y_off + 16 + 6 * 8);
-		sprintf(buf, "%6d", actor->get_exp());
+		Common::sprintf_s(buf, "%6d", actor->get_exp());
 		font->drawString(screen, buf, area.left + 5 * 16 + x_off, area.top + y_off + 16 + 7 * 8);
 		return;
 	}
 
 	font->drawString(screen, "Magic", area.left + 5 * 16, area.top + 16 + 4 * 8);
-	sprintf(buf, "%d/%d", actor->get_magic(), actor->get_maxmagic());
+	Common::sprintf_s(buf, "%d/%d", actor->get_magic(), actor->get_maxmagic());
 	font->drawString(screen, buf, area.left + 5 * 16, area.top + 16 + 5 * 8);
 
 	font->drawString(screen, "Health", area.left + 5 * 16, area.top + 16 + 6 * 8);
-	sprintf(buf, "%3d", actor->get_hp());
+	Common::sprintf_s(buf, "%3d", actor->get_hp());
 	font->drawString(screen, buf, strlen(buf), area.left + 5 * 16, area.top + 16 + 7 * 8, hp_text_color, 0);
-	sprintf(buf, "   /%d", actor->get_maxhp());
+	Common::sprintf_s(buf, "   /%d", actor->get_maxhp());
 	font->drawString(screen, buf, area.left + 5 * 16, area.top + 16 + 7 * 8);
 
 	font->drawString(screen, "Lev/Exp", area.left + 5 * 16, area.top + 16 + 8 * 8);
-	sprintf(buf, "%d/%d", actor->get_level(), actor->get_exp());
+	Common::sprintf_s(buf, "%d/%d", actor->get_level(), actor->get_exp());
 	font->drawString(screen, buf, area.left + 5 * 16, area.top + 16 + 9 * 8);
 
 	return;
diff --git a/engines/ultima/nuvie/views/container_widget.cpp b/engines/ultima/nuvie/views/container_widget.cpp
index 15e0518729a..fe7d56a58cc 100644
--- a/engines/ultima/nuvie/views/container_widget.cpp
+++ b/engines/ultima/nuvie/views/container_widget.cpp
@@ -177,7 +177,7 @@ void ContainerWidget::display_qty_string(uint16 x, uint16 y, uint16 qty) {
 	uint8 len, i, offset;
 	char buf[6];
 
-	sprintf(buf, "%d", qty);
+	Common::sprintf_s(buf, "%d", qty);
 	len = strlen(buf);
 
 	offset = (16 - len * 4) / 2;
diff --git a/engines/ultima/nuvie/views/inventory_widget.cpp b/engines/ultima/nuvie/views/inventory_widget.cpp
index 39916b1ca9a..124a8653504 100644
--- a/engines/ultima/nuvie/views/inventory_widget.cpp
+++ b/engines/ultima/nuvie/views/inventory_widget.cpp
@@ -234,7 +234,7 @@ void InventoryWidget::display_qty_string(uint16 x, uint16 y, uint16 qty) {
 	uint8 len, i, offset;
 	char buf[6];
 
-	sprintf(buf, "%d", qty);
+	Common::sprintf_s(buf, "%d", qty);
 	len = strlen(buf);
 
 	offset = (16 - len * 4) / 2;
diff --git a/engines/ultima/nuvie/views/party_view.cpp b/engines/ultima/nuvie/views/party_view.cpp
index 325f5df4e46..2f7312863e4 100644
--- a/engines/ultima/nuvie/views/party_view.cpp
+++ b/engines/ultima/nuvie/views/party_view.cpp
@@ -332,7 +332,7 @@ void PartyView::Display(bool full_redraw) {
 				y_offset = -3;
 			// FIXME: Martian Dreams text is somewhat center aligned
 			font->drawString(screen, actor_name, area.left + x_offset + 24, area.top + y_offset + (i - row_offset) * rowH + 8);
-			sprintf(hp_string, "%3d", actor->get_hp());
+			Common::sprintf_s(hp_string, "%3d", actor->get_hp());
 			hp_text_color = actor->get_hp_text_color();
 			if (SE) {
 				x_offset = -7;
diff --git a/engines/ultima/nuvie/views/spell_view_gump.cpp b/engines/ultima/nuvie/views/spell_view_gump.cpp
index 3be09aa2a8e..2978034aeec 100644
--- a/engines/ultima/nuvie/views/spell_view_gump.cpp
+++ b/engines/ultima/nuvie/views/spell_view_gump.cpp
@@ -127,7 +127,7 @@ uint8 SpellViewGump::fill_cur_spell_list() {
 	set_bg_color_key(0, 0x70, 0xfc);
 
 	for (i = 0; i < count; i++) {
-		sprintf(filename, "spellbook_spell_%03d.bmp", cur_spells[i]);
+		Common::sprintf_s(filename, "spellbook_spell_%03d.bmp", cur_spells[i]);
 		build_path(datadir, filename, imagefile);
 		Graphics::ManagedSurface *spell_image = bmp.getSdlSurface32(imagefile);
 		if (spell_image == NULL) {
@@ -158,7 +158,7 @@ void SpellViewGump::loadCircleString(Std::string datadir) {
 	Std::string imagefile;
 	char filename[7]; // n.bmp\0
 
-	sprintf(filename, "%d.bmp", level);
+	Common::sprintf_s(filename, "%d.bmp", level);
 	build_path(datadir, filename, imagefile);
 
 	Graphics::ManagedSurface *s = bmp.getSdlSurface32(imagefile);
diff --git a/engines/ultima/nuvie/views/sun_moon_ribbon.cpp b/engines/ultima/nuvie/views/sun_moon_ribbon.cpp
index d3ec1fcbdfc..45d191775a4 100644
--- a/engines/ultima/nuvie/views/sun_moon_ribbon.cpp
+++ b/engines/ultima/nuvie/views/sun_moon_ribbon.cpp
@@ -72,7 +72,7 @@ void SunMoonRibbon::loadBgImage(uint8 num) {
 	build_path(datadir, "celestial", path);
 	datadir = path;
 
-	sprintf(filename, "%d.bmp", num);
+	Common::sprintf_s(filename, "%d.bmp", num);
 	build_path(datadir, filename, imagefile);
 
 	if (bg_data)
diff --git a/engines/ultima/nuvie/views/view_manager.cpp b/engines/ultima/nuvie/views/view_manager.cpp
index f07f2eb833b..74e2cbc77c0 100644
--- a/engines/ultima/nuvie/views/view_manager.cpp
+++ b/engines/ultima/nuvie/views/view_manager.cpp
@@ -547,7 +547,7 @@ Graphics::ManagedSurface *ViewManager::loadAvatarDollImage(Graphics::ManagedSurf
 	Std::string imagefile;
 	uint8 portrait_num = Game::get_game()->get_portrait()->get_avatar_portrait_num();
 
-	sprintf(filename, "avatar_%s_%02d.bmp", get_game_tag(Game::get_game()->get_game_type()), portrait_num);
+	Common::sprintf_s(filename, "avatar_%s_%02d.bmp", get_game_tag(Game::get_game()->get_game_type()), portrait_num);
 	if (orig) {
 		build_path(getDollDataDirString(), "orig_style", imagefile);
 		build_path(imagefile, filename, imagefile);
@@ -570,7 +570,7 @@ Graphics::ManagedSurface *ViewManager::loadCustomActorDollImage(Graphics::Manage
 	if (actor_doll != NULL)
 		SDL_FreeSurface(actor_doll);
 
-	sprintf(filename, "actor_%s_%03d.bmp", get_game_tag(Game::get_game()->get_game_type()), actor_num);
+	Common::sprintf_s(filename, "actor_%s_%03d.bmp", get_game_tag(Game::get_game()->get_game_type()), actor_num);
 	if (orig) {
 		build_path(getDollDataDirString(), "orig_style", imagefile);
 		build_path(imagefile, filename, imagefile);
@@ -589,7 +589,7 @@ Graphics::ManagedSurface *ViewManager::loadGenericDollImage(bool orig) {
 	char filename[14]; //avatar_nn.bmp\0
 	Std::string imagefile;
 
-	sprintf(filename, "actor_%s.bmp", get_game_tag(Game::get_game()->get_game_type()));
+	Common::sprintf_s(filename, "actor_%s.bmp", get_game_tag(Game::get_game()->get_game_type()));
 	if (orig) {
 		build_path(getDollDataDirString(), "orig_style", imagefile);
 		build_path(imagefile, filename, imagefile);
diff --git a/engines/ultima/ultima4/controllers/intro_controller.cpp b/engines/ultima/ultima4/controllers/intro_controller.cpp
index ed8584a766e..188cc5f70d9 100644
--- a/engines/ultima/ultima4/controllers/intro_controller.cpp
+++ b/engines/ultima/ultima4/controllers/intro_controller.cpp
@@ -584,7 +584,7 @@ void IntroController::drawBeastie(int beast, int vertoffset, int frame) {
 
 	assertMsg(beast == 0 || beast == 1, "invalid beast: %d", beast);
 
-	sprintf(buffer, "beast%dframe%02d", beast, frame);
+	Common::sprintf_s(buffer, "beast%dframe%02d", beast, frame);
 
 	destx = beast ? (320 - 48) : 0;
 	_backgroundArea.draw(buffer, destx, vertoffset);
diff --git a/engines/ultima/ultima4/core/utils.cpp b/engines/ultima/ultima4/core/utils.cpp
index 786d570d942..2e55b1303dc 100644
--- a/engines/ultima/ultima4/core/utils.cpp
+++ b/engines/ultima/ultima4/core/utils.cpp
@@ -76,7 +76,7 @@ Common::String &uppercase(Common::String &val) {
 
 Common::String xu4_to_string(int val) {
 	char buffer[16];
-	sprintf(buffer, "%d", val);
+	Common::sprintf_s(buffer, "%d", val);
 	return buffer;
 }
 
diff --git a/engines/ultima/ultima4/game/portal.cpp b/engines/ultima/ultima4/game/portal.cpp
index c4be510afb8..d4c33ff7f46 100644
--- a/engines/ultima/ultima4/game/portal.cpp
+++ b/engines/ultima/ultima4/game/portal.cpp
@@ -95,13 +95,13 @@ int usePortalAt(Location *location, MapCoords coords, PortalTriggerAction action
 
 		switch (action) {
 		case ACTION_DESCEND:
-			sprintf(msg, "Descend down to level %d\n", portal->_start.z + 1);
+			Common::sprintf_s(msg, "Descend down to level %d\n", portal->_start.z + 1);
 			break;
 		case ACTION_KLIMB:
 			if (portal->_exitPortal)
-				sprintf(msg, "Klimb up!\nLeaving...\n");
+				Common::sprintf_s(msg, "Klimb up!\nLeaving...\n");
 			else
-				sprintf(msg, "Klimb up!\nTo level %d\n", portal->_start.z + 1);
+				Common::sprintf_s(msg, "Klimb up!\nTo level %d\n", portal->_start.z + 1);
 			break;
 		case ACTION_ENTER:
 			switch (destination->_type) {
diff --git a/engines/ultima/ultima8/games/game_data.cpp b/engines/ultima/ultima8/games/game_data.cpp
index 16cac613b5a..3866bb90603 100644
--- a/engines/ultima/ultima8/games/game_data.cpp
+++ b/engines/ultima/ultima8/games/game_data.cpp
@@ -207,7 +207,7 @@ FrameID GameData::translate(FrameID f) {
 	}
 
 	char buf[100];
-	sprintf(buf, "%d,%d", f._shapeNum, f._frameNum);
+	Common::sprintf_s(buf, "%d,%d", f._shapeNum, f._frameNum);
 
 	istring key = buf;
 	Std::string trans;
diff --git a/engines/ultima/ultima8/games/game_info.cpp b/engines/ultima/ultima8/games/game_info.cpp
index 3e54614d9bf..7a1ca7ccfd9 100644
--- a/engines/ultima/ultima8/games/game_info.cpp
+++ b/engines/ultima/ultima8/games/game_info.cpp
@@ -113,7 +113,7 @@ Std::string GameInfo::getGameTitle() const {
 
 Std::string GameInfo::getPrintableVersion() const {
 	char buf[32];
-	sprintf(buf, "%d.%02d", version / 100, version % 100);
+	Common::sprintf_s(buf, "%d.%02d", version / 100, version % 100);
 	return buf;
 }
 
@@ -148,7 +148,7 @@ Std::string GameInfo::getPrintableMD5() const {
 
 	char buf[33];
 	for (int i = 0; i < 16; ++i) {
-		sprintf(buf + 2 * i, "%02x", _md5[i]);
+		Common::sprintf_s(buf + 2 * i, 3, "%02x", _md5[i]);
 	}
 
 	ret = buf;
@@ -176,7 +176,7 @@ void GameInfo::save(Common::WriteStream *ws) {
 	Std::string lang = gamelangs[l].name;
 
 	char buf[16];
-	sprintf(buf, "%d", version);
+	Common::sprintf_s(buf, "%d", version);
 	Std::string ver = buf;
 	Std::string md5Str = getPrintableMD5();
 
diff --git a/engines/ultima/ultima8/gumps/paperdoll_gump.cpp b/engines/ultima/ultima8/gumps/paperdoll_gump.cpp
index 2911742ab4c..b905c3c229b 100644
--- a/engines/ultima/ultima8/gumps/paperdoll_gump.cpp
+++ b/engines/ultima/ultima8/gumps/paperdoll_gump.cpp
@@ -154,7 +154,7 @@ void PaperdollGump::PaintStat(RenderSurface *surf, unsigned int n,
 
 	if (!_cachedText[2 * n + 1] || _cachedVal[n] != val) {
 		delete _cachedText[2 * n + 1];
-		sprintf(buf, "%d", val);
+		Common::sprintf_s(buf, "%d", val);
 		_cachedText[2 * n + 1] = font->renderText(buf, remaining,
 		                         statwidth, statheight,
 		                         Font::TEXT_RIGHT);
diff --git a/engines/ultima/ultima8/gumps/shape_viewer_gump.cpp b/engines/ultima/ultima8/gumps/shape_viewer_gump.cpp
index 7a1d066eb75..c90ba9c6594 100644
--- a/engines/ultima/ultima8/gumps/shape_viewer_gump.cpp
+++ b/engines/ultima/ultima8/gumps/shape_viewer_gump.cpp
@@ -106,11 +106,11 @@ void ShapeViewerGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool /*s
 		char buf1[50];
 		char buf2[200];
 		if (!shape) {
-			sprintf(buf1, "NULL");
+			Common::sprintf_s(buf1, "NULL");
 		} else {
-			sprintf(buf1, "Frame %d of %d", _curFrame+1, shape->frameCount());
+			Common::sprintf_s(buf1, "Frame %d of %d", _curFrame+1, shape->frameCount());
 		}
-		sprintf(buf2, "%s:  Shape %d, %s", _flexes[_curFlex].first.c_str(),
+		Common::sprintf_s(buf2, "%s:  Shape %d, %s", _flexes[_curFlex].first.c_str(),
 				_curShape, buf1);
 		rendtext = font->renderText(buf2, remaining);
 		rendtext->draw(surf, 20, 10);
@@ -139,7 +139,7 @@ void ShapeViewerGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool /*s
 				uint8 px_g = shape->getPalette()->_palette[rawpx * 3 + 1];
 				uint8 px_b = shape->getPalette()->_palette[rawpx * 3 + 2];
 
-				sprintf(buf2, "px: (%d, %d)(%d, %d): %d (%d, %d, %d)", relx, rely, frame->_xoff, frame->_yoff, rawpx, px_r, px_g, px_b);
+				Common::sprintf_s(buf2, "px: (%d, %d)(%d, %d): %d (%d, %d, %d)", relx, rely, frame->_xoff, frame->_yoff, rawpx, px_r, px_g, px_b);
 				rendtext = font->renderText(buf2, remaining);
 				rendtext->draw(surf, 20, 25);
 				delete rendtext;
@@ -159,13 +159,13 @@ void ShapeViewerGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool /*s
 		char buf6[512];
 		const ShapeInfo *info = mainshapes->getShapeInfo(_curShape);
 		if (info) {
-			sprintf(buf3, "x: %d, y: %d, z: %d\n flags: 0x%04X, family: %d",
+			Common::sprintf_s(buf3, "x: %d, y: %d, z: %d\n flags: 0x%04X, family: %d",
 					info->_x, info->_y, info->_z, info->_flags, info->_family);
-			sprintf(buf4, "equip type: %d, weight: %d, vol: %d",
+			Common::sprintf_s(buf4, "equip type: %d, weight: %d, vol: %d",
 					info->_equipType, info->_weight, info->_volume);
-			sprintf(buf5, "anim:  type: %d, data: %d, speed: %d",
+			Common::sprintf_s(buf5, "anim:  type: %d, data: %d, speed: %d",
 					info->_animType, info->_animData, info->_animSpeed);
-			sprintf(buf6, "ShapeInfo: %s\n%s\n%s\nUsecode: %s",
+			Common::sprintf_s(buf6, "ShapeInfo: %s\n%s\n%s\nUsecode: %s",
 					buf3, buf4, buf5, GameData::get_instance()->getMainUsecode()->get_class_name(_curShape));
 			rendtext = font->renderText(buf6, remaining);
 			rendtext->draw(surf, 20, _dims.height() - 58);
diff --git a/engines/ultima/ultima8/gumps/slider_gump.cpp b/engines/ultima/ultima8/gumps/slider_gump.cpp
index 1a529309332..00b102da9b8 100644
--- a/engines/ultima/ultima8/gumps/slider_gump.cpp
+++ b/engines/ultima/ultima8/gumps/slider_gump.cpp
@@ -99,7 +99,7 @@ void SliderGump::drawText(RenderSurface *surf) {
 		Font *font;
 		font = FontManager::get_instance()->getGameFont(labelfont);
 		char buf[10]; // more than enough for a int16
-		sprintf(buf, "%d", _value);
+		Common::sprintf_s(buf, "%d", _value);
 
 		unsigned int remaining;
 		delete _renderedText;


Commit: 4c18545085065e0c72e980c6d54595d572056942
    https://github.com/scummvm/scummvm/commit/4c18545085065e0c72e980c6d54595d572056942
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
WAGE: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/wage/world.cpp


diff --git a/engines/wage/world.cpp b/engines/wage/world.cpp
index a5b83675f1e..5eec4ebdc57 100644
--- a/engines/wage/world.cpp
+++ b/engines/wage/world.cpp
@@ -537,7 +537,7 @@ const char *World::getAboutMenuItemName() {
 	*menu = '\0';
 
 	if (_aboutMenuItemName.empty()) {
-		sprintf(menu, "About %s...", _name.c_str());
+		Common::sprintf_s(menu, "About %s...", _name.c_str());
 	} else { // Replace '@' with name
 		const char *str = _aboutMenuItemName.c_str();
 		const char *pos = strchr(str, '@');


Commit: 62f105c0cef71edd7549079973dbe39d789fdcf2
    https://github.com/scummvm/scummvm/commit/62f105c0cef71edd7549079973dbe39d789fdcf2
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
WINTERMUTE: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/wintermute/ad/ad_game.cpp
    engines/wintermute/ad/ad_item.cpp
    engines/wintermute/base/base_dynamic_buffer.cpp
    engines/wintermute/base/base_engine.cpp
    engines/wintermute/base/base_game.cpp
    engines/wintermute/base/scriptables/script_ext_array.cpp
    engines/wintermute/base/scriptables/script_ext_file.cpp
    engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
    engines/wintermute/base/scriptables/script_value.cpp


diff --git a/engines/wintermute/ad/ad_game.cpp b/engines/wintermute/ad/ad_game.cpp
index db3c1d189d5..39759fddb8c 100644
--- a/engines/wintermute/ad/ad_game.cpp
+++ b/engines/wintermute/ad/ad_game.cpp
@@ -1899,11 +1899,10 @@ bool AdGame::windowScriptMethodHook(UIWindow *win, ScScript *script, ScStack *st
 
 //////////////////////////////////////////////////////////////////////////
 bool AdGame::startDlgBranch(const char *branchName, const char *scriptName, const char *eventName) {
-	char *name = new char[strlen(branchName) + 1 + strlen(scriptName) + 1 + strlen(eventName) + 1];
-	if (name) {
-		sprintf(name, "%s.%s.%s", branchName, scriptName, eventName);
-		_dlgPendingBranches.add(name);
-	}
+	size_t sz = strlen(branchName) + 1 + strlen(scriptName) + 1 + strlen(eventName) + 1;
+	char *name = new char[sz];
+	Common::sprintf_s(name, sz, "%s.%s.%s", branchName, scriptName, eventName);
+	_dlgPendingBranches.add(name);
 	return STATUS_OK;
 }
 
@@ -1916,11 +1915,10 @@ bool AdGame::endDlgBranch(const char *branchName, const char *scriptName, const
 		name = _dlgPendingBranches[_dlgPendingBranches.size() - 1];
 	} else {
 		if (branchName != nullptr) {
-			name = new char[strlen(branchName) + 1 + strlen(scriptName) + 1 + strlen(eventName) + 1];
-			if (name) {
-				sprintf(name, "%s.%s.%s", branchName, scriptName, eventName);
-				deleteName = true;
-			}
+			size_t sz = strlen(branchName) + 1 + strlen(scriptName) + 1 + strlen(eventName) + 1;
+			name = new char[sz];
+			Common::sprintf_s(name, sz, "%s.%s.%s", branchName, scriptName, eventName);
+			deleteName = true;
 		}
 	}
 
@@ -2327,12 +2325,12 @@ char *AdGame::findSpeechFile(char *stringID) {
 	char *ret = new char[MAX_PATH_LENGTH];
 
 	for (uint32 i = 0; i < _speechDirs.size(); i++) {
-		sprintf(ret, "%s%s.ogg", _speechDirs[i], stringID);
+		Common::sprintf_s(ret, MAX_PATH_LENGTH, "%s%s.ogg", _speechDirs[i], stringID);
 		if (BaseFileManager::getEngineInstance()->hasFile(ret)) {
 			return ret;
 		}
 
-		sprintf(ret, "%s%s.wav", _speechDirs[i], stringID);
+		Common::sprintf_s(ret, MAX_PATH_LENGTH, "%s%s.wav", _speechDirs[i], stringID);
 		if (BaseFileManager::getEngineInstance()->hasFile(ret)) {
 			return ret;
 		}
@@ -2486,10 +2484,10 @@ bool AdGame::onMouseRightUp() {
 bool AdGame::displayDebugInfo() {
 	char str[100];
 	if (_gameRef->_debugDebugMode) {
-		sprintf(str, "Mouse: %d, %d (scene: %d, %d)", _mousePos.x, _mousePos.y, _mousePos.x + (_scene ? _scene->getOffsetLeft() : 0), _mousePos.y + (_scene ? _scene->getOffsetTop() : 0));
+		Common::sprintf_s(str, "Mouse: %d, %d (scene: %d, %d)", _mousePos.x, _mousePos.y, _mousePos.x + (_scene ? _scene->getOffsetLeft() : 0), _mousePos.y + (_scene ? _scene->getOffsetTop() : 0));
 		_systemFont->drawText((byte *)str, 0, 90, _renderer->getWidth(), TAL_RIGHT);
 
-		sprintf(str, "Scene: %s (prev: %s)", (_scene && _scene->getName()) ? _scene->getName() : "???", _prevSceneName ? _prevSceneName : "???");
+		Common::sprintf_s(str, "Scene: %s (prev: %s)", (_scene && _scene->getName()) ? _scene->getName() : "???", _prevSceneName ? _prevSceneName : "???");
 		_systemFont->drawText((byte *)str, 0, 110, _renderer->getWidth(), TAL_RIGHT);
 	}
 	return BaseGame::displayDebugInfo();
diff --git a/engines/wintermute/ad/ad_item.cpp b/engines/wintermute/ad/ad_item.cpp
index ba171f5e9de..1fdf4d70f34 100644
--- a/engines/wintermute/ad/ad_item.cpp
+++ b/engines/wintermute/ad/ad_item.cpp
@@ -443,7 +443,7 @@ bool AdItem::display(int x, int y) {
 				font->drawText((byte *)_amountString, amountX, amountY, width, _amountAlign);
 			} else {
 				char str[256];
-				sprintf(str, "%d", _amount);
+				Common::sprintf_s(str, "%d", _amount);
 				font->drawText((byte *)str, amountX, amountY, width, _amountAlign);
 			}
 		}
diff --git a/engines/wintermute/base/base_dynamic_buffer.cpp b/engines/wintermute/base/base_dynamic_buffer.cpp
index db241fc1d43..3c2d013576d 100644
--- a/engines/wintermute/base/base_dynamic_buffer.cpp
+++ b/engines/wintermute/base/base_dynamic_buffer.cpp
@@ -196,7 +196,7 @@ void BaseDynamicBuffer::putTextIndent(int indent, const char *fmt, ...) {
 //////////////////////////////////////////////////////////////////////////
 void BaseDynamicBuffer::putTextForm(const char *format, va_list argptr) {
 	char buff[32768];
-	vsprintf(buff, format, argptr);
+	Common::vsprintf_s(buff, format, argptr);
 	putBytes((byte *)buff, strlen(buff));
 }
 
diff --git a/engines/wintermute/base/base_engine.cpp b/engines/wintermute/base/base_engine.cpp
index aced034014c..44620326074 100644
--- a/engines/wintermute/base/base_engine.cpp
+++ b/engines/wintermute/base/base_engine.cpp
@@ -82,7 +82,7 @@ void BaseEngine::LOG(bool res, const char *fmt, ...) {
 	va_list va;
 
 	va_start(va, fmt);
-	vsprintf(buff, fmt, va);
+	Common::vsprintf_s(buff, fmt, va);
 	va_end(va);
 
 	if (instance()._gameRef) {
diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp
index 3864063f6d5..e5829c5cd3f 100644
--- a/engines/wintermute/base/base_game.cpp
+++ b/engines/wintermute/base/base_game.cpp
@@ -641,7 +641,7 @@ void BaseGame::LOG(bool res, const char *fmt, ...) {
 	va_list va;
 
 	va_start(va, fmt);
-	vsprintf(buff, fmt, va);
+	Common::vsprintf_s(buff, fmt, va);
 	va_end(va);
 
 	// redirect to an engine's own callback
@@ -1803,7 +1803,7 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
 		int fileNum = 0;
 
 		while (true) {
-			sprintf(filename, "%s%03d.bmp", val->isNULL() ? getName() : val->getString(), fileNum);
+			Common::sprintf_s(filename, "%s%03d.bmp", val->isNULL() ? getName() : val->getString(), fileNum);
 			if (!Common::File::exists(filename)) {
 				break;
 			}
@@ -2124,7 +2124,7 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
 
 			if (asHex) {
 				char hex[100];
-				sprintf(hex, "%x", checksum);
+				Common::sprintf_s(hex, "%x", checksum);
 				stack->pushString(hex);
 			} else {
 				stack->pushInt(checksum);
@@ -2958,7 +2958,7 @@ ScValue *BaseGame::scGetProperty(const Common::String &name) {
 			gameVersion = fileManager->getPackageVersion("data.dcp");
 		}
 		char tmp[16];
-		sprintf(tmp,"%u",gameVersion);
+		Common::sprintf_s(tmp,"%u",gameVersion);
 		_scValue->setString(tmp);
 		return _scValue;
 	}
@@ -3294,7 +3294,7 @@ void BaseGame::quickMessageForm(char *fmt, ...) {
 	va_list va;
 
 	va_start(va, fmt);
-	vsprintf(buff, fmt, va);
+	Common::vsprintf_s(buff, fmt, va);
 	va_end(va);
 
 	quickMessage(buff);
@@ -4587,15 +4587,15 @@ bool BaseGame::displayDebugInfo() {
 	char str[strLength];
 
 	if (_debugShowFPS) {
-		sprintf(str, "FPS: %d", _gameRef->_fps);
+		Common::sprintf_s(str, "FPS: %d", _gameRef->_fps);
 		_systemFont->drawText((byte *)str, 0, 0, 100, TAL_LEFT);
 	}
 
 	if (_gameRef->_debugDebugMode) {
 		if (!_gameRef->_renderer->isWindowed()) {
-			sprintf(str, "Mode: %dx%dx%d", _renderer->getWidth(), _renderer->getHeight(), _renderer->getBPP());
+			Common::sprintf_s(str, "Mode: %dx%dx%d", _renderer->getWidth(), _renderer->getHeight(), _renderer->getBPP());
 		} else {
-			sprintf(str, "Mode: %dx%d windowed", _renderer->getWidth(), _renderer->getHeight());
+			Common::sprintf_s(str, "Mode: %dx%d windowed", _renderer->getWidth(), _renderer->getHeight());
 		}
 
 		Common::strlcat(str, " (", strLength);
@@ -4607,18 +4607,18 @@ bool BaseGame::displayDebugInfo() {
 
 		int scrTotal, scrRunning, scrWaiting, scrPersistent;
 		scrTotal = _scEngine->getNumScripts(&scrRunning, &scrWaiting, &scrPersistent);
-		sprintf(str, "Running scripts: %d (r:%d w:%d p:%d)", scrTotal, scrRunning, scrWaiting, scrPersistent);
+		Common::sprintf_s(str, "Running scripts: %d (r:%d w:%d p:%d)", scrTotal, scrRunning, scrWaiting, scrPersistent);
 		_systemFont->drawText((byte *)str, 0, 70, _renderer->getWidth(), TAL_RIGHT);
 
 
-		sprintf(str, "Timer: %d", getTimer()->getTime());
+		Common::sprintf_s(str, "Timer: %d", getTimer()->getTime());
 		_gameRef->_systemFont->drawText((byte *)str, 0, 130, _renderer->getWidth(), TAL_RIGHT);
 
 		if (_activeObject != nullptr) {
 			_systemFont->drawText((const byte *)_activeObject->getName(), 0, 150, _renderer->getWidth(), TAL_RIGHT);
 		}
 
-		sprintf(str, "GfxMem: %dMB", _usedMem / (1024 * 1024));
+		Common::sprintf_s(str, "GfxMem: %dMB", _usedMem / (1024 * 1024));
 		_systemFont->drawText((byte *)str, 0, 170, _renderer->getWidth(), TAL_RIGHT);
 
 	}
diff --git a/engines/wintermute/base/scriptables/script_ext_array.cpp b/engines/wintermute/base/scriptables/script_ext_array.cpp
index 7ebf44d4041..1ab2462ce21 100644
--- a/engines/wintermute/base/scriptables/script_ext_array.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_array.cpp
@@ -52,7 +52,7 @@ SXArray::SXArray(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
 		_length = numParams;
 		char paramName[20];
 		for (int i = 0; i < numParams; i++) {
-			sprintf(paramName, "%d", i);
+			Common::sprintf_s(paramName, "%d", i);
 			_values->setProp(paramName, stack->pop());
 		}
 	}
@@ -78,7 +78,7 @@ const char *SXArray::scToString() {
 	dummy[0] = '\0';
 	char propName[20];
 	for (int i = 0; i < _length; i++) {
-		sprintf(propName, "%d", i);
+		Common::sprintf_s(propName, "%d", i);
 		ScValue *val = _values->getProp(propName);
 		if (val) {
 			if (strlen(dummy) + strlen(val->getString()) < 32768) {
@@ -106,7 +106,7 @@ bool SXArray::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack,
 
 		for (int i = 0; i < numParams; i++) {
 			_length++;
-			sprintf(paramName, "%d", _length - 1);
+			Common::sprintf_s(paramName, "%d", _length - 1);
 			_values->setProp(paramName, stack->pop(), true);
 		}
 		stack->pushInt(_length);
@@ -122,7 +122,7 @@ bool SXArray::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack,
 
 		if (_length > 0) {
 			char paramName[20];
-			sprintf(paramName, "%d", _length - 1);
+			Common::sprintf_s(paramName, "%d", _length - 1);
 			stack->push(_values->getProp(paramName));
 			_values->deleteProp(paramName);
 			_length--;
@@ -148,8 +148,8 @@ bool SXArray::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack,
 		char paramNameTo[20];
 
 		for (int i = shiftPoint; i < _length - 1 ; i++) {
-			sprintf(paramNameFrom, "%d", i + 1);
-			sprintf(paramNameTo, "%d", i);
+			Common::sprintf_s(paramNameFrom, "%d", i + 1);
+			Common::sprintf_s(paramNameTo, "%d", i);
 			_values->setProp(paramNameTo, _values->getProp(paramNameFrom), false);
 		}
 		_values->deleteProp(paramNameFrom);
@@ -212,7 +212,7 @@ bool SXArray::scSetProperty(const char *name, ScValue *value) {
 		char propName[20];
 		if (_length < origLength) {
 			for (int i = _length; i < origLength; i++) {
-				sprintf(propName, "%d", i);
+				Common::sprintf_s(propName, "%d", i);
 				_values->deleteProp(propName);
 			}
 		}
@@ -260,7 +260,7 @@ bool SXArray::validNumber(const char *origStr, char *outStr) {
 
 	if (isNumber) {
 		int index = atoi(origStr);
-		sprintf(outStr, "%d", index);
+		Common::sprintf_s(outStr, 20, "%d", index);
 		return true;
 	} else {
 		return false;
@@ -271,7 +271,7 @@ bool SXArray::validNumber(const char *origStr, char *outStr) {
 bool SXArray::push(ScValue *val) {
 	char paramName[20];
 	_length++;
-	sprintf(paramName, "%d", _length - 1);
+	Common::sprintf_s(paramName, "%d", _length - 1);
 	_values->setProp(paramName, val, true);
 	return STATUS_OK;
 }
diff --git a/engines/wintermute/base/scriptables/script_ext_file.cpp b/engines/wintermute/base/scriptables/script_ext_file.cpp
index aad00c6f9d6..f934818a17c 100644
--- a/engines/wintermute/base/scriptables/script_ext_file.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_file.cpp
@@ -708,7 +708,7 @@ bool SXFile::scSetProperty(const char *name, ScValue *value) {
 	    char propName[20];
 	    if (_length < OrigLength) {
 	        for(int i=_length; i<OrigLength; i++) {
-	            sprintf(PropName, "%d", i);
+	            Common::sprintf_s(PropName, "%d", i);
 	            _values->DeleteProp(PropName);
 	        }
 	    }
diff --git a/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp b/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
index 429ab2ea57d..5a94100bf40 100644
--- a/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
@@ -482,7 +482,7 @@ bool SXMemBuffer::scSetProperty(const char *name, ScValue *value) {
 	    char propName[20];
 	    if (_length < origLength) {
 	        for(int i=_length; i < origLength; i++) {
-	            sprintf(propName, "%d", i);
+	            Common::sprintf_s(propName, "%d", i);
 	            _values->DeleteProp(propName);
 	        }
 	    }
diff --git a/engines/wintermute/base/scriptables/script_value.cpp b/engines/wintermute/base/scriptables/script_value.cpp
index 2cca3923bf6..91ccfb64706 100644
--- a/engines/wintermute/base/scriptables/script_value.cpp
+++ b/engines/wintermute/base/scriptables/script_value.cpp
@@ -656,14 +656,14 @@ const char *ScValue::getString() {
 
 	case VAL_INT: {
 		char dummy[50];
-		sprintf(dummy, "%d", _valInt);
+		Common::sprintf_s(dummy, "%d", _valInt);
 		setStringVal(dummy);
 		break;
 	}
 
 	case VAL_FLOAT: {
 		char dummy[50];
-		sprintf(dummy, "%f", _valFloat);
+		Common::sprintf_s(dummy, "%f", _valFloat);
 		setStringVal(dummy);
 		break;
 	}


Commit: 26dd9a05fae858fe5f488b399e0ea1848a0b3bf7
    https://github.com/scummvm/scummvm/commit/26dd9a05fae858fe5f488b399e0ea1848a0b3bf7
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
ZVISION: Don't use unsafe sprintf and vsprintf

Changed paths:
    engines/zvision/scripting/controls/slot_control.cpp
    engines/zvision/scripting/menu.cpp


diff --git a/engines/zvision/scripting/controls/slot_control.cpp b/engines/zvision/scripting/controls/slot_control.cpp
index 9fecf533012..b4b0ce76bfd 100644
--- a/engines/zvision/scripting/controls/slot_control.cpp
+++ b/engines/zvision/scripting/controls/slot_control.cpp
@@ -182,9 +182,9 @@ bool SlotControl::process(uint32 deltaTimeInMillis) {
 
 				char buf[16];
 				if (_engine->getGameId() == GID_NEMESIS)
-					sprintf(buf, "%d%cobj.tga", curItem, _distanceId);
+					Common::sprintf_s(buf, "%d%cobj.tga", curItem, _distanceId);
 				else
-					sprintf(buf, "g0z%cu%2.2x1.tga", _distanceId, curItem);
+					Common::sprintf_s(buf, "g0z%cu%2.2x1.tga", _distanceId, curItem);
 
 				Graphics::Surface *srf = _engine->getRenderManager()->loadImage(buf);
 
diff --git a/engines/zvision/scripting/menu.cpp b/engines/zvision/scripting/menu.cpp
index 081490ea114..7ed920fc9af 100644
--- a/engines/zvision/scripting/menu.cpp
+++ b/engines/zvision/scripting/menu.cpp
@@ -58,15 +58,15 @@ MenuZGI::MenuZGI(ZVision *engine) :
 
 	char buf[24];
 	for (int i = 1; i < 4; i++) {
-		sprintf(buf, "gmzau%2.2x1.tga", i);
+		Common::sprintf_s(buf, "gmzau%2.2x1.tga", i);
 		_engine->getRenderManager()->readImageToSurface(buf, menuBack[i - 1][0], false);
-		sprintf(buf, "gmzau%2.2x1.tga", i + 0x10);
+		Common::sprintf_s(buf, "gmzau%2.2x1.tga", i + 0x10);
 		_engine->getRenderManager()->readImageToSurface(buf, menuBack[i - 1][1], false);
 	}
 	for (int i = 0; i < 4; i++) {
-		sprintf(buf, "gmzmu%2.2x1.tga", i);
+		Common::sprintf_s(buf, "gmzmu%2.2x1.tga", i);
 		_engine->getRenderManager()->readImageToSurface(buf, menuBar[i][0], false);
-		sprintf(buf, "gmznu%2.2x1.tga", i);
+		Common::sprintf_s(buf, "gmznu%2.2x1.tga", i);
 		_engine->getRenderManager()->readImageToSurface(buf, menuBar[i][1], false);
 	}
 
@@ -392,9 +392,9 @@ void MenuZGI::process(uint32 deltatime) {
 				if (curItemId != 0) {
 					if (itemId[i] != curItemId) {
 						char buf[16];
-						sprintf(buf, "gmzwu%2.2x1.tga", curItemId);
+						Common::sprintf_s(buf, "gmzwu%2.2x1.tga", curItemId);
 						items[i][0] = _engine->getRenderManager()->loadImage(buf, false);
-						sprintf(buf, "gmzxu%2.2x1.tga", curItemId);
+						Common::sprintf_s(buf, "gmzxu%2.2x1.tga", curItemId);
 						items[i][1] = _engine->getRenderManager()->loadImage(buf, false);
 						itemId[i] = curItemId;
 					}
@@ -459,9 +459,9 @@ void MenuZGI::process(uint32 deltatime) {
 				if (curItemId != 0) {
 					if (itemId[i] != curItemId) {
 						char buf[16];
-						sprintf(buf, "gmzwu%2.2x1.tga", curItemId);
+						Common::sprintf_s(buf, "gmzwu%2.2x1.tga", curItemId);
 						magic[i][0] = _engine->getRenderManager()->loadImage(buf, false);
-						sprintf(buf, "gmzxu%2.2x1.tga", curItemId);
+						Common::sprintf_s(buf, "gmzxu%2.2x1.tga", curItemId);
 						magic[i][1] = _engine->getRenderManager()->loadImage(buf, false);
 						magicId[i] = curItemId;
 					}
@@ -563,7 +563,7 @@ MenuNemesis::MenuNemesis(ZVision *engine) :
 	char buf[24];
 	for (int i = 0; i < 4; i++)
 		for (int j = 0; j < 6; j++) {
-			sprintf(buf, "butfrm%d%d.tga", i + 1, j);
+			Common::sprintf_s(buf, "butfrm%d%d.tga", i + 1, j);
 			_engine->getRenderManager()->readImageToSurface(buf, but[i][j], false);
 		}
 


Commit: 29f5d5197221d3c4eb86ae7d036126ddc88c27e2
    https://github.com/scummvm/scummvm/commit/29f5d5197221d3c4eb86ae7d036126ddc88c27e2
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
DC: Don't use unsafe sprintf and vsprintf

Changed paths:
    backends/platform/dc/selector.cpp
    backends/platform/dc/vmsave.cpp


diff --git a/backends/platform/dc/selector.cpp b/backends/platform/dc/selector.cpp
index f8c3f2e3643..cb31f6bc53c 100644
--- a/backends/platform/dc/selector.cpp
+++ b/backends/platform/dc/selector.cpp
@@ -71,13 +71,13 @@ static bool isIcon(const Common::FSNode &entry)
 static bool loadIcon(Game &game, Dir *dirs, int num_dirs)
 {
   char icofn[520];
-  sprintf(icofn, "%s%s.ICO", game.dir, game.filename_base);
+  Common::sprintf_s(icofn, "%s%s.ICO", game.dir, game.filename_base);
   if (game.icon.load(icofn))
 	return true;
   for (int i=0; i<num_dirs; i++)
 	if (!strcmp(dirs[i].name, game.dir) &&
 	   dirs[i].deficon[0]) {
-	  sprintf(icofn, "%s%s", game.dir, dirs[i].deficon);
+	  Common::sprintf_s(icofn, "%s%s", game.dir, dirs[i].deficon);
 	  if (game.icon.load(icofn))
 	return true;
 	  break;
diff --git a/backends/platform/dc/vmsave.cpp b/backends/platform/dc/vmsave.cpp
index 458677b5265..361cc70b4aa 100644
--- a/backends/platform/dc/vmsave.cpp
+++ b/backends/platform/dc/vmsave.cpp
@@ -51,7 +51,7 @@ static void displaySaveResult(vmsaveResult res)
 
   switch(res) {
   case VMSAVE_OK:
-	sprintf(buf, "Game saved on unit %c%d", 'A'+(lastvm/6), lastvm%6);
+	Common::sprintf_s(buf, "Game saved on unit %c%d", 'A'+(lastvm/6), lastvm%6);
 	break;
   case VMSAVE_NOVM:
 	Common::strcpy_s(buf, "No memory card present!");


Commit: a60e8ff2cb0fd3eb6e3d953521403e95ea8e296b
    https://github.com/scummvm/scummvm/commit/a60e8ff2cb0fd3eb6e3d953521403e95ea8e296b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
MORPHOS: Don't use unsafe sprintf and vsprintf

Changed paths:
    backends/fs/morphos/morphos-fs.cpp


diff --git a/backends/fs/morphos/morphos-fs.cpp b/backends/fs/morphos/morphos-fs.cpp
index 5ab22c7ad11..4193bc34205 100644
--- a/backends/fs/morphos/morphos-fs.cpp
+++ b/backends/fs/morphos/morphos-fs.cpp
@@ -324,7 +324,7 @@ AbstractFSList MorphOSFilesystemNode::listVolumes() const {
 			volumeLock = Lock(buffer, SHARED_LOCK);
 			if (volumeLock) {
 
-				sprintf(buffer, "%s (%s)", volName, devName);
+				Common::sprintf_s(buffer, "%s (%s)", volName, devName);
 
 				entry = new MorphOSFilesystemNode(volumeLock, buffer);
 				if (entry) {


Commit: f61400075f10742e3a408ffb3209351f209850bb
    https://github.com/scummvm/scummvm/commit/f61400075f10742e3a408ffb3209351f209850bb
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
PSP: Don't use unsafe sprintf and vsprintf

Changed paths:
    backends/platform/psp/image_viewer.cpp


diff --git a/backends/platform/psp/image_viewer.cpp b/backends/platform/psp/image_viewer.cpp
index 03222b253a3..9a2e8ddcb24 100644
--- a/backends/platform/psp/image_viewer.cpp
+++ b/backends/platform/psp/image_viewer.cpp
@@ -47,7 +47,7 @@ bool ImageViewer::load(int imageNum) {
 
 	// build string
 	char number[8];
-	sprintf(number, "%d", imageNum);
+	Common::sprintf_s(number, "%d", imageNum);
 	Common::String imageNameStr(imageName);
 	Common::String specificImageName = imageNameStr + Common::String(number) + Common::String(".png");
 
@@ -74,19 +74,19 @@ bool ImageViewer::load(int imageNum) {
 
 	char error[100];
 	if (status == PngLoader::BAD_FILE) {
-		sprintf(error, "Cannot display %s. Not a proper PNG file", specificImageName.c_str());
+		Common::sprintf_s(error, "Cannot display %s. Not a proper PNG file", specificImageName.c_str());
 		GUI::TimedMessageDialog dialog(Common::U32String(error), 4000);
 		dialog.runModal();
 		return false;
 	} else if (status == PngLoader::OUT_OF_MEMORY) {
-		sprintf(error, "Out of memory loading %s. Try making the image smaller", specificImageName.c_str());
+		Common::sprintf_s(error, "Out of memory loading %s. Try making the image smaller", specificImageName.c_str());
 		GUI::TimedMessageDialog dialog(Common::U32String(error), 4000);
 		dialog.runModal();
 		return false;
 	}
 	// try to load the image file
 	if (!image.load()) {
-		sprintf(error, "Cannot display %s. Not a proper PNG file", specificImageName.c_str());
+		Common::sprintf_s(error, "Cannot display %s. Not a proper PNG file", specificImageName.c_str());
 		GUI::TimedMessageDialog dialog(Common::U32String(error), 4000);
 		dialog.runModal();
 		return false;


Commit: 43997e2911a42b976834fced9146536d4cb85ee1
    https://github.com/scummvm/scummvm/commit/43997e2911a42b976834fced9146536d4cb85ee1
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
WIN32: Don't use unsafe sprintf and vsprintf

Changed paths:
    backends/fs/windows/windows-fs.cpp


diff --git a/backends/fs/windows/windows-fs.cpp b/backends/fs/windows/windows-fs.cpp
index 6f69388a132..aed7da04ad1 100644
--- a/backends/fs/windows/windows-fs.cpp
+++ b/backends/fs/windows/windows-fs.cpp
@@ -179,7 +179,7 @@ bool WindowsFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b
 		HANDLE handle;
 		char searchPath[MAX_PATH + 10];
 
-		sprintf(searchPath, "%s*", _path.c_str());
+		Common::sprintf_s(searchPath, "%s*", _path.c_str());
 
 		handle = FindFirstFile(charToTchar(searchPath), &desc);
 


Commit: 6524f7beb5d9b05685a8759e2839bab2ef223b57
    https://github.com/scummvm/scummvm/commit/6524f7beb5d9b05685a8759e2839bab2ef223b57
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-10-23T22:46:19+02:00

Commit Message:
COMMON: Forbid use of unsafe sprintf and vsprintf

Changed paths:
    backends/platform/sdl/sdl-sys.h
    common/forbidden.h
    common/lua/liolib.cpp
    common/lua/llex.cpp
    common/lua/lobject.cpp
    common/lua/lstrlib.cpp
    common/lua/lvm.cpp
    test/common/md5.h


diff --git a/backends/platform/sdl/sdl-sys.h b/backends/platform/sdl/sdl-sys.h
index 12cc0b8c8ac..4fd48117980 100644
--- a/backends/platform/sdl/sdl-sys.h
+++ b/backends/platform/sdl/sdl-sys.h
@@ -74,6 +74,16 @@
 #define strcat FAKE_strcat
 #endif
 
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_vsprintf)
+#undef vsprintf
+#define vsprintf FAKE_vsprintf
+#endif
+
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_sprintf)
+#undef sprintf
+#define sprintf FAKE_sprintf
+#endif
+
 // Fix compilation with MacPorts SDL 2
 // It needs various (usually forbidden) symbols from time.h
 #ifndef FORBIDDEN_SYMBOL_EXCEPTION_time_h
@@ -275,6 +285,16 @@
 #define strcat(a,b)    FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
 #endif
 
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_vsprintf)
+#undef vsprintf
+#define vsprintf(a,b,c)    FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
+#endif
+
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_sprintf)
+#undef sprintf
+#define sprintf(a,b,...)    FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
+#endif
+
 // re-forbid all those time.h symbols again (if they were forbidden)
 #ifndef FORBIDDEN_SYMBOL_EXCEPTION_time_h
 
diff --git a/common/forbidden.h b/common/forbidden.h
index b9663681b67..203733dfeca 100644
--- a/common/forbidden.h
+++ b/common/forbidden.h
@@ -539,6 +539,18 @@
 #define strcpy(a,b)	FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
 #endif
 
+// Use Common::vsprintf_s in common/str.h or vsnprintf
+#ifndef FORBIDDEN_SYMBOL_EXCEPTION_vsprintf
+#undef vsprintf
+#define vsprintf(a,b,c)	FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
+#endif
+
+// Use Common::sprintf_s in common/str.h or snprintf
+#ifndef FORBIDDEN_SYMBOL_EXCEPTION_sprintf
+#undef sprintf
+#define sprintf(a,b,...)	FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%*
+#endif
+
 // Use Common:scumm_stricmp in common/str.h
 #ifndef FORBIDDEN_SYMBOL_EXCEPTION_stricmp
 #undef stricmp
diff --git a/common/lua/liolib.cpp b/common/lua/liolib.cpp
index 769a1ea8bf9..f0bf5cbff9f 100644
--- a/common/lua/liolib.cpp
+++ b/common/lua/liolib.cpp
@@ -4,6 +4,7 @@
 ** See Copyright Notice in lua.h
 */
 
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/common/lua/llex.cpp b/common/lua/llex.cpp
index ac9006ec3ca..306442eb562 100644
--- a/common/lua/llex.cpp
+++ b/common/lua/llex.cpp
@@ -4,6 +4,7 @@
 ** See Copyright Notice in lua.h
 */
 
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 #include "common/util.h"
 
 #define llex_c
diff --git a/common/lua/lobject.cpp b/common/lua/lobject.cpp
index d34a15af24d..c792201876b 100644
--- a/common/lua/lobject.cpp
+++ b/common/lua/lobject.cpp
@@ -6,6 +6,7 @@
 
 #define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
 #define FORBIDDEN_SYMBOL_EXCEPTION_strcat
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 
 #include "common/util.h"
 
diff --git a/common/lua/lstrlib.cpp b/common/lua/lstrlib.cpp
index 341a2a4850c..6d323abddf5 100644
--- a/common/lua/lstrlib.cpp
+++ b/common/lua/lstrlib.cpp
@@ -5,6 +5,7 @@
 */
 
 #define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 
 #include "common/util.h"
 
diff --git a/common/lua/lvm.cpp b/common/lua/lvm.cpp
index 5c426283259..8b7b799354b 100644
--- a/common/lua/lvm.cpp
+++ b/common/lua/lvm.cpp
@@ -4,6 +4,7 @@
 ** See Copyright Notice in lua.h
 */
 
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/test/common/md5.h b/test/common/md5.h
index 1970b796bb1..e82a6132f96 100644
--- a/test/common/md5.h
+++ b/test/common/md5.h
@@ -39,7 +39,7 @@ class MD5TestSuite : public CxxTest::TestSuite {
 			Common::computeStreamMD5(stream, md5sum);
 
 			for (j = 0; j < 16; j++) {
-				sprintf(output + j * 2, "%02x", md5sum[j]);
+				snprintf(output + j * 2, 3, "%02x", md5sum[j]);
 			}
 
 			Common::String tmp(output);




More information about the Scummvm-git-logs mailing list