Files
fs2open.github.com/code/globalincs/safe_strings.cpp
T
BMagnu 2116d1fe66 Modular POF Features (#4713)
* Add turret copying

* Ad addturret parsing

* Fix gun_nr error

* Fix strncpy_s

* Fix strings better

* Cleanup submodel / turret copying

* Add 'Add Engine'

* Add Glowpoints, add Special Subsys

* Remember to keep the glowpoint texture

* Fix unused param
2022-10-24 18:35:51 +09:00

160 lines
3.5 KiB
C++

#include "pstypes.h"
/* It is a condition of use that safe_strings.cpp, safe_strings.h, safe_strings_test.cpp remain together.
*
* Maintained by portej05 - contact via PM on www.hard-light.net/forums
* Why have we got this, what is it for?
* VC2005+ define some safe string functions which check buffer sizes before doing anything
* Unfortunately, GCC (on Linux and Mac OS X) does not yet provide these functions, therefore, we must!
* (if only to reduce the amount of noise the static analysis tools are spitting out)
* They are part of ISO/IEC TR 24731 and may find their way into the CRTs at some point, at which
* point these functions must be removed from the engine.
* While these functions do not add a huge amount of benefit for heap-allocated strings, they
* can protect against a class of buffer overruns in stack allocated situations.
*
*/
/* There is no safe strings below VS2005
* scp safe_strings are used in VS2005+ DEBUG because they give more info
*/
#if !defined(NO_SAFE_STRINGS) && ( !defined( _MSC_VER ) || ( defined( _MSC_VER ) && _MSC_VER >= 1400 /* && !defined(NDEBUG) */ ))
/* An implementation of strcpy_s
* We're not going to actually fully behave like the MS debug version.
*/
errno_t scp_strcpy_s( const char* file, int line, char* strDest, size_t sizeInBytes, const char* strSource )
{
char* pDest;
const char* pSource;
size_t bufferLeft = sizeInBytes;
if ( !strDest || !strSource )
{
if ( strDest )
*strDest = '\0';
__safe_strings_error_handler( EINVAL );
return EINVAL;
}
if ( sizeInBytes == 0 )
{
*strDest = '\0';
__safe_strings_error_handler( ERANGE );
return ERANGE;
}
pDest = strDest;
pSource = strSource;
while ((*pDest++ = *pSource++) != 0 && --bufferLeft > 0);
if ( bufferLeft == 0 )
{
*strDest = '\0';
__safe_strings_error_handler( ERANGE );
return ERANGE;
}
return 0;
}
errno_t scp_strncpy_s(const char* file, int line, char* strDest, size_t sizeInBytes, const char* strSource, size_t inputSizeInBytes) {
char* pDest;
const char* pSource;
size_t bufferLeft = sizeInBytes;
if (!strDest || !strSource)
{
if (strDest)
*strDest = '\0';
__safe_strings_error_handler(EINVAL);
return EINVAL;
}
if (sizeInBytes == 0)
{
*strDest = '\0';
__safe_strings_error_handler(ERANGE);
return ERANGE;
}
if (inputSizeInBytes == 0)
{
*strDest = '\0';
return 0;
}
pDest = strDest;
pSource = strSource;
while ((*pDest++ = *pSource++) != 0 && (--inputSizeInBytes > 0) && --bufferLeft > 0);
if (bufferLeft == 0 || (inputSizeInBytes == 0 && bufferLeft <= 1))
{
*strDest = '\0';
__safe_strings_error_handler(ERANGE);
return ERANGE;
}
if (inputSizeInBytes == 0) {
*pDest = '\0';
}
return 0;
}
errno_t scp_strcat_s( const char* file, int line, char* strDest, size_t sizeInBytes, const char* strSource )
{
char* pDest;
const char* pSource;
size_t bufferLeft = sizeInBytes;
if ( !strDest || !strSource )
{
if ( strDest )
*strDest = '\0';
__safe_strings_error_handler( EINVAL );
return EINVAL;
}
if ( bufferLeft == 0 )
{
*strDest = '\0';
__safe_strings_error_handler( ERANGE );
return ERANGE;
}
/* Find the terminating NULL of the input string */
pDest = strDest;
pSource = strSource;
while ( *pDest )
{
pDest++;
bufferLeft--;
}
if ( bufferLeft == 0 )
{
*strDest = '\0';
__safe_strings_error_handler( ERANGE );
return ERANGE;
}
/* Concatenate the strings */
while ((*pDest++ = *pSource++) != 0 && --bufferLeft > 0);
if ( bufferLeft == 0 )
{
*strDest = '\0';
__safe_strings_error_handler( ERANGE );
return ERANGE;
}
return 0;
}
#endif