1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
#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
|