From fbe81baca33c8f87db791f9bc592d0f7b153458f Mon Sep 17 00:00:00 2001
From: jacob1 <jfu614@gmail.com>
Date: Sat, 21 Apr 2018 19:28:36 -0400
Subject: [PATCH] make Platform::ExecutableName return std::string (fixes minor
 memory leak)

update code is untested
---
 src/Platform.cpp               | 18 ++++---
 src/Platform.h                 |  2 +-
 src/Update.cpp                 | 98 ++++++++++++++--------------------
 src/lua/LuaScriptInterface.cpp |  6 +--
 4 files changed, 55 insertions(+), 69 deletions(-)

diff --git a/src/Platform.cpp b/src/Platform.cpp
index 08c0b19df..8c18772c5 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -20,8 +20,9 @@
 namespace Platform
 {
 
-char *ExecutableName(void)
+std::string ExecutableName()
 {
+	std::string ret;
 #if defined(WIN)
 	char *name = (char *)malloc(64);
 	DWORD max = 64, res;
@@ -41,7 +42,7 @@ char *ExecutableName(void)
 	{
 		free(fn);
 		free(name);
-		return NULL;
+		return "";
 	}
 	res = 1;
 #else
@@ -63,22 +64,23 @@ char *ExecutableName(void)
 	if (res <= 0)
 	{
 		free(name);
-		return NULL;
+		return "";
 	}
-	return name;
+	ret = name;
+	free(name);
+	return ret;
 }
 
 void DoRestart()
 {
-	char *exename = ExecutableName();
-	if (exename)
+	std::string exename = ExecutableName();
+	if (exename.length())
 	{
 #ifdef WIN
 		ShellExecute(NULL, "open", exename, NULL, NULL, SW_SHOWNORMAL);
 #elif defined(LIN) || defined(MACOSX)
-		execl(exename, "powder", NULL);
+		execl(exename.c_str(), "powder", NULL);
 #endif
-		free(exename);
 	}
 	exit(-1);
 }
diff --git a/src/Platform.h b/src/Platform.h
index 83729197b..ecbdbf115 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -5,7 +5,7 @@
 
 namespace Platform
 {
-	char * ExecutableName();
+	std::string ExecutableName();
 	void DoRestart();
 
 	void OpenURI(std::string uri);
diff --git a/src/Update.cpp b/src/Update.cpp
index 39f33a809..4e20f515d 100644
--- a/src/Update.cpp
+++ b/src/Update.cpp
@@ -25,120 +25,106 @@
 
 int update_start(char *data, unsigned int len)
 {
-	char *self = Platform::ExecutableName(), *temp;
-#ifdef WIN
-	char *p;
-#endif
+	std::string exeName = Platform::ExecutableName(), updName;
 	FILE *f;
-	int res = 1;
 
-	if (!self)
+	if (!exeName.length())
 		return 1;
 
 #ifdef WIN
-	temp = (char*)malloc(strlen(self)+12);
-	strcpy(temp, self);
-	p = temp + strlen(temp) - 4;
-	if (_stricmp(p, ".exe"))
-		p += 4;
-	strcpy(p, "_upd.exe");
+	updName = exeName;
+	std::string extension = exeName.substr(exeName.length() - 4);
+	if (extension == ".exe")
+		updName = exeName.substr(0, exeName.length() - 4);
+	updName = updName + "_upd.exe";
 
-	if (!MoveFile(self, temp))
+	if (!MoveFile(exeName.c_str(), updName.c_str()))
 		goto fail;
 
-	f = fopen(self, "wb");
+	f = fopen(exeName.c_str(), "wb");
 	if (!f)
 		goto fail;
 	if (fwrite(data, 1, len, f) != len)
 	{
 		fclose(f);
-		DeleteFile(self);
+		DeleteFile(exeName.c_str());
 		goto fail;
 	}
 	fclose(f);
 
-	if ((uintptr_t)ShellExecute(NULL, "open", self, NULL, NULL, SW_SHOWNORMAL) <= 32)
+	if ((uintptr_t)ShellExecute(NULL, "open", exeName.c_str(), NULL, NULL, SW_SHOWNORMAL) <= 32)
 	{
-		DeleteFile(self);
+		DeleteFile(exeName.c_str());
 		goto fail;
 	}
 
 	return 0;
 #else
-	temp = (char*)malloc(strlen(self)+8);
-	strcpy(temp, self);
-	strcat(temp, "-update");
+	updName = exeName + "-update";
 
-	f = fopen(temp, "w");
+	f = fopen(updName.c_str(), "w");
 	if (!f)
-		goto fail;
+		return 1;
 	if (fwrite(data, 1, len, f) != len)
 	{
 		fclose(f);
-		unlink(temp);
-		goto fail;
+		unlink(updName.c_str());
+		return 1;
 	}
 	fclose(f);
 
-	if (chmod(temp, 0755))
+	if (chmod(updName.c_str(), 0755))
 	{
-		unlink(temp);
-		goto fail;
+		unlink(updName.c_str());
+		return 1;
 	}
 
-	if (rename(temp, self))
+	if (rename(updName.c_str(), exeName.c_str()))
 	{
-		unlink(temp);
-		goto fail;
+		unlink(updName.c_str());
+		return 1;
 	}
 
-	execl(self, "powder-update", NULL);
+	execl(exeName.c_str(), "powder-update", NULL);
+	return 0;
 #endif
-
-fail:
-	free(temp);
-	free(self);
-	return res;
 }
 
 int update_finish(void)
 {
 #ifdef WIN
-	char *temp, *self = Platform::ExecutableName(), *p;
+	std::string exeName = Platform::ExecutableName(), updName;
 	int timeout = 5, err;
 
 #ifdef DEBUG
-	printf("Update: Current EXE name: %s\n", self);
+	printf("Update: Current EXE name: %s\n", exeName.c_str());
 #endif
 
-	temp = (char*)malloc(strlen(self)+12);
-	strcpy(temp, self);
-	p = temp + strlen(temp) - 4;
-	if (_stricmp(p, ".exe"))
-		p += 4;
-	strcpy(p, "_upd.exe");
+	updName = exeName;
+	std::string extension = exeName.substr(exeName.length() - 4);
+	if (extension == ".exe")
+		updName = exeName.substr(0, exeName.length() - 4);
+	updName = updName + "_upd.exe";
 
 #ifdef DEBUG
-	printf("Update: Temp EXE name: %s\n", temp);
+	printf("Update: Temp EXE name: %s\n", updName.c_str());
 #endif
 
-	while (!DeleteFile(temp))
+	while (!DeleteFile(updName.c_str()))
 	{
 		err = GetLastError();
 		if (err == ERROR_FILE_NOT_FOUND)
 		{
 #ifdef DEBUG
-			printf("Update: Temp file deleted\n");
+			printf("Update: Temp file not deleted\n");
 #endif
-			free(temp);
 			// Old versions of powder toy name their update files with _update.exe, delete that upgrade file here
-			temp = (char*)malloc(strlen(self)+12);
-			strcpy(temp, self);
-			p = temp + strlen(temp) - 4;
-			if (_stricmp(p, ".exe"))
-				p += 4;
-			strcpy(p, "_update.exe");
-			DeleteFile(temp);
+			updName = exeName;
+			std::string extension = exeName.substr(exeName.length() - 4);
+			if (extension == ".exe")
+				updName = exeName.substr(0, exeName.length() - 4);
+			updName = updName + "_update.exe";
+			DeleteFile(updName.c_str());
 			return 0;
 		}
 		Sleep(500);
@@ -148,11 +134,9 @@ int update_finish(void)
 #ifdef DEBUG
 			printf("Update: Delete timeout\n");
 #endif
-			free(temp);
 			return 1;
 		}
 	}
-	free(temp);
 #endif
 	return 0;
 }
diff --git a/src/lua/LuaScriptInterface.cpp b/src/lua/LuaScriptInterface.cpp
index d37e216c5..a89e775ae 100644
--- a/src/lua/LuaScriptInterface.cpp
+++ b/src/lua/LuaScriptInterface.cpp
@@ -3379,9 +3379,9 @@ int LuaScriptInterface::platform_releaseType(lua_State * l)
 
 int LuaScriptInterface::platform_exeName(lua_State * l)
 {
-	char *name = Platform::ExecutableName();
-	if (name)
-		lua_pushstring(l, name);
+	std::string name = Platform::ExecutableName();
+	if (name.length())
+		lua_pushstring(l, name.c_str());
 	else
 		luaL_error(l, "Error, could not get executable name");
 	return 1;