From 4d74dc5052e04dafcf075fd08eff5c48ef6557fa Mon Sep 17 00:00:00 2001
From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com>
Date: Sun, 28 Jan 2024 19:07:04 +0100
Subject: [PATCH] RTech: fix bug when trying to print fourcc as string

The printf specifier does not allow limiting buffer reads. Made the FourCCToString more performant by using a fixed size stack array and creating the fourcc into that which we now use to properly print out the asset magic.
---
 r5dev/common/callback.cpp    |  5 ++++-
 r5dev/public/tier0/utility.h |  3 ++-
 r5dev/rtech/pak/pakparse.cpp |  7 +++++--
 r5dev/tier0/utility.cpp      | 13 ++++++-------
 4 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/r5dev/common/callback.cpp b/r5dev/common/callback.cpp
index 4e6b6c8e..fc9c920e 100644
--- a/r5dev/common/callback.cpp
+++ b/r5dev/common/callback.cpp
@@ -340,7 +340,10 @@ void Pak_ListTypes_f(const CCommand& args)
 		if (!type->description)
 			continue;
 
-		Msg(eDLL_T::RTECH, "| %-4s | %-25s | %7i | %11i | %11i |\n", FourCCToString(type->extension).c_str(), type->description, type->version, type->headerSize, type->nativeClassSize);
+		FourCCString_t assetExtension;
+		FourCCToString(assetExtension, type->extension);
+
+		Msg(eDLL_T::RTECH, "| %-4s | %-25s | %7i | %11i | %11i |\n", assetExtension, type->description, type->version, type->headerSize, type->nativeClassSize);
 		nRegistered++;
 	}
 	Msg(eDLL_T::RTECH, "|------|---------------------------|---------|-------------|-------------|\n");
diff --git a/r5dev/public/tier0/utility.h b/r5dev/public/tier0/utility.h
index 44a2f2c1..cf8e2e1a 100644
--- a/r5dev/public/tier0/utility.h
+++ b/r5dev/public/tier0/utility.h
@@ -64,7 +64,8 @@ string& StringLTrim(string& svInput, const char* pszToTrim, bool bTrimBefore = f
 string& StringRTrim(string& svInput, const char* pszToTrim, bool bTrimAfter = false);
 string& StringTrim(string& svInput, const char* pszToTrim, bool bTrimAll = false);
 
-string FourCCToString(int n);
+typedef char FourCCString_t[5];
+void FourCCToString(FourCCString_t& buf, const int n);
 
 /////////////////////////////////////////////////////////////////////////////
 // Bytes
diff --git a/r5dev/rtech/pak/pakparse.cpp b/r5dev/rtech/pak/pakparse.cpp
index 67c72e69..9a8c4920 100644
--- a/r5dev/rtech/pak/pakparse.cpp
+++ b/r5dev/rtech/pak/pakparse.cpp
@@ -848,10 +848,13 @@ void Pak_StubInvalidAssetBinds(PakFile_t* const pak, PakSegmentDescriptor_t* con
         // which isn't much help to the average user that can't rebuild other people's paks
         if (asset->version != assetBinding->version)
         {
+            FourCCString_t assetMagic;
+            FourCCToString(assetMagic, asset->magic);
+
             DevWarning(eDLL_T::RTECH,
-                "Unexpected asset version for \"%s\" (%.4s) asset with guid 0x%llX (asset %i in pakfile '%s'). Expected %i, found %i.\n",
+                "Unexpected asset version for \"%s\" (%.4s) asset with guid 0x%llX (asset %u in pakfile '%s'). Expected %u, found %u.\n",
                 assetBinding->description,
-                reinterpret_cast<char*>(&asset->magic),
+                assetMagic,
                 asset->guid,
                 i, pak->GetName(),
                 assetBinding->version, asset->version
diff --git a/r5dev/tier0/utility.cpp b/r5dev/tier0/utility.cpp
index 4e1745ea..dab4e454 100644
--- a/r5dev/tier0/utility.cpp
+++ b/r5dev/tier0/utility.cpp
@@ -918,14 +918,13 @@ pair<vector<uint8_t>, string> StringToMaskedBytes(const char* szInput, bool bNul
 
 ///////////////////////////////////////////////////////////////////////////////
 // For converting a 32-bit integer into a 4-char ascii string
-string FourCCToString(int n)
+void FourCCToString(FourCCString_t& buf, const int n)
 {
-    stringstream ss;
-    ss << (char)((n & 0x000000ff) >> 0);
-    ss << (char)((n & 0x0000ff00) >> 8);
-    ss << (char)((n & 0x00ff0000) >> 16);
-    ss << (char)((n & 0xff000000) >> 24);
-    return ss.str();
+    buf[0] = (char)((n & 0x000000ff) >> 0);
+    buf[1] = (char)((n & 0x0000ff00) >> 8);
+    buf[2] = (char)((n & 0x00ff0000) >> 16);
+    buf[3] = (char)((n & 0xff000000) >> 24);
+    buf[4] = '\0';
 };
 
 ///////////////////////////////////////////////////////////////////////////////