diff --git a/src/fileio.cpp b/src/fileio.cpp
index f88d8deeaf..c9d30051e2 100644
--- a/src/fileio.cpp
+++ b/src/fileio.cpp
@@ -849,29 +849,38 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha
 
 				char *pos = link;
 				while (*pos != '\0') {
-					char *next = strchr(link, PATHSEPCHAR);
-					if (next == NULL) next = pos + strlen(pos);
+					char *next = strchr(pos, PATHSEPCHAR);
+					if (next == NULL) {
+						next = pos + strlen(pos);
+					} else {
+						/* Terminate the substring up to the path separator character. */
+						*next++= '\0';
+					}
 
-					/* Skip '.' (current dir) */
-					if (next != pos + 1 || pos[0] != '.') {
-						if (next == pos + 2 && pos[0] == '.' && pos[1] == '.') {
-							/* level up */
-							if (dest[0] == '\0') {
-								DEBUG(misc, 1, "Ignoring link pointing outside of data directory: %s -> %s", name, link);
-								break;
-							}
-
-							/* Truncate 'dest' after last PATHSEPCHAR.
-							 * This assumes that the truncated part is a real directory and not a link. */
-							destpos = strrchr(dest, PATHSEPCHAR);
-							if (destpos == NULL) destpos = dest;
-						} else {
-							/* Append at end of 'dest' */
-							if (destpos != dest) *(destpos++) = PATHSEPCHAR;
-							strncpy(destpos, pos, next - pos); // Safe as we do '\0'-termination ourselves
-							destpos += next - pos;
+					if (strcmp(pos, ".") == 0) {
+						/* Skip '.' (current dir) */
+					} else if (strcmp(pos, "..") == 0) {
+						/* level up */
+						if (dest[0] == '\0') {
+							DEBUG(misc, 1, "Ignoring link pointing outside of data directory: %s -> %s", name, link);
+							break;
 						}
+
+						/* Truncate 'dest' after last PATHSEPCHAR.
+						 * This assumes that the truncated part is a real directory and not a link. */
+						destpos = strrchr(dest, PATHSEPCHAR);
+						if (destpos == NULL) destpos = dest;
 						*destpos = '\0';
+					} else {
+						/* Append at end of 'dest' */
+						if (destpos != dest) destpos = strecpy(destpos, PATHSEP, lastof(dest));
+						destpos = strecpy(destpos, pos, lastof(dest));
+					}
+
+					if (destpos >= lastof(dest)) {
+						DEBUG(misc, 0, "The length of a link in tar-file '%s' is too large (malformed?)", filename);
+						fclose(f);
+						return false;
 					}
 
 					pos = next;
diff --git a/src/game/game_text.cpp b/src/game/game_text.cpp
index cd9721b8ab..6fe008753a 100644
--- a/src/game/game_text.cpp
+++ b/src/game/game_text.cpp
@@ -377,7 +377,7 @@ void ReconsiderGameScriptLanguage()
 	if (_current_data == NULL) return;
 
 	char temp[MAX_PATH];
-	strecpy(temp, _current_language->file, temp + sizeof(temp));
+	strecpy(temp, _current_language->file, lastof(temp));
 
 	/* Remove the extension */
 	char *l = strrchr(temp, '.');
diff --git a/src/strgen/strgen.cpp b/src/strgen/strgen.cpp
index 5d04538413..c407f23454 100644
--- a/src/strgen/strgen.cpp
+++ b/src/strgen/strgen.cpp
@@ -561,7 +561,7 @@ int CDECL main(int argc, char *argv[])
 				/* rename the .txt (input-extension) to .lng */
 				r = strrchr(pathbuf, '.');
 				if (r == NULL || strcmp(r, ".txt") != 0) r = strchr(pathbuf, '\0');
-				ttd_strlcpy(r, ".lng", (size_t)(r - pathbuf));
+				strecpy(r, ".lng", lastof(pathbuf));
 
 				LanguageFileWriter writer(pathbuf);
 				writer.WriteLang(data);
diff --git a/src/video/dedicated_v.cpp b/src/video/dedicated_v.cpp
index 8e5b9ea91c..ed02fc76ef 100644
--- a/src/video/dedicated_v.cpp
+++ b/src/video/dedicated_v.cpp
@@ -99,6 +99,9 @@ static void WINAPI CheckForConsoleInput()
 	HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
 	for (;;) {
 		ReadFile(hStdin, _win_console_thread_buffer, lengthof(_win_console_thread_buffer), &nb, NULL);
+		if (nb >= lengthof(_win_console_thread_buffer)) nb = lengthof(_win_console_thread_buffer) - 1;
+		_win_console_thread_buffer[nb] = '\0';
+
 		/* Signal input waiting that input is read and wait for it being handled
 		 * SignalObjectAndWait() should be used here, but it's unsupported in Win98< */
 		SetEvent(_hInputReady);
@@ -243,9 +246,7 @@ static void DedicatedHandleKeyInput()
 	SetEvent(_hWaitForInputHandling);
 #endif
 
-	/* strtok() does not 'forget' \r\n if the string starts with it,
-	 * so we have to manually remove that! */
-	strtok(input_line, "\r\n");
+	/* Remove trailing \r or \n */
 	for (char *c = input_line; *c != '\0'; c++) {
 		if (*c == '\n' || *c == '\r' || c == lastof(input_line)) {
 			*c = '\0';