diff --git a/rehlds/engine/common.cpp b/rehlds/engine/common.cpp index f652253..368cece 100644 --- a/rehlds/engine/common.cpp +++ b/rehlds/engine/common.cpp @@ -33,6 +33,12 @@ char serverinfo[MAX_INFO_STRING]; char gpszVersionString[32]; char gpszProductString[32]; +char* strcpy_safe(char* dst, char* src) { + int len = strlen(src); + memmove(dst, src, len + 1); + return dst; +} + /* ../engine/common.c:80 */ char *Info_Serverinfo(void) diff --git a/rehlds/engine/common.h b/rehlds/engine/common.h index 10adfe8..5c2f2f2 100644 --- a/rehlds/engine/common.h +++ b/rehlds/engine/common.h @@ -170,6 +170,9 @@ NOBODY uint64 Q_strtoull(char *str); #endif // Q_functions +//strcpy that works correctly with overlapping src and dst buffers +char* strcpy_safe(char* dst, char* src); + int build_number(void); char *Info_Serverinfo(void); diff --git a/rehlds/engine/info.cpp b/rehlds/engine/info.cpp index dfec4f9..96ffd26 100644 --- a/rehlds/engine/info.cpp +++ b/rehlds/engine/info.cpp @@ -30,7 +30,6 @@ // NOTE: This file contains a lot of fixes that are not covered by REHLDS_FIXES define. // TODO: Most of the Info_ functions can be speedup via removing unneded copy of key and values. -// TODO: We have a problem with Q_strcpy, because it maps to strcpy which have undefined behavior when strings overlaps (possibly we need to use memmove solution here) /* =============== @@ -179,7 +178,7 @@ void Info_RemoveKey(char *s, const char *key) // Compare keys if (!Q_strncmp(key, pkey, cmpsize)) { - Q_strcpy(start, s); // remove this part + strcpy_safe(start, s); // remove this part s = start; // continue searching } } @@ -245,7 +244,7 @@ void Info_RemovePrefixedKeys(char *s, const char prefix) if (pkey[0] == prefix) { - Q_strcpy(start, s); // remove this part + strcpy_safe(start, s); // remove this part s = start; // continue searching } } diff --git a/rehlds/engine/tmessage.cpp b/rehlds/engine/tmessage.cpp index 9e0a898..ab82a58 100644 --- a/rehlds/engine/tmessage.cpp +++ b/rehlds/engine/tmessage.cpp @@ -248,76 +248,76 @@ NOXREF int IsToken(const char *pText, const char *pTokenName) /* ../engine/tmessage.c:245 */ NOXREF int ParseDirective(const char *pText) { - if (pText && pText[0] == '$') - { - float tempFloat[8]; - if (IsToken(pText, "position")) - { - if (ParseFloats(pText, tempFloat, 2)) - { - gMessageParms.x = tempFloat[0]; - gMessageParms.y = tempFloat[1]; - } - } - else if (IsToken(pText, "effect")) - { - if (ParseFloats(pText, tempFloat, 1)) - { - gMessageParms.effect = (int)tempFloat[0]; - } - } - else if (IsToken(pText, "fxtime")) - { - if (ParseFloats(pText, tempFloat, 1)) - { - gMessageParms.fxtime = tempFloat[0]; - } - } - else if (IsToken(pText, "color2")) - { - if (ParseFloats(pText, tempFloat, 3)) - { - gMessageParms.r2 = (int)tempFloat[0]; - gMessageParms.g2 = (int)tempFloat[1]; - gMessageParms.b2 = (int)tempFloat[2]; - } - } - else if (IsToken(pText, "color")) - { - if (ParseFloats(pText, tempFloat, 3)) - { - gMessageParms.r1 = (int)tempFloat[0]; - gMessageParms.g1 = (int)tempFloat[1]; - gMessageParms.b1 = (int)tempFloat[2]; - } - } - else if (IsToken(pText, "fadein")) - { - if (ParseFloats(pText, tempFloat, 1)) - { - gMessageParms.fadein = tempFloat[0]; - } - } - else if (IsToken(pText, "fadeout")) - { - if (ParseFloats(pText, tempFloat, 3)) - { - gMessageParms.fadeout = tempFloat[0]; - } - } - else if (IsToken(pText, "holdtime")) - { - if (ParseFloats(pText, tempFloat, 3)) - { - gMessageParms.holdtime = tempFloat[0]; - } - } - else - { - Con_DPrintf("Unknown token: %s\n", pText); - } - return 1; - } + if (pText && pText[0] == '$') + { + float tempFloat[8]; + if (IsToken(pText, "position")) + { + if (ParseFloats(pText, tempFloat, 2)) + { + gMessageParms.x = tempFloat[0]; + gMessageParms.y = tempFloat[1]; + } + } + else if (IsToken(pText, "effect")) + { + if (ParseFloats(pText, tempFloat, 1)) + { + gMessageParms.effect = (int)tempFloat[0]; + } + } + else if (IsToken(pText, "fxtime")) + { + if (ParseFloats(pText, tempFloat, 1)) + { + gMessageParms.fxtime = tempFloat[0]; + } + } + else if (IsToken(pText, "color2")) + { + if (ParseFloats(pText, tempFloat, 3)) + { + gMessageParms.r2 = (int)tempFloat[0]; + gMessageParms.g2 = (int)tempFloat[1]; + gMessageParms.b2 = (int)tempFloat[2]; + } + } + else if (IsToken(pText, "color")) + { + if (ParseFloats(pText, tempFloat, 3)) + { + gMessageParms.r1 = (int)tempFloat[0]; + gMessageParms.g1 = (int)tempFloat[1]; + gMessageParms.b1 = (int)tempFloat[2]; + } + } + else if (IsToken(pText, "fadein")) + { + if (ParseFloats(pText, tempFloat, 1)) + { + gMessageParms.fadein = tempFloat[0]; + } + } + else if (IsToken(pText, "fadeout")) + { + if (ParseFloats(pText, tempFloat, 3)) + { + gMessageParms.fadeout = tempFloat[0]; + } + } + else if (IsToken(pText, "holdtime")) + { + if (ParseFloats(pText, tempFloat, 3)) + { + gMessageParms.holdtime = tempFloat[0]; + } + } + else + { + Con_DPrintf("Unknown token: %s\n", pText); + } + return 1; + } return 0; }