[HL25] Backport safer strings operations

One exception where Updated's existing work has been kept is in
CHudTextMessage::LocaliseTextString.

See those commits for details:
- d2da2f17fd
- a3aeea468f
This commit is contained in:
Joël Troch 2024-08-27 23:57:48 +02:00
parent 246c1d575e
commit 91ea9ed318
14 changed files with 46 additions and 24 deletions

View file

@ -643,7 +643,8 @@ bool CHudAmmo::MsgFunc_WeaponList(const char* pszName, int iSize, void* pbuf)
WEAPON Weapon; WEAPON Weapon;
strcpy(Weapon.szName, READ_STRING()); strncpy(Weapon.szName, READ_STRING(), MAX_WEAPON_NAME);
Weapon.szName[sizeof(Weapon.szName) - 1] = '\0';
Weapon.iAmmoType = (int)READ_CHAR(); Weapon.iAmmoType = (int)READ_CHAR();
Weapon.iMax1 = READ_BYTE(); Weapon.iMax1 = READ_BYTE();

View file

@ -209,7 +209,8 @@ void UTIL_StringToVector(float* pVector, const char* pString)
char *pstr, *pfront, tempString[128]; char *pstr, *pfront, tempString[128];
int j; int j;
strcpy(tempString, pString); strncpy(tempString, pString, sizeof(tempString));
tempString[sizeof(tempString) - 1] = '\0';
pstr = pfront = tempString; pstr = pfront = tempString;
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)

View file

@ -711,7 +711,7 @@ void IN_StartupJoystick()
// mark the joystick as available and advanced initialization not completed // mark the joystick as available and advanced initialization not completed
// this is needed as cvars are not available during initialization // this is needed as cvars are not available during initialization
gEngfuncs.Con_Printf("joystick found\n\n", SDL_GameControllerName(s_pJoystick)); gEngfuncs.Con_Printf("joystick found %s\n\n", SDL_GameControllerName(s_pJoystick));
joy_avail = true; joy_avail = true;
joy_advancedinit = false; joy_advancedinit = false;
break; break;

View file

@ -285,7 +285,7 @@ void CHudMessage::MessageDrawScan(client_textmessage_t* pMessage, float time)
{ {
m_parms.lineLength = 0; m_parms.lineLength = 0;
m_parms.width = 0; m_parms.width = 0;
while ('\0' != *pText && *pText != '\n') while ('\0' != *pText && *pText != '\n' && m_parms.lineLength < ARRAYSIZE(line) - 1)
{ {
unsigned char c = *pText; unsigned char c = *pText;
line[m_parms.lineLength] = c; line[m_parms.lineLength] = c;

View file

@ -223,7 +223,7 @@ bool CHudTextMessage::MsgFunc_TextMsg(const char* pszName, int iSize, void* pbuf
case HUD_PRINTNOTIFY: case HUD_PRINTNOTIFY:
psz[0] = 1; // mark this message to go into the notify buffer psz[0] = 1; // mark this message to go into the notify buffer
safe_sprintf(psz + 1, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4); safe_sprintf(psz + 1, MSG_BUF_SIZE - 1, msg_text, sstr1, sstr2, sstr3, sstr4);
ConsolePrint(ConvertCRtoNL(psz)); ConsolePrint(ConvertCRtoNL(psz));
break; break;

View file

@ -604,6 +604,13 @@ void ClientCommand(edict_t* pEntity)
// max total length is 192 ...and we're adding a string below ("Unknown command: %s\n") // max total length is 192 ...and we're adding a string below ("Unknown command: %s\n")
strncpy(command, pcmd, 127); strncpy(command, pcmd, 127);
command[127] = '\0'; command[127] = '\0';
// First parse the name and remove any %'s
for (char* pApersand = command; pApersand != NULL && *pApersand != 0; pApersand++)
{
// Replace it with a space
if (*pApersand == '%')
*pApersand = ' ';
}
// tell the user they entered an unknown command // tell the user they entered an unknown command
ClientPrint(&pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs("Unknown command: %s\n", command)); ClientPrint(&pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs("Unknown command: %s\n", command));

View file

@ -808,7 +808,7 @@ bool CGamePlayerEquip::KeyValue(KeyValueData* pkvd)
{ {
char tmp[128]; char tmp[128];
UTIL_StripToken(pkvd->szKeyName, tmp); UTIL_StripToken(pkvd->szKeyName, tmp, sizeof(tmp));
m_weaponNames[i] = ALLOC_STRING(tmp); m_weaponNames[i] = ALLOC_STRING(tmp);
m_weaponCount[i] = atoi(pkvd->szValue); m_weaponCount[i] = atoi(pkvd->szValue);

View file

@ -1263,7 +1263,8 @@ bool ReloadMapCycleFile(char* filename, mapcycle_t* cycle)
if (strlen(com_token) <= 0) if (strlen(com_token) <= 0)
break; break;
strcpy(szMap, com_token); strncpy(szMap, com_token, sizeof(szMap));
szMap[sizeof(szMap) - 1] = '\0';
// Any more tokens on this line? // Any more tokens on this line?
if (COM_TokenWaiting(pFileList)) if (COM_TokenWaiting(pFileList))
@ -1272,7 +1273,8 @@ bool ReloadMapCycleFile(char* filename, mapcycle_t* cycle)
if (strlen(com_token) > 0) if (strlen(com_token) > 0)
{ {
hasbuffer = true; hasbuffer = true;
strcpy(szBuffer, com_token); strncpy(szBuffer, com_token, sizeof(szBuffer));
szBuffer[sizeof(szBuffer) - 1] = '\0';
} }
} }

View file

@ -329,7 +329,7 @@ bool CMultiManager::KeyValue(KeyValueData* pkvd)
{ {
char tmp[128]; char tmp[128];
UTIL_StripToken(pkvd->szKeyName, tmp); UTIL_StripToken(pkvd->szKeyName, tmp, sizeof(tmp));
m_iTargetName[m_cTargets] = ALLOC_STRING(tmp); m_iTargetName[m_cTargets] = ALLOC_STRING(tmp);
m_flTargetDelay[m_cTargets] = atof(pkvd->szValue); m_flTargetDelay[m_cTargets] = atof(pkvd->szValue);
m_cTargets++; m_cTargets++;

View file

@ -1403,7 +1403,8 @@ void UTIL_StringToVector(float* pVector, const char* pString)
char *pstr, *pfront, tempString[128]; char *pstr, *pfront, tempString[128];
int j; int j;
strcpy(tempString, pString); strncpy(tempString, pString, sizeof(tempString));
tempString[sizeof(tempString) - 1] = '\0';
pstr = pfront = tempString; pstr = pfront = tempString;
for (j = 0; j < 3; j++) // lifted from pr_edict.c for (j = 0; j < 3; j++) // lifted from pr_edict.c
@ -1434,7 +1435,8 @@ void UTIL_StringToIntArray(int* pVector, int count, const char* pString)
char *pstr, *pfront, tempString[128]; char *pstr, *pfront, tempString[128];
int j; int j;
strcpy(tempString, pString); strncpy(tempString, pString, sizeof(tempString));
tempString[sizeof(tempString) - 1] = '\0';
pstr = pfront = tempString; pstr = pfront = tempString;
for (j = 0; j < count; j++) // lifted from pr_edict.c for (j = 0; j < count; j++) // lifted from pr_edict.c
@ -1642,11 +1644,11 @@ float UTIL_DotPoints(const Vector& vecSrc, const Vector& vecCheck, const Vector&
//========================================================= //=========================================================
// UTIL_StripToken - for redundant keynames // UTIL_StripToken - for redundant keynames
//========================================================= //=========================================================
void UTIL_StripToken(const char* pKey, char* pDest) void UTIL_StripToken(const char* pKey, char* pDest, int nLen)
{ {
int i = 0; int i = 0;
while ('\0' != pKey[i] && pKey[i] != '#') while (i < nLen - 1 && '\0' != pKey[i] && pKey[i] != '#')
{ {
pDest[i] = pKey[i]; pDest[i] = pKey[i];
i++; i++;

View file

@ -369,7 +369,7 @@ extern void UTIL_LogPrintf(const char* fmt, ...);
// Sorta like FInViewCone, but for nonmonsters. // Sorta like FInViewCone, but for nonmonsters.
extern float UTIL_DotPoints(const Vector& vecSrc, const Vector& vecCheck, const Vector& vecDir); extern float UTIL_DotPoints(const Vector& vecSrc, const Vector& vecCheck, const Vector& vecDir);
extern void UTIL_StripToken(const char* pKey, char* pDest); // for redundant keynames extern void UTIL_StripToken(const char* pKey, char* pDest, int nLen); // for redundant keynames
// Misc functions // Misc functions
extern void SetMovedir(entvars_t* pev); extern void SetMovedir(entvars_t* pev);

View file

@ -364,7 +364,8 @@ void BotProfileManager::Init( const char *filename, unsigned int *checksum )
// found attribute name - keep it // found attribute name - keep it
char attributeName[64]; char attributeName[64];
strcpy( attributeName, token ); strncpy( attributeName, token, sizeof( attributeName ) - 1 );
attributeName[ sizeof( attributeName ) - 1 ] = '\0';
// eat '=' // eat '='
dataFile = SharedParse( dataFile ); dataFile = SharedParse( dataFile );

View file

@ -154,6 +154,7 @@ public:
{ {
file->Read( &len, sizeof(unsigned short) ); file->Read( &len, sizeof(unsigned short) );
file->Read( placeName, len ); file->Read( placeName, len );
placeName[ sizeof( placeName ) - 1 ] = '\0';
AddPlace( TheBotPhrases->NameToID( placeName ) ); AddPlace( TheBotPhrases->NameToID( placeName ) );
} }

View file

@ -203,7 +203,7 @@ skipwhite:
if (c == s_shared_quote) if (c == s_shared_quote)
{ {
data++; data++;
while (1) while (len < sizeof( s_shared_token ) - 1))
{ {
c = *data++; c = *data++;
if (c==s_shared_quote || !c) if (c==s_shared_quote || !c)
@ -217,24 +217,31 @@ skipwhite:
} }
// parse single characters // parse single characters
if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c == ',' ) if (len < sizeof( s_shared_token ) - 1)
{ {
s_shared_token[len] = c; if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c == ',' )
len++; {
s_shared_token[len] = 0; s_shared_token[len] = c;
return data+1; len++;
s_shared_token[len] = 0;
return data+1;
}
} }
// parse a regular word // parse a regular word
do while (len < sizeof( s_shared_token ) - 1)
{ {
s_shared_token[len] = c; s_shared_token[len] = c;
data++; data++;
len++; len++;
c = *data; c = *data;
if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c == ',' )
if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c == ',' )
break; break;
} while (c>32);
if (c <= 32)
break;
}
s_shared_token[len] = 0; s_shared_token[len] = 0;
return data; return data;