diff --git a/Core/GameEngine/Source/Common/System/Debug.cpp b/Core/GameEngine/Source/Common/System/Debug.cpp index 7a96696ffb..e114aea496 100644 --- a/Core/GameEngine/Source/Common/System/Debug.cpp +++ b/Core/GameEngine/Source/Common/System/Debug.cpp @@ -381,6 +381,7 @@ void DebugInit(int flags) *(pEnd + 1) = 0; } + static_assert(ARRAY_SIZE(theLogFileNamePrev) >= ARRAY_SIZE(dirbuf), "Incorrect array size"); strcpy(theLogFileNamePrev, dirbuf); strlcat(theLogFileNamePrev, gAppPrefix, ARRAY_SIZE(theLogFileNamePrev)); strlcat(theLogFileNamePrev, DEBUG_FILE_NAME_PREV, ARRAY_SIZE(theLogFileNamePrev)); @@ -391,6 +392,7 @@ void DebugInit(int flags) } strlcat(theLogFileNamePrev, ".txt", ARRAY_SIZE(theLogFileNamePrev)); + static_assert(ARRAY_SIZE(theLogFileName) >= ARRAY_SIZE(dirbuf), "Incorrect array size"); strcpy(theLogFileName, dirbuf); strlcat(theLogFileName, gAppPrefix, ARRAY_SIZE(theLogFileNamePrev)); strlcat(theLogFileName, DEBUG_FILE_NAME, ARRAY_SIZE(theLogFileNamePrev)); @@ -730,9 +732,9 @@ void ReleaseCrash(const char *reason) return; // We are shutting down, and TheGlobalData has been freed. jba. [4/15/2003] } - strcpy(prevbuf, TheGlobalData->getPath_UserData().str()); + strlcpy(prevbuf, TheGlobalData->getPath_UserData().str(), ARRAY_SIZE(prevbuf)); strlcat(prevbuf, RELEASECRASH_FILE_NAME_PREV, ARRAY_SIZE(prevbuf)); - strcpy(curbuf, TheGlobalData->getPath_UserData().str()); + strlcpy(curbuf, TheGlobalData->getPath_UserData().str(), ARRAY_SIZE(curbuf)); strlcat(curbuf, RELEASECRASH_FILE_NAME, ARRAY_SIZE(curbuf)); remove(prevbuf); @@ -819,9 +821,9 @@ void ReleaseCrashLocalized(const AsciiString& p, const AsciiString& m) char prevbuf[ _MAX_PATH ]; char curbuf[ _MAX_PATH ]; - strcpy(prevbuf, TheGlobalData->getPath_UserData().str()); + strlcpy(prevbuf, TheGlobalData->getPath_UserData().str(), ARRAY_SIZE(prevbuf)); strlcat(prevbuf, RELEASECRASH_FILE_NAME_PREV, ARRAY_SIZE(prevbuf)); - strcpy(curbuf, TheGlobalData->getPath_UserData().str()); + strlcpy(curbuf, TheGlobalData->getPath_UserData().str(), ARRAY_SIZE(curbuf)); strlcat(curbuf, RELEASECRASH_FILE_NAME, ARRAY_SIZE(curbuf)); remove(prevbuf); diff --git a/Core/GameEngine/Source/Common/System/GameMemory.cpp b/Core/GameEngine/Source/Common/System/GameMemory.cpp index 0d178ec774..78a855c00d 100644 --- a/Core/GameEngine/Source/Common/System/GameMemory.cpp +++ b/Core/GameEngine/Source/Common/System/GameMemory.cpp @@ -2975,7 +2975,7 @@ void MemoryPoolFactory::memoryPoolUsageReport( const char* filename, FILE *appen if( !appendToFileInstead ) { char tmp[256]; - strcpy(tmp,filename); + strlcpy(tmp, filename, ARRAY_SIZE(tmp)); strlcat(tmp, ".csv", ARRAY_SIZE(tmp)); perfStatsFile = fopen(tmp, "w"); } diff --git a/Core/GameEngineDevice/Source/StdDevice/Common/StdLocalFileSystem.cpp b/Core/GameEngineDevice/Source/StdDevice/Common/StdLocalFileSystem.cpp index 9cacda79bf..a9a3362c6c 100644 --- a/Core/GameEngineDevice/Source/StdDevice/Common/StdLocalFileSystem.cpp +++ b/Core/GameEngineDevice/Source/StdDevice/Common/StdLocalFileSystem.cpp @@ -211,7 +211,6 @@ Bool StdLocalFileSystem::doesFileExist(const Char *filename) const void StdLocalFileSystem::getFileListInDirectory(const AsciiString& currentDirectory, const AsciiString& originalDirectory, const AsciiString& searchName, FilenameList & filenameList, Bool searchSubdirectories) const { - char search[_MAX_PATH]; AsciiString asciisearch; asciisearch = originalDirectory; asciisearch.concat(currentDirectory); @@ -227,17 +226,15 @@ void StdLocalFileSystem::getFileListInDirectory(const AsciiString& currentDirect std::replace(fixedDirectory.begin(), fixedDirectory.end(), '\\', '/'); #endif - strcpy(search, fixedDirectory.c_str()); - Bool done = FALSE; std::error_code ec; - auto iter = std::filesystem::directory_iterator(search, ec); + auto iter = std::filesystem::directory_iterator(fixedDirectory.c_str(), ec); // The default iterator constructor creates an end iterator done = iter == std::filesystem::directory_iterator(); if (ec) { - DEBUG_LOG(("StdLocalFileSystem::getFileListInDirectory - Error opening directory %s", search)); + DEBUG_LOG(("StdLocalFileSystem::getFileListInDirectory - Error opening directory %s", fixedDirectory.c_str())); return; } diff --git a/Core/GameEngineDevice/Source/Win32Device/Common/Win32LocalFileSystem.cpp b/Core/GameEngineDevice/Source/Win32Device/Common/Win32LocalFileSystem.cpp index 49e8b8de1a..7b63431cbe 100644 --- a/Core/GameEngineDevice/Source/Win32Device/Common/Win32LocalFileSystem.cpp +++ b/Core/GameEngineDevice/Source/Win32Device/Common/Win32LocalFileSystem.cpp @@ -127,16 +127,14 @@ void Win32LocalFileSystem::getFileListInDirectory(const AsciiString& currentDire HANDLE fileHandle = NULL; WIN32_FIND_DATA findData; - char search[_MAX_PATH]; AsciiString asciisearch; asciisearch = originalDirectory; asciisearch.concat(currentDirectory); asciisearch.concat(searchName); - strcpy(search, asciisearch.str()); Bool done = FALSE; - fileHandle = FindFirstFile(search, &findData); + fileHandle = FindFirstFile(asciisearch.str(), &findData); done = (fileHandle == INVALID_HANDLE_VALUE); while (!done) { diff --git a/Core/Libraries/Source/WWVegas/WW3D2/collect.cpp b/Core/Libraries/Source/WWVegas/WW3D2/collect.cpp index eaefe47fbd..43717fe6ae 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/collect.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/collect.cpp @@ -1015,7 +1015,8 @@ WW3DErrorType CollectionDefClass::Load(ChunkLoadClass & cload) if (cload.Read(&header,sizeof(header)) != sizeof(header)) goto Error; if (!cload.Close_Chunk()) goto Error; - strlcpy(Name,header.Name,W3D_NAME_LEN); + static_assert(ARRAY_SIZE(Name) >= ARRAY_SIZE(header.Name), "Incorrect array size"); + strcpy(Name,header.Name); ObjectNames.Resize(header.RenderObjectCount); while (cload.Open_Chunk()) { diff --git a/Core/Libraries/Source/WWVegas/WW3D2/hcanim.cpp b/Core/Libraries/Source/WWVegas/WW3D2/hcanim.cpp index a38b30408b..6813ca0785 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/hcanim.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/hcanim.cpp @@ -255,7 +255,8 @@ int HCompressedAnimClass::Load_W3D(ChunkLoadClass & cload) cload.Close_Chunk(); - strcpy(Name,aheader.HierarchyName); + static_assert(ARRAY_SIZE(Name) >= ARRAY_SIZE(aheader.HierarchyName), "Incorrect array size"); + strcpy(Name, aheader.HierarchyName); strlcat(Name, ".", ARRAY_SIZE(Name)); strlcat(Name, aheader.Name, ARRAY_SIZE(Name)); @@ -263,7 +264,8 @@ int HCompressedAnimClass::Load_W3D(ChunkLoadClass & cload) WWASSERT(HierarchyName != NULL); WWASSERT(aheader.HierarchyName != NULL); WWASSERT(sizeof(HierarchyName) >= W3D_NAME_LEN); - strlcpy(HierarchyName,aheader.HierarchyName,W3D_NAME_LEN); + static_assert(ARRAY_SIZE(HierarchyName) >= ARRAY_SIZE(aheader.HierarchyName), "Incorrect array size"); + strcpy(HierarchyName, aheader.HierarchyName); HTreeClass * base_pose = WW3DAssetManager::Get_Instance()->Get_HTree(HierarchyName); if (base_pose == NULL) { diff --git a/Core/Libraries/Source/WWVegas/WW3D2/hmdldef.cpp b/Core/Libraries/Source/WWVegas/WW3D2/hmdldef.cpp index dadf97e65b..0a344c8e12 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/hmdldef.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/hmdldef.cpp @@ -148,9 +148,12 @@ int HModelDefClass::Load_W3D(ChunkLoadClass & cload) /* ** process the header info */ - strlcpy(ModelName,header.Name,W3D_NAME_LEN); - strlcpy(BasePoseName,header.HierarchyName,W3D_NAME_LEN); - strcpy(Name,ModelName); + static_assert(ARRAY_SIZE(ModelName) >= ARRAY_SIZE(header.Name), "Incorrect array size"); + static_assert(ARRAY_SIZE(BasePoseName) >= ARRAY_SIZE(header.HierarchyName), "Incorrect array size"); + static_assert(ARRAY_SIZE(Name) >= ARRAY_SIZE(ModelName), "Incorrect array size"); + strcpy(ModelName, header.Name); + strcpy(BasePoseName, header.HierarchyName); + strcpy(Name, ModelName); /* ** Just allocate a node for the number of sub objects we're expecting @@ -232,7 +235,8 @@ bool HModelDefClass::read_connection(ChunkLoadClass & cload,HmdlNodeDefStruct * return false; } - strcpy(node->RenderObjName,ModelName); + static_assert(ARRAY_SIZE(node->RenderObjName) >= ARRAY_SIZE(ModelName), "Incorrect array size"); + strcpy(node->RenderObjName, ModelName); strlcat(node->RenderObjName, ".", ARRAY_SIZE(node->RenderObjName)); strlcat(node->RenderObjName, con.RenderObjName, ARRAY_SIZE(node->RenderObjName)); diff --git a/Core/Libraries/Source/WWVegas/WW3D2/ringobj.cpp b/Core/Libraries/Source/WWVegas/WW3D2/ringobj.cpp index 6fde0831d2..5108aa7152 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/ringobj.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/ringobj.cpp @@ -1206,7 +1206,7 @@ RingPrototypeClass::RingPrototypeClass (void) RingPrototypeClass::RingPrototypeClass(RingRenderObjClass *ring) { ::memset (&Definition, 0, sizeof (Definition)); - ::strcpy (Definition.Name, ring->Get_Name ()); + strlcpy(Definition.Name, ring->Get_Name(), ARRAY_SIZE(Definition.Name)); Definition.AnimDuration = ring->AnimDuration; Definition.Attributes = ring->Get_Flags (); @@ -1237,7 +1237,7 @@ RingPrototypeClass::RingPrototypeClass(RingRenderObjClass *ring) filename = name; } - ::strcpy (Definition.TextureName, filename); + strlcpy(Definition.TextureName, filename, ARRAY_SIZE(Definition.TextureName)); } // diff --git a/Core/Libraries/Source/WWVegas/WW3D2/sphereobj.cpp b/Core/Libraries/Source/WWVegas/WW3D2/sphereobj.cpp index 2e97045991..3b24f5e09d 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/sphereobj.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/sphereobj.cpp @@ -1162,7 +1162,7 @@ SpherePrototypeClass::SpherePrototypeClass (void) SpherePrototypeClass::SpherePrototypeClass(SphereRenderObjClass *sphere) { ::memset (&Definition, 0, sizeof (Definition)); - ::strcpy (Definition.Name, sphere->Get_Name ()); + strlcpy(Definition.Name, sphere->Get_Name(), ARRAY_SIZE(Definition.Name)); Definition.DefaultAlpha = sphere->Get_Default_Alpha (); Definition.AnimDuration = sphere->AnimDuration; @@ -1190,7 +1190,7 @@ SpherePrototypeClass::SpherePrototypeClass(SphereRenderObjClass *sphere) filename = name; } - ::strcpy (Definition.TextureName, filename); + strlcpy(Definition.TextureName, filename, ARRAY_SIZE(Definition.TextureName)); } diff --git a/Core/Libraries/Source/WWVegas/WWDownload/FTP.cpp b/Core/Libraries/Source/WWVegas/WWDownload/FTP.cpp index 94ec07d8d9..01e67957ea 100644 --- a/Core/Libraries/Source/WWVegas/WWDownload/FTP.cpp +++ b/Core/Libraries/Source/WWVegas/WWDownload/FTP.cpp @@ -1719,7 +1719,7 @@ HRESULT Cftp::FileRecoveryPosition( LPCSTR szLocalFileName, LPCSTR szRegistryRo // Concatenate the registry key together - strcpy( regkey, szRegistryRoot ); + strlcpy(regkey, szRegistryRoot, ARRAY_SIZE(regkey)); if( regkey[ strlen( regkey ) - 1 ] != '\\' ) { strlcat(regkey, "\\Download", ARRAY_SIZE(regkey)); diff --git a/Core/Libraries/Source/WWVegas/WWLib/Except.cpp b/Core/Libraries/Source/WWVegas/WWLib/Except.cpp index fe9e303638..e49d6ffb0e 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/Except.cpp +++ b/Core/Libraries/Source/WWVegas/WWLib/Except.cpp @@ -903,7 +903,7 @@ void Register_Thread_ID(unsigned long thread_id, char *thread_name, bool main_th ThreadInfoType *thread = new ThreadInfoType; thread->ThreadID = thread_id; - strcpy(thread->ThreadName, thread_name); + strlcpy(thread->ThreadName, thread_name, ARRAY_SIZE(thread->ThreadName)); thread->Main = main_thread; thread->ThreadHandle = INVALID_HANDLE_VALUE; ThreadList.Add(thread); diff --git a/Core/Libraries/Source/WWVegas/WWLib/WWCommon.h b/Core/Libraries/Source/WWVegas/WWLib/WWCommon.h index fa0ec8c282..d36f6df963 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/WWCommon.h +++ b/Core/Libraries/Source/WWVegas/WWLib/WWCommon.h @@ -26,8 +26,13 @@ // This macro serves as a general way to determine the number of elements within an array. #ifndef ARRAY_SIZE -#define ARRAY_SIZE(x) int(sizeof(x)/sizeof(x[0])) +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) +#else +template char (*ArraySizeHelper(Type(&)[Size]))[Size]; +#define ARRAY_SIZE(arr) sizeof(*ArraySizeHelper(arr)) #endif +#endif // ARRAY_SIZE enum { diff --git a/Core/Libraries/Source/WWVegas/WWLib/ffactory.cpp b/Core/Libraries/Source/WWVegas/WWLib/ffactory.cpp index 308d5e5e6a..02ea652aea 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/ffactory.cpp +++ b/Core/Libraries/Source/WWVegas/WWLib/ffactory.cpp @@ -146,7 +146,7 @@ void SimpleFileFactoryClass::Prepend_Sub_Directory( const char * sub_directory ) // Ensure sub_directory ends with a slash, and append a semicolon char temp_sub_dir[1024]; - strcpy(temp_sub_dir, sub_directory); + strlcpy(temp_sub_dir, sub_directory, ARRAY_SIZE(temp_sub_dir)); if (temp_sub_dir[sub_len - 1] != '\\') { temp_sub_dir[sub_len] = '\\'; temp_sub_dir[sub_len + 1] = 0; @@ -181,7 +181,7 @@ void SimpleFileFactoryClass::Append_Sub_Directory( const char * sub_directory ) // Ensure sub_directory ends with a slash char temp_sub_dir[1024]; - strcpy(temp_sub_dir, sub_directory); + strlcpy(temp_sub_dir, sub_directory, ARRAY_SIZE(temp_sub_dir)); if (temp_sub_dir[sub_len - 1] != '\\') { temp_sub_dir[sub_len] = '\\'; temp_sub_dir[sub_len + 1] = 0; diff --git a/Core/Libraries/Source/WWVegas/WWLib/ini.cpp b/Core/Libraries/Source/WWVegas/WWLib/ini.cpp index 0d28dd83d4..db08a4d6c4 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/ini.cpp +++ b/Core/Libraries/Source/WWVegas/WWLib/ini.cpp @@ -430,7 +430,7 @@ int INIClass::Load(Straw & ffile) if (ptr != NULL) *ptr = '\0'; strtrim(buffer); char section[64]; - strcpy(section, buffer); + strlcpy(section, buffer, ARRAY_SIZE(section)); /* ** Read in the entries of this section. diff --git a/Core/Libraries/Source/WWVegas/WWLib/registry.cpp b/Core/Libraries/Source/WWVegas/WWLib/registry.cpp index de172c5f49..15ec71602f 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/registry.cpp +++ b/Core/Libraries/Source/WWVegas/WWLib/registry.cpp @@ -470,7 +470,7 @@ void RegistryClass::Save_Registry_Tree(char *path, INIClass *ini) ** See if there are sub keys. */ char new_key_path[512]; - strcpy(new_key_path, path); + strlcpy(new_key_path, path, ARRAY_SIZE(new_key_path)); strlcat(new_key_path, "\\", ARRAY_SIZE(new_key_path)); strlcat(new_key_path, name, ARRAY_SIZE(new_key_path)); @@ -564,7 +564,7 @@ void RegistryClass::Load_Registry(const char *filename, char *old_path, char *ne ** Build the new path to use in the registry. */ char *section_name = section->Section; - strcpy(path, new_path); + strlcpy(path, new_path, ARRAY_SIZE(path)); char *cut = strstr(section_name, old_path); if (cut) { strlcat(path, cut + old_path_len, ARRAY_SIZE(path)); @@ -693,7 +693,7 @@ void RegistryClass::Delete_Registry_Tree(char *path) ** See if there are sub keys. */ char new_key_path[512]; - strcpy(new_key_path, path); + strlcpy(new_key_path, path, ARRAY_SIZE(new_key_path)); strlcat(new_key_path, "\\", ARRAY_SIZE(new_key_path)); strlcat(new_key_path, name, ARRAY_SIZE(new_key_path)); diff --git a/Core/Libraries/Source/debug/debug_debug.cpp b/Core/Libraries/Source/debug/debug_debug.cpp index 27e412e55c..5bc38c7c5b 100644 --- a/Core/Libraries/Source/debug/debug_debug.cpp +++ b/Core/Libraries/Source/debug/debug_debug.cpp @@ -1188,7 +1188,7 @@ void Debug::UpdateFrameStatus(FrameHashEntry &entry) entry.frameType==FrameTypeCheck) wsprintf(help,"%s(%i)",entry.fileOrGroup,entry.line); else - strcpy(help,entry.fileOrGroup); + strlcpy(help, entry.fileOrGroup, ARRAY_SIZE(help)); // update frame status bool active=entry.frameType!=FrameTypeLog; diff --git a/Core/Libraries/Source/debug/debug_io_flat.cpp b/Core/Libraries/Source/debug/debug_io_flat.cpp index f78a5e7059..eec7cd31f6 100644 --- a/Core/Libraries/Source/debug/debug_io_flat.cpp +++ b/Core/Libraries/Source/debug/debug_io_flat.cpp @@ -83,17 +83,15 @@ void DebugIOFlat::OutputStream::Delete(const char *path) char help[512]; if (path[0]&&(path[1]==':'||(path[0]=='\\'&&path[1]=='\\'))) { - strcpy(help,path); - strcpy(help+pathLen,fileNameOnly); - help[ext-fileNameOnly+pathLen]=0; + strlcpy(help, path, ARRAY_SIZE(help)); + strlcat(help, fileNameOnly, ARRAY_SIZE(help)); } else { // no, relative path given - strcpy(help,m_fileName); - strcpy(help+(fileNameOnly-m_fileName),path); - strcpy(help+(fileNameOnly-m_fileName)+pathLen,fileNameOnly); - help[ext-fileNameOnly+pathLen+(fileNameOnly-m_fileName)]=0; + strlcpy(help, m_fileName, ARRAY_SIZE(help)); + strlcat(help, path, ARRAY_SIZE(help)); + strlcat(help, fileNameOnly, ARRAY_SIZE(help)); } if (++run) wsprintf(help+strlen(help),"(%i)%s",run,ext); @@ -268,7 +266,7 @@ void DebugIOFlat::ExpandMagic(const char *src, const char *splitName, char *buf) case 'n': case 'N': if (splitName&&strlen(splitName)<250) - strcpy(help,splitName); + strlcpy(help, splitName, ARRAY_SIZE(help)); break; default: *dst++=src[-1]; @@ -277,7 +275,7 @@ void DebugIOFlat::ExpandMagic(const char *src, const char *splitName, char *buf) unsigned len=strlen(help); if (dst-buf+len>250) break; - strcpy(dst,help); + strcpy(dst, help); dst+=len; } strcpy(dst,".log"); @@ -418,7 +416,7 @@ void DebugIOFlat::Execute(class Debug& dbg, const char *cmd, bool structuredCmd, // add [ [ ] ] __ASSERT(m_firstStream==NULL); - strcpy(m_baseFilename,argn?argv[0]:"*eMN"); + strlcpy(m_baseFilename, argn?argv[0]:"*eMN", ARRAY_SIZE(m_baseFilename)); char fn[256]; ExpandMagic(m_baseFilename,NULL,fn); diff --git a/Generals/Code/GameEngine/Source/Common/INI/INI.cpp b/Generals/Code/GameEngine/Source/Common/INI/INI.cpp index 9f131d4211..3aca266605 100644 --- a/Generals/Code/GameEngine/Source/Common/INI/INI.cpp +++ b/Generals/Code/GameEngine/Source/Common/INI/INI.cpp @@ -404,7 +404,7 @@ UnsignedInt INI::load( AsciiString filename, INILoadType loadType, Xfer *pXfer ) if (parse) { #ifdef DEBUG_CRASHING - strcpy(m_curBlockStart, m_buffer); + strlcpy(m_curBlockStart, m_buffer, ARRAY_SIZE(m_curBlockStart)); #endif try { (*parse)( this ); @@ -776,7 +776,7 @@ AsciiString INI::getNextQuotedAsciiString() Bool done=FALSE; if ((strLen=strlen(token)) > 1) { - strcpy(buff, &token[1]); //skip the starting quote + strlcpy(buff, &token[1], ARRAY_SIZE(buff)); //skip the starting quote //Check for end of quoted string. Checking here fixes cases where quoted string on same line with other data. if (buff[strLen-2]=='"') //skip ending quote if present { buff[strLen-2]='\0'; @@ -825,7 +825,7 @@ AsciiString INI::getNextAsciiString() if (strlen(token) > 1) { - strcpy(buff, &token[1]); + strlcpy(buff, &token[1], ARRAY_SIZE(buff)); } token = getNextToken(getSepsQuote()); diff --git a/Generals/Code/GameEngine/Source/Common/PerfTimer.cpp b/Generals/Code/GameEngine/Source/Common/PerfTimer.cpp index d01abfd4f7..41e5557df0 100644 --- a/Generals/Code/GameEngine/Source/Common/PerfTimer.cpp +++ b/Generals/Code/GameEngine/Source/Common/PerfTimer.cpp @@ -269,10 +269,10 @@ void PerfGather::reset() { PerfGather::termPerfDump(); - strcpy(s_buf, fname); + strlcpy(s_buf, fname, ARRAY_SIZE(s_buf); char tmp[256]; - strcpy(tmp, s_buf); + strlcpy(tmp, s_buf, ARRAY_SIZE(tmp)); strlcat(tmp, ".csv", ARRAY_SIZE(tmp)); s_perfStatsFile = fopen(tmp, "w"); diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp index 5c0e0d74a0..e3d7e353f6 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp @@ -1260,9 +1260,9 @@ WindowMsgHandledType WOLLoginMenuSystem( GameWindow *window, UnsignedInt msg, loginAttemptTime = timeGetTime(); BuddyRequest req; req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGINNEW; - strcpy(req.arg.login.nick, login.str()); - strcpy(req.arg.login.email, email.str()); - strcpy(req.arg.login.password, password.str()); + strlcpy(req.arg.login.nick, login.str(), ARRAY_SIZE(req.arg.login.nick)); + strlcpy(req.arg.login.email, email.str(), ARRAY_SIZE(req.arg.login.email)); + strlcpy(req.arg.login.password, password.str(), ARRAY_SIZE(req.arg.login.password)); req.arg.login.hasFirewall = TRUE; TheGameSpyInfo->setLocalBaseName( login ); @@ -1349,9 +1349,9 @@ WindowMsgHandledType WOLLoginMenuSystem( GameWindow *window, UnsignedInt msg, loginAttemptTime = timeGetTime(); BuddyRequest req; req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGIN; - strcpy(req.arg.login.nick, login.str()); - strcpy(req.arg.login.email, email.str()); - strcpy(req.arg.login.password, password.str()); + strlcpy(req.arg.login.nick, login.str(), ARRAY_SIZE(req.arg.login.nick)); + strlcpy(req.arg.login.email, email.str(), ARRAY_SIZE(req.arg.login.email)); + strlcpy(req.arg.login.password, password.str(), ARRAY_SIZE(req.arg.login.password)); req.arg.login.hasFirewall = true; TheGameSpyInfo->setLocalBaseName( login ); diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp index ed55cc7873..dcb40e294b 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp @@ -231,7 +231,7 @@ static void parseBitString( const char *inBuffer, UnsignedInt *bits, ConstCharPt char *tok; // do not modify the inBuffer argument - strcpy( buffer, inBuffer ); + strlcpy(buffer, inBuffer, ARRAY_SIZE(buffer)); if( strncmp( buffer, "NULL", 4 ) ) { @@ -604,7 +604,7 @@ static Bool parseFont( const char *token, WinInstanceData *instData, ptr++; ptr++; // skip the " c = strtok( ptr, stringSeps ); // value - strcpy( fontName, c ); + strlcpy(fontName, c, ARRAY_SIZE(fontName)); // "SIZE" c = strtok( NULL, seps ); // label @@ -1641,7 +1641,7 @@ static GameWindow *createGadget( char *type, // filename the radio button was saved in // - strcpy( filename, instData->m_decoratedNameString.str() ); + strlcpy(filename, instData->m_decoratedNameString.str(), ARRAY_SIZE(filename)); c = strchr( filename, ':' ); if( c ) *c = 0; // terminate after filename (format is filename:gadgetname) @@ -2365,7 +2365,7 @@ static GameWindow *parseWindow( File *inFile, char *buffer ) c = strtok( buffer, seps ); assert( strcmp( c, "WINDOWTYPE" ) == 0 ); c = strtok( NULL, seps ); // get data to right of = sign - strcpy( type, c ); + strlcpy(type, c, ARRAY_SIZE(type)); // // based on the window type get a pointer for any specific data @@ -2394,7 +2394,7 @@ static GameWindow *parseWindow( File *inFile, char *buffer ) if (asciibuf.compare(parse->name) == 0) { - strcpy( token, asciibuf.str() ); + strlcpy(token, asciibuf.str(), ARRAY_SIZE(token)); // eat '=' inFile->scanString(asciibuf); @@ -2610,7 +2610,7 @@ Bool parseLayoutBlock( File *inFile, char *buffer, UnsignedInt version, WindowLa // eat equals separator " = " c = strtok( buffer, " =" ); - strcpy(token, asciitoken.str()); + strlcpy(token, asciitoken.str(), ARRAY_SIZE(token)); // parse it if( parse->parse( token, c, version, info ) == FALSE ) @@ -2719,7 +2719,7 @@ GameWindow *GameWindowManager::winCreateFromScript( AsciiString filenameString, if( strchr( filename, '\\' ) == NULL ) sprintf( filepath, "Window\\%s", filename ); else - strcpy( filepath, filename ); + strlcpy(filepath, filename, ARRAY_SIZE(filepath)); // Open the input file inFile = TheFileSystem->openFile(filepath, File::READ); diff --git a/Generals/Code/GameEngine/Source/GameClient/RadiusDecal.cpp b/Generals/Code/GameEngine/Source/GameClient/RadiusDecal.cpp index a020654375..350e981e19 100644 --- a/Generals/Code/GameEngine/Source/GameClient/RadiusDecal.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/RadiusDecal.cpp @@ -73,7 +73,7 @@ void RadiusDecalTemplate::createRadiusDecal(const Coord3D& pos, Real radius, con decalInfo.allowUpdates = FALSE; // shadow texture will never update decalInfo.allowWorldAlign = TRUE; // shadow image will wrap around world objects decalInfo.m_type = m_shadowType; - strcpy(decalInfo.m_ShadowName, m_name.str()); // name of your texture + strlcpy(decalInfo.m_ShadowName, m_name.str(), ARRAY_SIZE(decalInfo.m_ShadowName)); // name of your texture decalInfo.m_sizeX = radius*2; // world space dimensions decalInfo.m_sizeY = radius*2; // world space dimensions diff --git a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 29ad251aaa..92d3f2bd83 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -2149,17 +2149,17 @@ void GameLogic::loadMapINI( AsciiString mapName ) char filename[_MAX_PATH]; char fullFledgeFilename[_MAX_PATH]; - memset(filename, 0, _MAX_PATH); - strcpy(filename, mapName.str()); - // // if map name begins with a "SAVE_DIRECTORY\", then the map refers to a map // that has been extracted from a save game file ... in that case we need to get // the pristine map name string in order to manipulate and load the right map.ini // for that map from it's original location // - if (TheGameState->isInSaveDirectory(filename)) - strcpy( filename, TheGameState->getSaveGameInfo()->pristineMapName.str() ); + const char* pristineMapName = TheGameState->isInSaveDirectory(filename) + ? TheGameState->getSaveGameInfo()->pristineMapName.str() + : mapName.str(); + + strlcpy(filename, pristineMapName, ARRAY_SIZE(filename)); // sanity int length = strlen(filename); diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp index 20c7de6772..8af5511a63 100644 --- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp +++ b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp @@ -558,9 +558,9 @@ void BuddyThreadClass::connectCallback( GPConnection *con, GPConnectResponseArg DEBUG_LOG(("User Error: Create Account instead of Login. Fixing them...")); BuddyRequest req; req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGIN; - strcpy(req.arg.login.nick, m_nick.c_str()); - strcpy(req.arg.login.email, m_email.c_str()); - strcpy(req.arg.login.password, m_pass.c_str()); + strlcpy(req.arg.login.nick, m_nick.c_str(), ARRAY_SIZE(req.arg.login.nick)); + strlcpy(req.arg.login.email, m_email.c_str(), ARRAY_SIZE(req.arg.login.email)); + strlcpy(req.arg.login.password, m_pass.c_str(), ARRAY_SIZE(req.arg.login.password)); req.arg.login.hasFirewall = true; TheGameSpyBuddyMessageQueue->addRequest( req ); return; diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp index 650f249c5e..06db0bf2b1 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp @@ -1824,7 +1824,7 @@ void W3DModelDraw::allocateShadows(void) if (m_shadow == NULL && m_renderObject && TheW3DShadowManager && tmplate->getShadowType() != SHADOW_NONE) { Shadow::ShadowTypeInfo shadowInfo; - strcpy(shadowInfo.m_ShadowName, tmplate->getShadowTextureName().str()); + strlcpy(shadowInfo.m_ShadowName, tmplate->getShadowTextureName().str(), ARRAY_SIZE(shadowInfo.m_ShadowName)); DEBUG_ASSERTCRASH(shadowInfo.m_ShadowName[0] != '\0', ("this should be validated in ThingTemplate now")); shadowInfo.allowUpdates = FALSE; //shadow image will never update shadowInfo.allowWorldAlign = TRUE; //shadow image will wrap around world objects @@ -2698,7 +2698,7 @@ void W3DModelDraw::setTerrainDecal(TerrainDecalType type) //decalInfo.m_type = SHADOW_ADDITIVE_DECAL;//temporary kluge to test graphics - strcpy(decalInfo.m_ShadowName,TerrainDecalTextureName[type]); + strlcpy(decalInfo.m_ShadowName, TerrainDecalTextureName[type], ARRAY_SIZE(decalInfo.m_ShadowName)); decalInfo.m_sizeX = tmplate->getShadowSizeX(); decalInfo.m_sizeY = tmplate->getShadowSizeY(); decalInfo.m_offsetX = tmplate->getShadowOffsetX(); @@ -3014,7 +3014,7 @@ void W3DModelDraw::setModelState(const ModelConditionInfo* newState) if (m_renderObject && TheW3DShadowManager && tmplate->getShadowType() != SHADOW_NONE) { Shadow::ShadowTypeInfo shadowInfo; - strcpy(shadowInfo.m_ShadowName, tmplate->getShadowTextureName().str()); + strlcpy(shadowInfo.m_ShadowName, tmplate->getShadowTextureName().str(), ARRAY_SIZE(shadowInfo.m_ShadowName)); DEBUG_ASSERTCRASH(shadowInfo.m_ShadowName[0] != '\0', ("this should be validated in ThingTemplate now")); shadowInfo.allowUpdates = FALSE; //shadow image will never update shadowInfo.allowWorldAlign = TRUE; //shadow image will wrap around world objects @@ -3400,7 +3400,7 @@ Int W3DModelDraw::getPristineBonePositionsForConditionState( for (; i <= endIndex; ++i) { if (i == 0) - strcpy(buffer, boneNamePrefix); + strlcpy(buffer, boneNamePrefix, ARRAY_SIZE(buffer)); else sprintf(buffer, "%s%02d", boneNamePrefix, i); @@ -3515,7 +3515,7 @@ Int W3DModelDraw::getCurrentBonePositions( for (; i <= endIndex; ++i) { if (i == 0) - strcpy(buffer, boneNamePrefix); + strlcpy(buffer, boneNamePrefix, ARRAY_SIZE(buffer)); else sprintf(buffer, "%s%02d", boneNamePrefix, i); diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp index e14d435c5c..bab48f379a 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp @@ -1764,10 +1764,11 @@ W3DProjectedShadow* W3DProjectedShadowManager::addShadow(RenderObjClass *robj, S //to allow multiple models to share same shadow - for //example, all trees could use same shadow even if slightly //different color, etc. - strcpy(texture_name,shadowInfo->m_ShadowName); + static_assert(ARRAY_SIZE(texture_name) >= ARRAY_SIZE(shadowInfo->m_ShadowName), "Incorrect array size"); + strcpy(texture_name, shadowInfo->m_ShadowName); } else - strcpy(texture_name,robj->Get_Name()); //not texture name give, assume model name. + strlcpy(texture_name, robj->Get_Name(), ARRAY_SIZE(texture_name)); //not texture name give, assume model name. st=m_W3DShadowTextureManager->getTexture(texture_name); if (st == NULL) @@ -1786,7 +1787,7 @@ W3DProjectedShadow* W3DProjectedShadowManager::addShadow(RenderObjClass *robj, S } else { //no shadow info, assume user wants a projected shadow - strcpy(texture_name,robj->Get_Name()); + strlcpy(texture_name, robj->Get_Name(), ARRAY_SIZE(texture_name)); st=m_W3DShadowTextureManager->getTexture(texture_name); diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp index 55f7f17e1d..55a53a8596 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp @@ -240,7 +240,7 @@ RenderObjClass * W3DAssetManager::Create_Render_Obj(const char* name) static inline void Munge_Render_Obj_Name(char *newname, const char *oldname, float scale, const int color, const char *textureName) { char lower_case_name[255]; - strcpy(lower_case_name, oldname); + strlcpy(lower_case_name, oldname, ARRAY_SIZE(lower_case_name)); _strlwr(lower_case_name); if (!textureName) @@ -253,7 +253,7 @@ static inline void Munge_Render_Obj_Name(char *newname, const char *oldname, flo static inline void Munge_Texture_Name(char *newname, const char *oldname, const int color) { char lower_case_name[255]; - strcpy(lower_case_name, oldname); + strlcpy(lower_case_name, oldname, ARRAY_SIZE(lower_case_name)); _strlwr(lower_case_name); sprintf(newname,"#%d#%s", color, lower_case_name); } @@ -943,7 +943,7 @@ bool W3DAssetManager::Load_3D_Assets( const char * filename ) // Try to find an existing prototype char basename[512]; - strcpy(basename, filename); + strlcpy(basename, filename, ARRAY_SIZE(basename)); char *pext = strrchr(basename, '.'); //find file extension if (pext) *pext = '\0'; //drop the extension @@ -1287,7 +1287,7 @@ void W3DAssetManager::Make_Unique(RenderObjClass *robj, Bool geometry, Bool colo static inline void Munge_Render_Obj_Name(char *newname, const char *oldname, float scale, const Vector3 &hsv_shift) { char lower_case_name[255]; - strcpy(lower_case_name, oldname); + strlcpy(lower_case_name, oldname, ARRAY_SIZE(lower_case_name)); _strlwr(lower_case_name); sprintf(newname,"#%s!%gH%gS%gV%g", lower_case_name, scale, hsv_shift.X, hsv_shift.Y, hsv_shift.Z); } @@ -1295,7 +1295,7 @@ static inline void Munge_Render_Obj_Name(char *newname, const char *oldname, flo static inline void Munge_Texture_Name(char *newname, const char *oldname, const Vector3 &hsv_shift) { char lower_case_name[255]; - strcpy(lower_case_name, oldname); + strlcpy(lower_case_name, oldname, ARRAY_SIZE(lower_case_name)); _strlwr(lower_case_name); sprintf(newname,"#%s!H%gS%gV%g", lower_case_name, hsv_shift.X, hsv_shift.Y, hsv_shift.Z); } @@ -1318,7 +1318,7 @@ RenderObjClass * W3DAssetManager::Create_Render_Obj(const char * name,float scal if (isGranny) { //Granny objects share the same prototype since they allow instance scaling. - strcpy(newname,name); //use same name for all granny objects at any scale. + strlcpy(newname, name, ARRAY_SIZE(newname)); //use same name for all granny objects at any scale. } Set_WW3D_Load_On_Demand(false); // munged name will never be found in a file. rendobj=WW3DAssetManager::Create_Render_Obj(newname); @@ -1424,7 +1424,7 @@ TextureClass * W3DAssetManager::Get_Texture_With_HSV_Shift(const char * filename // No cached texture - need to create char lower_case_name[255]; - strcpy(lower_case_name, filename); + strlcpy(lower_case_name, filename, ARRAY_SIZE(lower_case_name)); _strlwr(lower_case_name); TextureClass *oldtex = TextureHash.Get(lower_case_name); if (!oldtex) { diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp index 58e83d84ab..282706871e 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp @@ -212,20 +212,20 @@ Bool W3DBridge::load(BodyDamageType curDamageState) default: return false; case BODY_PRISTINE: - strcpy( textureFile, bridge->getTexture().str() ); - strcpy( modelName, bridge->getBridgeModel().str() ); + strlcpy(textureFile, bridge->getTexture().str(), ARRAY_SIZE(textureFile)); + strlcpy(modelName, bridge->getBridgeModel().str(), ARRAY_SIZE(modelName)); break; case BODY_DAMAGED: - strcpy( textureFile, bridge->getTextureDamaged().str() ); - strcpy( modelName, bridge->getBridgeModelNameDamaged().str() ); + strlcpy(textureFile, bridge->getTextureDamaged().str(), ARRAY_SIZE(textureFile)); + strlcpy(modelName, bridge->getBridgeModelNameDamaged().str(), ARRAY_SIZE(modelName)); break; case BODY_REALLYDAMAGED: - strcpy( textureFile, bridge->getTextureReallyDamaged().str() ); - strcpy( modelName, bridge->getBridgeModelNameReallyDamaged().str() ); + strlcpy(textureFile, bridge->getTextureReallyDamaged().str(), ARRAY_SIZE(textureFile)); + strlcpy(modelName, bridge->getBridgeModelNameReallyDamaged().str(), ARRAY_SIZE(modelName)); break; case BODY_RUBBLE: - strcpy( textureFile, bridge->getTextureBroken().str() ); - strcpy( modelName, bridge->getBridgeModelNameBroken().str() ); + strlcpy(textureFile, bridge->getTextureBroken().str(), ARRAY_SIZE(textureFile)); + strlcpy(modelName, bridge->getBridgeModelNameBroken().str(), ARRAY_SIZE(modelName)); break; } @@ -234,6 +234,9 @@ Bool W3DBridge::load(BodyDamageType curDamageState) char section[_MAX_PATH]; char right[_MAX_PATH]; + static_assert(ARRAY_SIZE(left) >= ARRAY_SIZE(section), "Incorrect array size"); + static_assert(ARRAY_SIZE(section) >= ARRAY_SIZE(modelName), "Incorrect array size"); + static_assert(ARRAY_SIZE(right) >= ARRAY_SIZE(modelName), "Incorrect array size"); strcpy(left, modelName); strlcat(left, ".BRIDGE_LEFT", ARRAY_SIZE(left)); strcpy(section, modelName); @@ -254,15 +257,15 @@ Bool W3DBridge::load(BodyDamageType curDamageState) Matrix3D mtx = pSub->Get_Transform(); if (0==strnicmp(left, pSub->Get_Name(), strlen(left))) { m_leftMtx = mtx; - strcpy(left, pSub->Get_Name()); + strlcpy(left, pSub->Get_Name(), ARRAY_SIZE(left)); } if (0==strnicmp(section, pSub->Get_Name(), strlen(section))) { m_sectionMtx = mtx; - strcpy(section, pSub->Get_Name()); + strlcpy(section, pSub->Get_Name(), ARRAY_SIZE(section)); } if (0==strnicmp(right, pSub->Get_Name(), strlen(right))) { m_rightMtx = mtx; - strcpy(right, pSub->Get_Name()); + strlcpy(right, pSub->Get_Name(), ARRAY_SIZE(right)); } REF_PTR_RELEASE(pSub); //DEBUG_LOG(("Sub obj name %s", pSub->Get_Name())); diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index 561f507542..de0aeff179 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -2893,7 +2893,7 @@ void W3DDisplay::takeScreenShot(void) #else sprintf( leafname, "%s%.3d.bmp", "sshot", frame_number++); #endif - strcpy(pathname, TheGlobalData->getPath_UserData().str()); + strlcpy(pathname, TheGlobalData->getPath_UserData().str(), ARRAY_SIZE(pathname)); strlcat(pathname, leafname, ARRAY_SIZE(pathname)); if (_access( pathname, 0 ) == -1) done = true; diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DFileSystem.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DFileSystem.cpp index 2261562bf6..c0df9dc89d 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DFileSystem.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DFileSystem.cpp @@ -171,7 +171,7 @@ char const * GameFileClass::Set_Name( char const *filename ) } else - strcpy( m_filePath, filename ); + strlcpy(m_filePath, filename, ARRAY_SIZE(m_filePath)); // see if the file exists m_fileExists = TheFileSystem->doesFileExist( m_filePath ); diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp index 4edfd72bde..c5cb7e4168 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp @@ -930,10 +930,8 @@ void WaterTracksRenderSystem::saveTracks(void) AsciiString fileName=TheTerrainLogic->getSourceFilename(); char path[256]; - strcpy(path,fileName.str()); - Int len=strlen(path); - - strcpy(path+len-4,".wak"); + strlcpy(path, fileName.str(), ARRAY_SIZE(path)); + strlcat(path, ".wak", ARRAY_SIZE(path)); WaterTracksObj *umod; Int trackCount=0; @@ -968,10 +966,8 @@ void WaterTracksRenderSystem::loadTracks(void) AsciiString fileName=TheTerrainLogic->getSourceFilename(); char path[256]; - strcpy(path,fileName.str()); - Int len=strlen(path); - - strcpy(path+len-4,".wak"); + strlcpy(path, fileName.str(), ARRAY_SIZE(path)); + strlcat(path, ".wak", ARRAY_SIZE(path)); File *file = TheFileSystem->openFile(path, File::READ | File::BINARY); WaterTracksObj *umod; diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/hmorphanim.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/hmorphanim.cpp index 8214610364..87b28837ea 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/hmorphanim.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/hmorphanim.cpp @@ -475,7 +475,7 @@ void HMorphAnimClass::Set_Name(const char * name) // // Copy the full name // - ::strcpy (Name, name); + strlcpy(Name, name, ARRAY_SIZE(Name)); // // Try to find the separator (a period) @@ -489,8 +489,8 @@ void HMorphAnimClass::Set_Name(const char * name) // into our two buffers // separator[0] = 0; - ::strcpy (AnimName, separator + 1); - ::strcpy (HierarchyName, full_name); + strlcpy(AnimName, separator + 1, ARRAY_SIZE(AnimName)); + strlcpy(HierarchyName, full_name, ARRAY_SIZE(HierarchyName)); } return ; @@ -549,9 +549,12 @@ int HMorphAnimClass::Load_W3D(ChunkLoadClass & cload) cload.Read(&header,sizeof(header)); cload.Close_Chunk(); - strlcpy(AnimName,header.Name,sizeof(AnimName)); - strlcpy(HierarchyName,header.HierarchyName,sizeof(HierarchyName)); - strcpy(Name,HierarchyName); + static_assert(ARRAY_SIZE(AnimName) >= ARRAY_SIZE(header.Name), "Incorrect array size"); + static_assert(ARRAY_SIZE(HierarchyName) >= ARRAY_SIZE(header.HierarchyName), "Incorrect array size"); + static_assert(ARRAY_SIZE(Name) >= ARRAY_SIZE(HierarchyName), "Incorrect array size"); + strcpy(AnimName, header.Name); + strcpy(HierarchyName, header.HierarchyName); + strcpy(Name, HierarchyName); strlcat(Name, ".", ARRAY_SIZE(Name)); strlcat(Name, AnimName, ARRAY_SIZE(Name)); diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/hrawanim.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/hrawanim.cpp index ae95dfc976..d2dfd93862 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/hrawanim.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/hrawanim.cpp @@ -211,7 +211,7 @@ int HRawAnimClass::Load_W3D(ChunkLoadClass & cload) pre30 = true; } - strcpy(Name,aheader.HierarchyName); + strlcpy(Name, aheader.HierarchyName, ARRAY_SIZE(Name)); strlcat(Name, ".", ARRAY_SIZE(Name)); strlcat(Name, aheader.Name, ARRAY_SIZE(Name)); diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/nullrobj.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/nullrobj.cpp index 4151b3daa1..a08a7853bc 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/nullrobj.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/nullrobj.cpp @@ -45,7 +45,7 @@ NullLoaderClass _NullLoader; Null3DObjClass::Null3DObjClass(const char * name) { - strcpy(Name, name); + strlcpy(Name, name, ARRAY_SIZE(Name)); } Null3DObjClass::Null3DObjClass(const Null3DObjClass & src) diff --git a/Generals/Code/Tools/GUIEdit/Include/LayoutScheme.h b/Generals/Code/Tools/GUIEdit/Include/LayoutScheme.h index 550c035c87..8cd195b9fc 100644 --- a/Generals/Code/Tools/GUIEdit/Include/LayoutScheme.h +++ b/Generals/Code/Tools/GUIEdit/Include/LayoutScheme.h @@ -124,7 +124,7 @@ class LayoutScheme // INLINING /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// inline char *LayoutScheme::getSchemeFilename( void ) { return m_schemeFilename; } -inline void LayoutScheme::setSchemeFilename( char *filename ) { strcpy( m_schemeFilename, filename ); } +inline void LayoutScheme::setSchemeFilename( char *filename ) { strlcpy(m_schemeFilename, filename, ARRAY_SIZE(m_schemeFilename)); } inline Color LayoutScheme::getEnabledTextColor( void ) { return m_enabledText.color; } inline Color LayoutScheme::getEnabledTextBorderColor( void ) { return m_enabledText.borderColor; } inline Color LayoutScheme::getDisabledTextColor( void ) { return m_disabledText.color; } diff --git a/Generals/Code/Tools/GUIEdit/Source/GUIEdit.cpp b/Generals/Code/Tools/GUIEdit/Source/GUIEdit.cpp index 4c38d26286..e5a350b1a9 100644 --- a/Generals/Code/Tools/GUIEdit/Source/GUIEdit.cpp +++ b/Generals/Code/Tools/GUIEdit/Source/GUIEdit.cpp @@ -251,14 +251,14 @@ void GUIEdit::setSaveFile( const char *fullPathAndFilename ) const char *ptr; // copy over the full path and filename - strcpy( m_savePathAndFilename, fullPathAndFilename ); + strlcpy(m_savePathAndFilename, fullPathAndFilename, ARRAY_SIZE(m_savePathAndFilename)); // // copy everything after the last '\' from the full path, this will // be just the filename with extension // ptr = strrchr( fullPathAndFilename, '\\' ) + 1; - strcpy( m_saveFilename, ptr ); + strlcpy(m_saveFilename, ptr, ARRAY_SIZE(m_saveFilename)); } diff --git a/Generals/Code/Tools/GUIEdit/Source/GUIEditWindowManager.cpp b/Generals/Code/Tools/GUIEdit/Source/GUIEditWindowManager.cpp index df5e9a0dc1..8e00fe565f 100644 --- a/Generals/Code/Tools/GUIEdit/Source/GUIEditWindowManager.cpp +++ b/Generals/Code/Tools/GUIEdit/Source/GUIEditWindowManager.cpp @@ -501,7 +501,7 @@ void GUIEditWindowManager::incrementName( GameWindow *window ) // this I will botch it (cuz I'm currently not sure // how to test it) char name[MAX_WINDOW_NAME_LEN]; - strcpy(name, instData->m_decoratedNameString.str()); + strlcpy(name, instData->m_decoratedNameString.str(), ARRAY_SIZE(name)); Int len = strlen( name ); char numberBuffer[ MAX_WINDOW_NAME_LEN ]; diff --git a/Generals/Code/Tools/WorldBuilder/src/BlendMaterial.cpp b/Generals/Code/Tools/WorldBuilder/src/BlendMaterial.cpp index 3eaa72618e..2848478375 100644 --- a/Generals/Code/Tools/WorldBuilder/src/BlendMaterial.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/BlendMaterial.cpp @@ -191,15 +191,15 @@ void BlendMaterial::addTerrain(const char *pPath, Int terrainNdx, HTREEITEM pare } // set the name in the tree view to that of the entry - strcpy( buffer, terrain->getName().str() ); + strlcpy(buffer, terrain->getName().str(), ARRAY_SIZE(buffer)); doAdd = TRUE; } else if (terrainNdx==-1) { - strcpy(buffer, pPath); + strlcpy(buffer, pPath, ARRAY_SIZE(buffer)); doAdd = true; } else if (WorldHeightMapEdit::getTexClassIsBlendEdge(terrainNdx)) { parent = findOrAdd( parent, "**EVAL**" ); - strcpy(buffer, pPath); + strlcpy(buffer, pPath, ARRAY_SIZE(buffer)); doAdd = true; } diff --git a/Generals/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp index 46931a87a9..a8018940ae 100644 --- a/Generals/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp @@ -94,7 +94,7 @@ BOOL MeshMoldOptions::OnInitDialog() int len = filename.getLength(); if (len<5) continue; - strcpy(fileBuf, filename.str()); + strlcpy(fileBuf, filename.str(), ARRAY_SIZE(fileBuf)); for (i=strlen(fileBuf)-1; i>0; i--) { if (fileBuf[i] == '.') { // strip off .w3d file extension. diff --git a/Generals/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp b/Generals/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp index 4868389506..5f4b9d903a 100644 --- a/Generals/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp @@ -265,6 +265,7 @@ BOOL PickUnitDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) m_objectTreeView.GetItem(&item); if (item.lParam >= 0) { m_currentObjectIndex = item.lParam; + static_assert(ARRAY_SIZE(m_currentObjectName) >= ARRAY_SIZE(buffer), "Incorrect array size"); strcpy(m_currentObjectName, buffer); } else if (m_objectTreeView.ItemHasChildren(item.hItem)) { strcpy(m_currentObjectName, ""); diff --git a/Generals/Code/Tools/WorldBuilder/src/RoadOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/RoadOptions.cpp index 694b1de6cb..744d8d857a 100644 --- a/Generals/Code/Tools/WorldBuilder/src/RoadOptions.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/RoadOptions.cpp @@ -242,18 +242,10 @@ BOOL RoadOptions::OnInitDialog() // load roads from test assets #ifdef LOAD_TEST_ASSETS { - char dirBuf[_MAX_PATH]; - char findBuf[_MAX_PATH]; char fileBuf[_MAX_PATH]; - static_assert(ARRAY_SIZE(dirBuf) >= ARRAY_SIZE(ROAD_DIRECTORY), "Incorrect array size"); - strcpy(dirBuf, ROAD_DIRECTORY); - int len = strlen(dirBuf); - - strcpy(findBuf, dirBuf); - FilenameList filenameList; - TheFileSystem->getFileListInDirectory(AsciiString(findBuf), AsciiString("*.tga"), filenameList, FALSE); + TheFileSystem->getFileListInDirectory(ROAD_DIRECTORY, "*.tga", filenameList, FALSE); if (filenameList.size() > 0) { FilenameList::iterator it = filenameList.begin(); @@ -264,7 +256,7 @@ BOOL RoadOptions::OnInitDialog() ++it; continue; } - len = filename.getLength(); + int len = filename.getLength(); if (len<5) { ++it; continue; @@ -389,7 +381,7 @@ void RoadOptions::addRoad(char *pPath, Int terrainNdx, HTREEITEM parent) parent = findOrAdd( parent, "Roads" ); // set the name to place as the name of the road entry in INI - strcpy( buffer, road->getName().str() ); + strlcpy(buffer, road->getName().str(), ARRAY_SIZE(buffer)); // do the add doAdd = TRUE; @@ -399,7 +391,7 @@ void RoadOptions::addRoad(char *pPath, Int terrainNdx, HTREEITEM parent) #ifdef LOAD_TEST_ASSETS if (!doAdd && !strncmp(TEST_STRING, pPath, strlen(TEST_STRING))) { parent = findOrAdd(parent, TEST_STRING); - strcpy(buffer, pPath + strlen(TEST_STRING) + 1); + strlcpy(buffer, pPath + strlen(TEST_STRING) + 1, ARRAY_SIZE(buffer)); doAdd = true; } #endif diff --git a/Generals/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp b/Generals/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp index f1819af44a..9abdd6d479 100644 --- a/Generals/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp @@ -86,7 +86,7 @@ BOOL SelectMacrotexture::OnInitDialog() AsciiString filename = *it; int len = filename.getLength(); if (len<5) continue; - strcpy(fileBuf, filename.str()); + strlcpy(fileBuf, filename.str(), ARRAY_SIZE(fileBuf)); ::memset(&ins, 0, sizeof(ins)); ins.hParent = TVI_ROOT; ins.hInsertAfter = TVI_SORT; diff --git a/Generals/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp b/Generals/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp index d8b75321a7..beed12aff1 100644 --- a/Generals/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp @@ -302,7 +302,7 @@ void TerrainMaterial::addTerrain(char *pPath, Int terrainNdx, HTREEITEM parent) } // set the name in the tree view to that of the entry - strcpy( buffer, terrain->getName().str() ); + strlcpy(buffer, terrain->getName().str(), ARRAY_SIZE(buffer)); doAdd = TRUE; } diff --git a/Generals/Code/Tools/WorldBuilder/src/TerrainModal.cpp b/Generals/Code/Tools/WorldBuilder/src/TerrainModal.cpp index 430d7b36d0..c4d6e5a30a 100644 --- a/Generals/Code/Tools/WorldBuilder/src/TerrainModal.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/TerrainModal.cpp @@ -172,7 +172,7 @@ void TerrainModal::addTerrain(char *pPath, Int terrainNdx, HTREEITEM parent) } - strcpy( buffer, terrain->getName().str() ); + strlcpy(buffer, terrain->getName().str(), ARRAY_SIZE(buffer)); doAdd = TRUE; diff --git a/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp b/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp index fa278f7ebe..a756f622f7 100644 --- a/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp @@ -125,7 +125,7 @@ char const * WBGameFileClass::Set_Name( char const *filename ) } if (TheFileSystem->doesFileExist(filename)) { - strcpy( m_filePath, filename ); + strlcpy(m_filePath, filename, ARRAY_SIZE(m_filePath)); m_fileExists = true; } return m_filename; @@ -347,7 +347,7 @@ BOOL CWorldBuilderApp::InitInstance() #if 1 // srj sez: put INI into our user data folder, not the ap dir free((void*)m_pszProfileName); - strcpy(buf, TheGlobalData->getPath_UserData().str()); + strlcpy(buf, TheGlobalData->getPath_UserData().str(), ARRAY_SIZE(buf)); strlcat(buf, "WorldBuilder.ini", ARRAY_SIZE(buf)); #else strlcat(buf, "//", ARRAY_SIZE(buf)); diff --git a/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp b/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp index d2f89e964f..c94bf3d688 100644 --- a/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp @@ -2098,16 +2098,13 @@ void CWorldBuilderDoc::OnDumpDocToText(void) static FILE *theLogFile = NULL; Bool open = false; try { - char dirbuf[ _MAX_PATH ]; - ::GetModuleFileName( NULL, dirbuf, sizeof( dirbuf ) ); - if (char *pEnd = strrchr(dirbuf, '\\')) + char curbuf[_MAX_PATH]; + GetModuleFileName(NULL, curbuf, sizeof(curbuf)); + if (char *pEnd = strrchr(curbuf, '\\')) { *(pEnd + 1) = 0; } - char curbuf[ _MAX_PATH ]; - - strcpy(curbuf, dirbuf); strlcat(curbuf, m_strTitle, ARRAY_SIZE(curbuf)); strlcat(curbuf, ".txt", ARRAY_SIZE(curbuf)); diff --git a/Generals/Code/Tools/WorldBuilder/src/playerlistdlg.cpp b/Generals/Code/Tools/WorldBuilder/src/playerlistdlg.cpp index e66da5dde4..5a62979733 100644 --- a/Generals/Code/Tools/WorldBuilder/src/playerlistdlg.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/playerlistdlg.cpp @@ -87,7 +87,7 @@ static void ensureValidPlayerName(Dict *d) { // ensure there are no illegal chars in it. (in particular, no spaces!) char buf[1024]; - strcpy(buf, d->getAsciiString(TheKey_playerName).str()); + strlcpy(buf, d->getAsciiString(TheKey_playerName).str(), ARRAY_SIZE(buf)); for (char* p = buf; *p; ++p) if (!islegalplayernamechar(*p)) *p = '_'; diff --git a/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp b/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp index b867dd42fa..4028488247 100644 --- a/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp @@ -1140,7 +1140,7 @@ void WbView3d::invalBuildListItemInView(BuildListInfo *pBuildToInval) Shadow::ShadowTypeInfo shadowInfo; shadowInfo.allowUpdates=FALSE; //shadow image will never update shadowInfo.allowWorldAlign=TRUE; //shadow image will wrap around world objects - strcpy(shadowInfo.m_ShadowName,tTemplate->getShadowTextureName().str()); + strlcpy(shadowInfo.m_ShadowName, tTemplate->getShadowTextureName().str(), ARRAY_SIZE(shadowInfo.m_ShadowName)); DEBUG_ASSERTCRASH(shadowInfo.m_ShadowName[0] != '\0', ("this should be validated in ThingTemplate now")); shadowInfo.m_type=(ShadowType)tTemplate->getShadowType(); shadowInfo.m_sizeX=tTemplate->getShadowSizeX(); @@ -1257,7 +1257,7 @@ AsciiString WbView3d::getModelNameAndScale(MapObject *pMapObj, Real *scale, Body if (strncmp(TEST_STRING, pMapObj->getName().str(), strlen(TEST_STRING)) == 0) { /* Handle test art models here */ - strcpy(buffer, pMapObj->getName().str()); + strlcpy(buffer, pMapObj->getName().str(), ARRAY_SIZE(buffer)); Int i; for (i=0; buffer[i]; i++) { @@ -1410,7 +1410,7 @@ void WbView3d::invalObjectInView(MapObject *pMapObjIn) const ThingTemplate *tTemplate = pMapObj->getThingTemplate(); if (tTemplate && tTemplate->getShadowType() != SHADOW_NONE && !(pMapObj->getFlags() & FLAG_DONT_RENDER)) { //add correct type of shadow - strcpy(shadowInfo.m_ShadowName,tTemplate->getShadowTextureName().str()); + strlcpy(shadowInfo.m_ShadowName, tTemplate->getShadowTextureName().str(), ARRAY_SIZE(shadowInfo.m_ShadowName)); DEBUG_ASSERTCRASH(shadowInfo.m_ShadowName[0] != '\0', ("this should be validated in ThingTemplate now")); shadowInfo.m_type=(ShadowType)tTemplate->getShadowType(); shadowInfo.m_sizeX=tTemplate->getShadowSizeX(); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/INI/INI.cpp b/GeneralsMD/Code/GameEngine/Source/Common/INI/INI.cpp index 35dff5e5ce..b1de518e71 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/INI/INI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/INI/INI.cpp @@ -411,7 +411,7 @@ UnsignedInt INI::load( AsciiString filename, INILoadType loadType, Xfer *pXfer ) if (parse) { #ifdef DEBUG_CRASHING - strcpy(m_curBlockStart, m_buffer); + strlcpy(m_curBlockStart, m_buffer, ARRAY_SIZE(m_curBlockStart)); #endif try { (*parse)( this ); @@ -768,7 +768,7 @@ AsciiString INI::getNextQuotedAsciiString() Bool done=FALSE; if ((strLen=strlen(token)) > 1) { - strcpy(buff, &token[1]); //skip the starting quote + strlcpy(buff, &token[1], ARRAY_SIZE(buff)); //skip the starting quote //Check for end of quoted string. Checking here fixes cases where quoted string on same line with other data. if (buff[strLen-2]=='"') //skip ending quote if present { buff[strLen-2]='\0'; @@ -817,7 +817,7 @@ AsciiString INI::getNextAsciiString() buff[0] = 0; if (strlen(token) > 1) { - strcpy(buff, &token[1]); + strlcpy(buff, &token[1], ARRAY_SIZE(buff)); } token = getNextTokenOrNull(getSepsQuote()); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/PerfTimer.cpp b/GeneralsMD/Code/GameEngine/Source/Common/PerfTimer.cpp index 1cd19f42e4..e18d2c8eab 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/PerfTimer.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/PerfTimer.cpp @@ -349,10 +349,10 @@ void PerfGather::reset() { PerfGather::termPerfDump(); - strcpy(s_buf, fname); + strlcpy(s_buf, fname, ARRAY_SIZE(s_buf); char tmp[256]; - strcpy(tmp, s_buf); + strlcpy(tmp, s_buf, ARRAY_SIZE(tmp)); strlcat(tmp, ".csv", ARRAY_SIZE(tmp)); s_perfStatsFile = fopen(tmp, "w"); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp index a803dff162..0795b273aa 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp @@ -1260,9 +1260,9 @@ WindowMsgHandledType WOLLoginMenuSystem( GameWindow *window, UnsignedInt msg, loginAttemptTime = timeGetTime(); BuddyRequest req; req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGINNEW; - strcpy(req.arg.login.nick, login.str()); - strcpy(req.arg.login.email, email.str()); - strcpy(req.arg.login.password, password.str()); + strlcpy(req.arg.login.nick, login.str(), ARRAY_SIZE(req.arg.login.nick)); + strlcpy(req.arg.login.email, email.str(), ARRAY_SIZE(req.arg.login.email)); + strlcpy(req.arg.login.password, password.str(), ARRAY_SIZE(req.arg.login.password)); req.arg.login.hasFirewall = TRUE; TheGameSpyInfo->setLocalBaseName( login ); @@ -1349,9 +1349,9 @@ WindowMsgHandledType WOLLoginMenuSystem( GameWindow *window, UnsignedInt msg, loginAttemptTime = timeGetTime(); BuddyRequest req; req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGIN; - strcpy(req.arg.login.nick, login.str()); - strcpy(req.arg.login.email, email.str()); - strcpy(req.arg.login.password, password.str()); + strlcpy(req.arg.login.nick, login.str(), ARRAY_SIZE(req.arg.login.nick)); + strlcpy(req.arg.login.email, email.str(), ARRAY_SIZE(req.arg.login.email)); + strlcpy(req.arg.login.password, password.str(), ARRAY_SIZE(req.arg.login.password)); req.arg.login.hasFirewall = true; TheGameSpyInfo->setLocalBaseName( login ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp index d771079b23..c7396019d2 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp @@ -232,7 +232,7 @@ static void parseBitString( const char *inBuffer, UnsignedInt *bits, ConstCharPt char *tok; // do not modify the inBuffer argument - strcpy( buffer, inBuffer ); + strlcpy(buffer, inBuffer, ARRAY_SIZE(buffer)); if( strncmp( buffer, "NULL", 4 ) ) { @@ -605,7 +605,7 @@ static Bool parseFont( const char *token, WinInstanceData *instData, ptr++; ptr++; // skip the " c = strtok( ptr, stringSeps ); // value - strcpy( fontName, c ); + strlcpy(fontName, c, ARRAY_SIZE(fontName)); // "SIZE" c = strtok( NULL, seps ); // label @@ -1649,7 +1649,7 @@ static GameWindow *createGadget( char *type, // filename the radio button was saved in // - strcpy( filename, instData->m_decoratedNameString.str() ); + strlcpy(filename, instData->m_decoratedNameString.str(), ARRAY_SIZE(filename)); c = strchr( filename, ':' ); if( c ) *c = 0; // terminate after filename (format is filename:gadgetname) @@ -2373,7 +2373,7 @@ static GameWindow *parseWindow( File *inFile, char *buffer ) c = strtok( buffer, seps ); assert( strcmp( c, "WINDOWTYPE" ) == 0 ); c = strtok( NULL, seps ); // get data to right of = sign - strcpy( type, c ); + strlcpy(type, c, ARRAY_SIZE(type)); // // based on the window type get a pointer for any specific data @@ -2402,7 +2402,7 @@ static GameWindow *parseWindow( File *inFile, char *buffer ) if (asciibuf.compare(parse->name) == 0) { - strcpy( token, asciibuf.str() ); + strlcpy(token, asciibuf.str(), ARRAY_SIZE(token)); // eat '=' inFile->scanString(asciibuf); @@ -2618,7 +2618,7 @@ Bool parseLayoutBlock( File *inFile, char *buffer, UnsignedInt version, WindowLa // eat equals separator " = " c = strtok( buffer, " =" ); - strcpy(token, asciitoken.str()); + strlcpy(token, asciitoken.str(), ARRAY_SIZE(token)); // parse it if( parse->parse( token, c, version, info ) == FALSE ) @@ -2727,7 +2727,7 @@ GameWindow *GameWindowManager::winCreateFromScript( AsciiString filenameString, if( strchr( filename, '\\' ) == NULL ) sprintf( filepath, "Window\\%s", filename ); else - strcpy( filepath, filename ); + strlcpy(filepath, filename, ARRAY_SIZE(filepath)); // Open the input file inFile = TheFileSystem->openFile(filepath, File::READ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/RadiusDecal.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/RadiusDecal.cpp index ed003bf6e5..e6558f637b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/RadiusDecal.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/RadiusDecal.cpp @@ -73,7 +73,7 @@ void RadiusDecalTemplate::createRadiusDecal(const Coord3D& pos, Real radius, con decalInfo.allowUpdates = FALSE; // shadow texture will never update decalInfo.allowWorldAlign = TRUE; // shadow image will wrap around world objects decalInfo.m_type = m_shadowType; - strcpy(decalInfo.m_ShadowName, m_name.str()); // name of your texture + strlcpy(decalInfo.m_ShadowName, m_name.str(), ARRAY_SIZE(decalInfo.m_ShadowName)); // name of your texture decalInfo.m_sizeX = radius*2; // world space dimensions decalInfo.m_sizeY = radius*2; // world space dimensions diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 80f5586059..59e1c7e6d7 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -2466,17 +2466,17 @@ void GameLogic::loadMapINI( AsciiString mapName ) char filename[_MAX_PATH]; char fullFledgeFilename[_MAX_PATH]; - memset(filename, 0, _MAX_PATH); - strcpy(filename, mapName.str()); - // // if map name begins with a "SAVE_DIRECTORY\", then the map refers to a map // that has been extracted from a save game file ... in that case we need to get // the pristine map name string in order to manipulate and load the right map.ini // for that map from it's original location // - if (TheGameState->isInSaveDirectory(filename)) - strcpy( filename, TheGameState->getSaveGameInfo()->pristineMapName.str() ); + const char* pristineMapName = TheGameState->isInSaveDirectory(filename) + ? TheGameState->getSaveGameInfo()->pristineMapName.str() + : mapName.str(); + + strlcpy(filename, pristineMapName, ARRAY_SIZE(filename)); // sanity int length = strlen(filename); diff --git a/GeneralsMD/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp b/GeneralsMD/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp index e6125e0fa4..da36009076 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp @@ -558,9 +558,9 @@ void BuddyThreadClass::connectCallback( GPConnection *con, GPConnectResponseArg DEBUG_LOG(("User Error: Create Account instead of Login. Fixing them...")); BuddyRequest req; req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGIN; - strcpy(req.arg.login.nick, m_nick.c_str()); - strcpy(req.arg.login.email, m_email.c_str()); - strcpy(req.arg.login.password, m_pass.c_str()); + strlcpy(req.arg.login.nick, m_nick.c_str(), ARRAY_SIZE(req.arg.login.nick)); + strlcpy(req.arg.login.email, m_email.c_str(), ARRAY_SIZE(req.arg.login.email)); + strlcpy(req.arg.login.password, m_pass.c_str(), ARRAY_SIZE(req.arg.login.password)); req.arg.login.hasFirewall = true; TheGameSpyBuddyMessageQueue->addRequest( req ); return; diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp index 4c2f30d686..469b401b45 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp @@ -1859,7 +1859,7 @@ void W3DModelDraw::allocateShadows(void) if (m_shadow == NULL && m_renderObject && TheW3DShadowManager && tmplate->getShadowType() != SHADOW_NONE) { Shadow::ShadowTypeInfo shadowInfo; - strcpy(shadowInfo.m_ShadowName, tmplate->getShadowTextureName().str()); + strlcpy(shadowInfo.m_ShadowName, tmplate->getShadowTextureName().str(), ARRAY_SIZE(shadowInfo.m_ShadowName)); DEBUG_ASSERTCRASH(shadowInfo.m_ShadowName[0] != '\0', ("this should be validated in ThingTemplate now")); shadowInfo.allowUpdates = FALSE; //shadow image will never update shadowInfo.allowWorldAlign = TRUE; //shadow image will wrap around world objects @@ -2751,9 +2751,9 @@ void W3DModelDraw::setTerrainDecal(TerrainDecalType type) //decalInfo.m_type = SHADOW_ADDITIVE_DECAL;//temporary kluge to test graphics if (type == TERRAIN_DECAL_SHADOW_TEXTURE) - strcpy(decalInfo.m_ShadowName,tmplate->getShadowTextureName().str()); + strlcpy(decalInfo.m_ShadowName, tmplate->getShadowTextureName().str(), ARRAY_SIZE(decalInfo.m_ShadowName)); else - strcpy(decalInfo.m_ShadowName,TerrainDecalTextureName[type]); + strlcpy(decalInfo.m_ShadowName, TerrainDecalTextureName[type], ARRAY_SIZE(decalInfo.m_ShadowName)); decalInfo.m_sizeX = tmplate->getShadowSizeX(); decalInfo.m_sizeY = tmplate->getShadowSizeY(); decalInfo.m_offsetX = tmplate->getShadowOffsetX(); @@ -3069,7 +3069,7 @@ void W3DModelDraw::setModelState(const ModelConditionInfo* newState) if (m_renderObject && TheW3DShadowManager && tmplate->getShadowType() != SHADOW_NONE) { Shadow::ShadowTypeInfo shadowInfo; - strcpy(shadowInfo.m_ShadowName, tmplate->getShadowTextureName().str()); + strlcpy(shadowInfo.m_ShadowName, tmplate->getShadowTextureName().str(), ARRAY_SIZE(shadowInfo.m_ShadowName)); DEBUG_ASSERTCRASH(shadowInfo.m_ShadowName[0] != '\0', ("this should be validated in ThingTemplate now")); shadowInfo.allowUpdates = FALSE; //shadow image will never update shadowInfo.allowWorldAlign = TRUE; //shadow image will wrap around world objects @@ -3455,7 +3455,7 @@ Int W3DModelDraw::getPristineBonePositionsForConditionState( for (; i <= endIndex; ++i) { if (i == 0) - strcpy(buffer, boneNamePrefix); + strlcpy(buffer, boneNamePrefix, ARRAY_SIZE(buffer)); else sprintf(buffer, "%s%02d", boneNamePrefix, i); @@ -3612,7 +3612,7 @@ Int W3DModelDraw::getCurrentBonePositions( for (; i <= endIndex; ++i) { if (i == 0) - strcpy(buffer, boneNamePrefix); + strlcpy(buffer, boneNamePrefix, ARRAY_SIZE(buffer)); else sprintf(buffer, "%s%02d", boneNamePrefix, i); diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp index 3ca23283ca..7389c0c1f4 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp @@ -1485,7 +1485,8 @@ Shadow* W3DProjectedShadowManager::addDecal(Shadow::ShadowTypeInfo *shadowInfo) //simple decal using the premade texture specified. //can be always perpendicular to model's z-axis or projected //onto world geometry. - strlcpy(texture_name, shadowInfo->m_ShadowName, ARRAY_SIZE(texture_name)); + static_assert(ARRAY_SIZE(texture_name) >= ARRAY_SIZE(shadowInfo->m_ShadowName), "Incorrect array size"); + strcpy(texture_name, shadowInfo->m_ShadowName); strlcat(texture_name, ".tga", ARRAY_SIZE(texture_name)); //Check if we previously added a decal using this texture @@ -1589,7 +1590,8 @@ Shadow* W3DProjectedShadowManager::addDecal(RenderObjClass *robj, Shadow::Shadow //simple decal using the premade texture specified. //can be always perpendicular to model's z-axis or projected //onto world geometry. - strlcpy(texture_name, shadowInfo->m_ShadowName, ARRAY_SIZE(texture_name)); + static_assert(ARRAY_SIZE(texture_name) >= ARRAY_SIZE(shadowInfo->m_ShadowName), "Incorrect array size"); + strcpy(texture_name, shadowInfo->m_ShadowName); strlcat(texture_name, ".tga", ARRAY_SIZE(texture_name)); //Check if we previously added a decal using this texture @@ -1723,7 +1725,8 @@ W3DProjectedShadow* W3DProjectedShadowManager::addShadow(RenderObjClass *robj, S } else { - strlcpy(texture_name, shadowInfo->m_ShadowName, ARRAY_SIZE(texture_name)); + static_assert(ARRAY_SIZE(texture_name) >= ARRAY_SIZE(shadowInfo->m_ShadowName), "Incorrect array size"); + strcpy(texture_name, shadowInfo->m_ShadowName); strlcat(texture_name, ".tga", ARRAY_SIZE(texture_name)); } @@ -1764,10 +1767,11 @@ W3DProjectedShadow* W3DProjectedShadowManager::addShadow(RenderObjClass *robj, S //to allow multiple models to share same shadow - for //example, all trees could use same shadow even if slightly //different color, etc. - strcpy(texture_name,shadowInfo->m_ShadowName); + static_assert(ARRAY_SIZE(texture_name) >= ARRAY_SIZE(shadowInfo->m_ShadowName), "Incorrect array size"); + strcpy(texture_name, shadowInfo->m_ShadowName); } else - strcpy(texture_name,robj->Get_Name()); //not texture name give, assume model name. + strlcpy(texture_name, robj->Get_Name(), ARRAY_SIZE(texture_name)); //not texture name give, assume model name. st=m_W3DShadowTextureManager->getTexture(texture_name); if (st == NULL) @@ -1786,7 +1790,7 @@ W3DProjectedShadow* W3DProjectedShadowManager::addShadow(RenderObjClass *robj, S } else { //no shadow info, assume user wants a projected shadow - strcpy(texture_name,robj->Get_Name()); + strlcpy(texture_name, robj->Get_Name(), ARRAY_SIZE(texture_name)); st=m_W3DShadowTextureManager->getTexture(texture_name); @@ -1900,7 +1904,8 @@ W3DProjectedShadow* W3DProjectedShadowManager::createDecalShadow(Shadow::ShadowT } else { - strlcpy(texture_name, shadowInfo->m_ShadowName, ARRAY_SIZE(texture_name)); + static_assert(ARRAY_SIZE(texture_name) >= ARRAY_SIZE(shadowInfo->m_ShadowName), "Incorrect array size"); + strcpy(texture_name, shadowInfo->m_ShadowName); strlcat(texture_name, ".tga", ARRAY_SIZE(texture_name)); } diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp index b6d4111f7e..a27412e974 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp @@ -270,7 +270,7 @@ RenderObjClass * W3DAssetManager::Create_Render_Obj(const char* name) static inline void Munge_Render_Obj_Name(char *newname, const char *oldname, float scale, const int color, const char *textureName) { char lower_case_name[255]; - strcpy(lower_case_name, oldname); + strlcpy(lower_case_name, oldname, ARRAY_SIZE(lower_case_name)); _strlwr(lower_case_name); if (!textureName) @@ -283,7 +283,7 @@ static inline void Munge_Render_Obj_Name(char *newname, const char *oldname, flo static inline void Munge_Texture_Name(char *newname, const char *oldname, const int color) { char lower_case_name[255]; - strcpy(lower_case_name, oldname); + strlcpy(lower_case_name, oldname, ARRAY_SIZE(lower_case_name)); _strlwr(lower_case_name); sprintf(newname,"#%d#%s", color, lower_case_name); } @@ -975,7 +975,7 @@ bool W3DAssetManager::Load_3D_Assets( const char * filename ) // Try to find an existing prototype char basename[512]; - strcpy(basename, filename); + strlcpy(basename, filename, ARRAY_SIZE(basename)); char *pext = strrchr(basename, '.'); //find file extension if (pext) *pext = '\0'; //drop the extension @@ -1314,7 +1314,7 @@ void W3DAssetManager::Make_Unique(RenderObjClass *robj, Bool geometry, Bool colo static inline void Munge_Render_Obj_Name(char *newname, const char *oldname, float scale, const Vector3 &hsv_shift) { char lower_case_name[255]; - strcpy(lower_case_name, oldname); + strlcpy(lower_case_name, oldname, ARRAY_SIZE(lower_case_name)); _strlwr(lower_case_name); sprintf(newname,"#%s!%gH%gS%gV%g", lower_case_name, scale, hsv_shift.X, hsv_shift.Y, hsv_shift.Z); } @@ -1322,7 +1322,7 @@ static inline void Munge_Render_Obj_Name(char *newname, const char *oldname, flo static inline void Munge_Texture_Name(char *newname, const char *oldname, const Vector3 &hsv_shift) { char lower_case_name[255]; - strcpy(lower_case_name, oldname); + strlcpy(lower_case_name, oldname, ARRAY_SIZE(lower_case_name)); _strlwr(lower_case_name); sprintf(newname,"#%s!H%gS%gV%g", lower_case_name, hsv_shift.X, hsv_shift.Y, hsv_shift.Z); } @@ -1345,7 +1345,7 @@ RenderObjClass * W3DAssetManager::Create_Render_Obj(const char * name,float scal if (isGranny) { //Granny objects share the same prototype since they allow instance scaling. - strcpy(newname,name); //use same name for all granny objects at any scale. + strlcpy(newname, name, ARRAY_SIZE(newname)); //use same name for all granny objects at any scale. } Set_WW3D_Load_On_Demand(false); // munged name will never be found in a file. rendobj=WW3DAssetManager::Create_Render_Obj(newname); @@ -1451,7 +1451,7 @@ TextureClass * W3DAssetManager::Get_Texture_With_HSV_Shift(const char * filename // No cached texture - need to create char lower_case_name[255]; - strcpy(lower_case_name, filename); + strlcpy(lower_case_name, filename, ARRAY_SIZE(lower_case_name)); _strlwr(lower_case_name); TextureClass *oldtex = TextureHash.Get(lower_case_name); if (!oldtex) { diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp index 404d0f7196..655f5e484d 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DBridgeBuffer.cpp @@ -212,20 +212,20 @@ Bool W3DBridge::load(BodyDamageType curDamageState) default: return false; case BODY_PRISTINE: - strcpy( textureFile, bridge->getTexture().str() ); - strcpy( modelName, bridge->getBridgeModel().str() ); + strlcpy(textureFile, bridge->getTexture().str(), ARRAY_SIZE(textureFile)); + strlcpy(modelName, bridge->getBridgeModel().str(), ARRAY_SIZE(modelName)); break; case BODY_DAMAGED: - strcpy( textureFile, bridge->getTextureDamaged().str() ); - strcpy( modelName, bridge->getBridgeModelNameDamaged().str() ); + strlcpy(textureFile, bridge->getTextureDamaged().str(), ARRAY_SIZE(textureFile)); + strlcpy(modelName, bridge->getBridgeModelNameDamaged().str(), ARRAY_SIZE(modelName)); break; case BODY_REALLYDAMAGED: - strcpy( textureFile, bridge->getTextureReallyDamaged().str() ); - strcpy( modelName, bridge->getBridgeModelNameReallyDamaged().str() ); + strlcpy(textureFile, bridge->getTextureReallyDamaged().str(), ARRAY_SIZE(textureFile)); + strlcpy(modelName, bridge->getBridgeModelNameReallyDamaged().str(), ARRAY_SIZE(modelName)); break; case BODY_RUBBLE: - strcpy( textureFile, bridge->getTextureBroken().str() ); - strcpy( modelName, bridge->getBridgeModelNameBroken().str() ); + strlcpy(textureFile, bridge->getTextureBroken().str(), ARRAY_SIZE(textureFile)); + strlcpy(modelName, bridge->getBridgeModelNameBroken().str(), ARRAY_SIZE(modelName)); break; } @@ -234,6 +234,9 @@ Bool W3DBridge::load(BodyDamageType curDamageState) char section[_MAX_PATH]; char right[_MAX_PATH]; + static_assert(ARRAY_SIZE(left) >= ARRAY_SIZE(modelName), "Incorrect array size"); + static_assert(ARRAY_SIZE(section) >= ARRAY_SIZE(modelName), "Incorrect array size"); + static_assert(ARRAY_SIZE(right) >= ARRAY_SIZE(modelName), "Incorrect array size"); strcpy(left, modelName); strlcat(left, ".BRIDGE_LEFT", ARRAY_SIZE(left)); strcpy(section, modelName); @@ -254,15 +257,15 @@ Bool W3DBridge::load(BodyDamageType curDamageState) Matrix3D mtx = pSub->Get_Transform(); if (0==strnicmp(left, pSub->Get_Name(), strlen(left))) { m_leftMtx = mtx; - strcpy(left, pSub->Get_Name()); + strlcpy(left, pSub->Get_Name(), ARRAY_SIZE(left)); } if (0==strnicmp(section, pSub->Get_Name(), strlen(section))) { m_sectionMtx = mtx; - strcpy(section, pSub->Get_Name()); + strlcpy(section, pSub->Get_Name(), ARRAY_SIZE(section)); } if (0==strnicmp(right, pSub->Get_Name(), strlen(right))) { m_rightMtx = mtx; - strcpy(right, pSub->Get_Name()); + strlcpy(right, pSub->Get_Name(), ARRAY_SIZE(right)); } REF_PTR_RELEASE(pSub); //DEBUG_LOG(("Sub obj name %s", pSub->Get_Name())); diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index 32a9be834f..91ddfa9d84 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -3012,7 +3012,7 @@ void W3DDisplay::takeScreenShot(void) #else sprintf( leafname, "%s%.3d.bmp", "sshot", frame_number++); #endif - strcpy(pathname, TheGlobalData->getPath_UserData().str()); + strlcpy(pathname, TheGlobalData->getPath_UserData().str(), ARRAY_SIZE(pathname)); strlcat(pathname, leafname, ARRAY_SIZE(pathname)); if (_access( pathname, 0 ) == -1) done = true; diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DFileSystem.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DFileSystem.cpp index b54300961a..054cc27966 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DFileSystem.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DFileSystem.cpp @@ -211,7 +211,7 @@ char const * GameFileClass::Set_Name( char const *filename ) } else - strcpy( m_filePath, filename ); + strlcpy(m_filePath, filename, ARRAY_SIZE(m_filePath)); // see if the file exists m_fileExists = TheFileSystem->doesFileExist( m_filePath ); diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp index 98c2556fbf..964eb896ac 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp @@ -960,10 +960,8 @@ void WaterTracksRenderSystem::saveTracks(void) AsciiString fileName=TheTerrainLogic->getSourceFilename(); char path[256]; - strcpy(path,fileName.str()); - Int len=strlen(path); - - strcpy(path+len-4,".wak"); + strlcpy(path, fileName.str(), ARRAY_SIZE(path)); + strlcat(path, ".wak", ARRAY_SIZE(path)); WaterTracksObj *umod; Int trackCount=0; @@ -998,10 +996,8 @@ void WaterTracksRenderSystem::loadTracks(void) AsciiString fileName=TheTerrainLogic->getSourceFilename(); char path[256]; - strcpy(path,fileName.str()); - Int len=strlen(path); - - strcpy(path+len-4,".wak"); + strlcpy(path, fileName.str(), ARRAY_SIZE(path)); + strlcat(path, ".wak", ARRAY_SIZE(path)); File *file = TheFileSystem->openFile(path, File::READ | File::BINARY); WaterTracksObj *umod; diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/hmorphanim.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/hmorphanim.cpp index 03477b880d..488bb4e72a 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/hmorphanim.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/hmorphanim.cpp @@ -475,7 +475,7 @@ void HMorphAnimClass::Set_Name(const char * name) // // Copy the full name // - ::strcpy (Name, name); + strlcpy(Name, name, ARRAY_SIZE(Name)); // // Try to find the separator (a period) @@ -489,8 +489,8 @@ void HMorphAnimClass::Set_Name(const char * name) // into our two buffers // separator[0] = 0; - ::strcpy (AnimName, separator + 1); - ::strcpy (HierarchyName, full_name); + strlcpy(AnimName, separator + 1, ARRAY_SIZE(AnimName)); + strlcpy(HierarchyName, full_name, ARRAY_SIZE(HierarchyName)); } return ; @@ -548,9 +548,12 @@ int HMorphAnimClass::Load_W3D(ChunkLoadClass & cload) cload.Read(&header,sizeof(header)); cload.Close_Chunk(); - strlcpy(AnimName,header.Name,sizeof(AnimName)); - strlcpy(HierarchyName,header.HierarchyName,sizeof(HierarchyName)); - strcpy(Name,HierarchyName); + static_assert(ARRAY_SIZE(AnimName) >= ARRAY_SIZE(header.Name), "Incorrect array size"); + static_assert(ARRAY_SIZE(HierarchyName) >= ARRAY_SIZE(header.HierarchyName), "Incorrect array size"); + static_assert(ARRAY_SIZE(Name) >= ARRAY_SIZE(HierarchyName), "Incorrect array size"); + strcpy(AnimName, header.Name); + strcpy(HierarchyName, header.HierarchyName); + strcpy(Name, HierarchyName); strlcat(Name, ".", ARRAY_SIZE(Name)); strlcat(Name, AnimName, ARRAY_SIZE(Name)); diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/hrawanim.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/hrawanim.cpp index 790abf043a..2a76881dd3 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/hrawanim.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/hrawanim.cpp @@ -211,7 +211,7 @@ int HRawAnimClass::Load_W3D(ChunkLoadClass & cload) pre30 = true; } - strcpy(Name,aheader.HierarchyName); + strlcpy(Name, aheader.HierarchyName, ARRAY_SIZE(Name)); strlcat(Name, ".", ARRAY_SIZE(Name)); strlcat(Name, aheader.Name, ARRAY_SIZE(Name)); diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/nullrobj.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/nullrobj.cpp index 8fbc5e9e97..68fe079e74 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/nullrobj.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/nullrobj.cpp @@ -45,7 +45,7 @@ NullLoaderClass _NullLoader; Null3DObjClass::Null3DObjClass(const char * name) { - strcpy(Name, name); + strlcpy(Name, name, ARRAY_SIZE(Name)); } Null3DObjClass::Null3DObjClass(const Null3DObjClass & src) diff --git a/GeneralsMD/Code/Tools/GUIEdit/Include/LayoutScheme.h b/GeneralsMD/Code/Tools/GUIEdit/Include/LayoutScheme.h index dbbe51d888..747c588de0 100644 --- a/GeneralsMD/Code/Tools/GUIEdit/Include/LayoutScheme.h +++ b/GeneralsMD/Code/Tools/GUIEdit/Include/LayoutScheme.h @@ -124,7 +124,7 @@ class LayoutScheme // INLINING /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// inline char *LayoutScheme::getSchemeFilename( void ) { return m_schemeFilename; } -inline void LayoutScheme::setSchemeFilename( char *filename ) { strcpy( m_schemeFilename, filename ); } +inline void LayoutScheme::setSchemeFilename( char *filename ) { strlcpy(m_schemeFilename, filename, ARRAY_SIZE(m_schemeFilename)); } inline Color LayoutScheme::getEnabledTextColor( void ) { return m_enabledText.color; } inline Color LayoutScheme::getEnabledTextBorderColor( void ) { return m_enabledText.borderColor; } inline Color LayoutScheme::getDisabledTextColor( void ) { return m_disabledText.color; } diff --git a/GeneralsMD/Code/Tools/GUIEdit/Source/GUIEdit.cpp b/GeneralsMD/Code/Tools/GUIEdit/Source/GUIEdit.cpp index 99e40f1f48..401e29e834 100644 --- a/GeneralsMD/Code/Tools/GUIEdit/Source/GUIEdit.cpp +++ b/GeneralsMD/Code/Tools/GUIEdit/Source/GUIEdit.cpp @@ -251,14 +251,14 @@ void GUIEdit::setSaveFile( const char *fullPathAndFilename ) const char *ptr; // copy over the full path and filename - strcpy( m_savePathAndFilename, fullPathAndFilename ); + strlcpy(m_savePathAndFilename, fullPathAndFilename, ARRAY_SIZE(m_savePathAndFilename)); // // copy everything after the last '\' from the full path, this will // be just the filename with extension // ptr = strrchr( fullPathAndFilename, '\\' ) + 1; - strcpy( m_saveFilename, ptr ); + strlcpy(m_saveFilename, ptr, ARRAY_SIZE(m_saveFilename)); } diff --git a/GeneralsMD/Code/Tools/GUIEdit/Source/GUIEditWindowManager.cpp b/GeneralsMD/Code/Tools/GUIEdit/Source/GUIEditWindowManager.cpp index dbed4df9f2..efc03f6691 100644 --- a/GeneralsMD/Code/Tools/GUIEdit/Source/GUIEditWindowManager.cpp +++ b/GeneralsMD/Code/Tools/GUIEdit/Source/GUIEditWindowManager.cpp @@ -501,7 +501,7 @@ void GUIEditWindowManager::incrementName( GameWindow *window ) // this I will botch it (cuz I'm currently not sure // how to test it) char name[MAX_WINDOW_NAME_LEN]; - strcpy(name, instData->m_decoratedNameString.str()); + strlcpy(name, instData->m_decoratedNameString.str(), ARRAY_SIZE(name)); Int len = strlen( name ); char numberBuffer[ MAX_WINDOW_NAME_LEN ]; diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/BlendMaterial.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/BlendMaterial.cpp index 3cd3f55681..6dc85eadc1 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/BlendMaterial.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/BlendMaterial.cpp @@ -191,15 +191,15 @@ void BlendMaterial::addTerrain(const char *pPath, Int terrainNdx, HTREEITEM pare } // set the name in the tree view to that of the entry - strcpy( buffer, terrain->getName().str() ); + strlcpy(buffer, terrain->getName().str(), ARRAY_SIZE(buffer)); doAdd = TRUE; } else if (terrainNdx==-1) { - strcpy(buffer, pPath); + strlcpy(buffer, pPath, ARRAY_SIZE(buffer)); doAdd = true; } else if (WorldHeightMapEdit::getTexClassIsBlendEdge(terrainNdx)) { parent = findOrAdd( parent, "**EVAL**" ); - strcpy(buffer, pPath); + strlcpy(buffer, pPath, ARRAY_SIZE(buffer)); doAdd = true; } diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp index 965ad627e5..a21de4cd64 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp @@ -94,7 +94,7 @@ BOOL MeshMoldOptions::OnInitDialog() int len = filename.getLength(); if (len<5) continue; - strcpy(fileBuf, filename.str()); + strlcpy(fileBuf, filename.str(), ARRAY_SIZE(fileBuf)); for (i=strlen(fileBuf)-1; i>0; i--) { if (fileBuf[i] == '.') { // strip off .w3d file extension. diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp index af43ef583b..480ede7b2e 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp @@ -265,6 +265,7 @@ BOOL PickUnitDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) m_objectTreeView.GetItem(&item); if (item.lParam >= 0) { m_currentObjectIndex = item.lParam; + static_assert(ARRAY_SIZE(m_currentObjectName) >= ARRAY_SIZE(buffer), "Incorrect array size"); strcpy(m_currentObjectName, buffer); } else if (m_objectTreeView.ItemHasChildren(item.hItem)) { strcpy(m_currentObjectName, ""); diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/RoadOptions.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/RoadOptions.cpp index e3c98a434c..d1c31678f0 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/RoadOptions.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/RoadOptions.cpp @@ -242,18 +242,10 @@ BOOL RoadOptions::OnInitDialog() // load roads from test assets #ifdef LOAD_TEST_ASSETS { - char dirBuf[_MAX_PATH]; - char findBuf[_MAX_PATH]; char fileBuf[_MAX_PATH]; - static_assert(ARRAY_SIZE(dirBuf) >= ARRAY_SIZE(ROAD_DIRECTORY), "Incorrect array size"); - strcpy(dirBuf, ROAD_DIRECTORY); - int len = strlen(dirBuf); - - strcpy(findBuf, dirBuf); - FilenameList filenameList; - TheFileSystem->getFileListInDirectory(AsciiString(findBuf), AsciiString("*.tga"), filenameList, FALSE); + TheFileSystem->getFileListInDirectory(ROAD_DIRECTORY, "*.tga", filenameList, FALSE); if (filenameList.size() > 0) { FilenameList::iterator it = filenameList.begin(); @@ -264,7 +256,7 @@ BOOL RoadOptions::OnInitDialog() ++it; continue; } - len = filename.getLength(); + int len = filename.getLength(); if (len<5) { ++it; continue; @@ -389,7 +381,7 @@ void RoadOptions::addRoad(char *pPath, Int terrainNdx, HTREEITEM parent) parent = findOrAdd( parent, "Roads" ); // set the name to place as the name of the road entry in INI - strcpy( buffer, road->getName().str() ); + strlcpy(buffer, road->getName().str(), ARRAY_SIZE(buffer)); // do the add doAdd = TRUE; @@ -399,7 +391,7 @@ void RoadOptions::addRoad(char *pPath, Int terrainNdx, HTREEITEM parent) #ifdef LOAD_TEST_ASSETS if (!doAdd && !strncmp(TEST_STRING, pPath, strlen(TEST_STRING))) { parent = findOrAdd(parent, TEST_STRING); - strcpy(buffer, pPath + strlen(TEST_STRING) + 1); + strlcpy(buffer, pPath + strlen(TEST_STRING) + 1, ARRAY_SIZE(buffer)); doAdd = true; } #endif diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp index b8d347083a..cf5c6d77a8 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp @@ -86,7 +86,7 @@ BOOL SelectMacrotexture::OnInitDialog() AsciiString filename = *it; int len = filename.getLength(); if (len<5) continue; - strcpy(fileBuf, filename.str()); + strlcpy(fileBuf, filename.str(), ARRAY_SIZE(fileBuf)); ::memset(&ins, 0, sizeof(ins)); ins.hParent = TVI_ROOT; ins.hInsertAfter = TVI_SORT; diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp index 6d356be196..1d2c46b312 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp @@ -302,7 +302,7 @@ void TerrainMaterial::addTerrain(char *pPath, Int terrainNdx, HTREEITEM parent) } // set the name in the tree view to that of the entry - strcpy( buffer, terrain->getName().str() ); + strlcpy(buffer, terrain->getName().str(), ARRAY_SIZE(buffer)); doAdd = TRUE; } diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/TerrainModal.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/TerrainModal.cpp index 17afe7ba5e..ad41eebdd3 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/TerrainModal.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/TerrainModal.cpp @@ -172,7 +172,7 @@ void TerrainModal::addTerrain(char *pPath, Int terrainNdx, HTREEITEM parent) } - strcpy( buffer, terrain->getName().str() ); + strlcpy(buffer, terrain->getName().str(), ARRAY_SIZE(buffer)); doAdd = TRUE; diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilder.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilder.cpp index 3eaf249a1c..d4459af550 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilder.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilder.cpp @@ -125,7 +125,7 @@ char const * WBGameFileClass::Set_Name( char const *filename ) } if (TheFileSystem->doesFileExist(filename)) { - strcpy( m_filePath, filename ); + strlcpy(m_filePath, filename, ARRAY_SIZE(m_filePath)); m_fileExists = true; } return m_filename; @@ -360,7 +360,7 @@ BOOL CWorldBuilderApp::InitInstance() #if 1 // srj sez: put INI into our user data folder, not the ap dir free((void*)m_pszProfileName); - strcpy(buf, TheGlobalData->getPath_UserData().str()); + strlcpy(buf, TheGlobalData->getPath_UserData().str(), ARRAY_SIZE(buf)); strlcat(buf, "WorldBuilder.ini", ARRAY_SIZE(buf)); #else strlcat(buf, "//", ARRAY_SIZE(buf)); diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp index 24442484d8..4db400158f 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp @@ -2155,16 +2155,13 @@ void CWorldBuilderDoc::OnDumpDocToText(void) static FILE *theLogFile = NULL; Bool open = false; try { - char dirbuf[ _MAX_PATH ]; - ::GetModuleFileName( NULL, dirbuf, sizeof( dirbuf ) ); - if (char *pEnd = strrchr(dirbuf, '\\')) + char curbuf[_MAX_PATH]; + GetModuleFileName(NULL, curbuf, sizeof(curbuf)); + if (char *pEnd = strrchr(curbuf, '\\')) { *(pEnd + 1) = 0; } - char curbuf[ _MAX_PATH ]; - - strcpy(curbuf, dirbuf); strlcat(curbuf, m_strTitle, ARRAY_SIZE(curbuf)); strlcat(curbuf, ".txt", ARRAY_SIZE(curbuf)); diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/mapobjectprops.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/mapobjectprops.cpp index b47b83f46f..a0d7487fbe 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/mapobjectprops.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/mapobjectprops.cpp @@ -266,7 +266,7 @@ void MapObjectProps::_TeamToDict(void) static char buf[1024]; owner->GetWindowText(buf, sizeof(buf)-2); if (strcmp(buf, NEUTRAL_TEAM_UI_STR)==0) - strcpy(buf, NEUTRAL_TEAM_INTERNAL_STR); + strlcpy(buf, NEUTRAL_TEAM_INTERNAL_STR, ARRAY_SIZE(buf)); CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc(); if ( pDoc ) diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/playerlistdlg.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/playerlistdlg.cpp index 1c8d56fdf5..d9125debeb 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/playerlistdlg.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/playerlistdlg.cpp @@ -87,7 +87,7 @@ static void ensureValidPlayerName(Dict *d) { // ensure there are no illegal chars in it. (in particular, no spaces!) char buf[1024]; - strcpy(buf, d->getAsciiString(TheKey_playerName).str()); + strlcpy(buf, d->getAsciiString(TheKey_playerName).str(), ARRAY_SIZE(buf)); for (char* p = buf; *p; ++p) if (!islegalplayernamechar(*p)) *p = '_'; diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp index 2cfa7e5fcd..b499c5be1e 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp @@ -1196,7 +1196,7 @@ void WbView3d::invalBuildListItemInView(BuildListInfo *pBuildToInval) Shadow::ShadowTypeInfo shadowInfo; shadowInfo.allowUpdates=FALSE; //shadow image will never update shadowInfo.allowWorldAlign=TRUE; //shadow image will wrap around world objects - strcpy(shadowInfo.m_ShadowName,tTemplate->getShadowTextureName().str()); + strlcpy(shadowInfo.m_ShadowName, tTemplate->getShadowTextureName().str(), ARRAY_SIZE(shadowInfo.m_ShadowName)); DEBUG_ASSERTCRASH(shadowInfo.m_ShadowName[0] != '\0', ("this should be validated in ThingTemplate now")); shadowInfo.m_type=(ShadowType)tTemplate->getShadowType(); shadowInfo.m_sizeX=tTemplate->getShadowSizeX(); @@ -1313,7 +1313,7 @@ AsciiString WbView3d::getModelNameAndScale(MapObject *pMapObj, Real *scale, Body if (strncmp(TEST_STRING, pMapObj->getName().str(), strlen(TEST_STRING)) == 0) { /* Handle test art models here */ - strcpy(buffer, pMapObj->getName().str()); + strlcpy(buffer, pMapObj->getName().str(), ARRAY_SIZE(buffer)); Int i; for (i=0; buffer[i]; i++) { @@ -1474,7 +1474,7 @@ void WbView3d::invalObjectInView(MapObject *pMapObjIn) shadowInfo.allowWorldAlign=TRUE; //shadow image will wrap around world objects if (tTemplate && tTemplate->getShadowType() != SHADOW_NONE && !(pMapObj->getFlags() & FLAG_DONT_RENDER)) { //add correct type of shadow - strcpy(shadowInfo.m_ShadowName,tTemplate->getShadowTextureName().str()); + strlcpy(shadowInfo.m_ShadowName, tTemplate->getShadowTextureName().str(), ARRAY_SIZE(shadowInfo.m_ShadowName)); DEBUG_ASSERTCRASH(shadowInfo.m_ShadowName[0] != '\0', ("this should be validated in ThingTemplate now")); shadowInfo.m_type=(ShadowType)tTemplate->getShadowType(); shadowInfo.m_sizeX=tTemplate->getShadowSizeX();