FS2_Open
Open source remastering of the Freespace 2 engine
safe_strings.cpp
Go to the documentation of this file.
1 #include "pstypes.h"
2 
3 /* It is a condition of use that safe_strings.cpp, safe_strings.h, safe_strings_test.cpp remain together.
4  *
5  * Maintained by portej05 - contact via PM on www.hard-light.net/forums
6  * Why have we got this, what is it for?
7  * VC2005+ define some safe string functions which check buffer sizes before doing anything
8  * Unfortunately, GCC (on Linux and Mac OS X) does not yet provide these functions, therefore, we must!
9  * (if only to reduce the amount of noise the static analysis tools are spitting out)
10  * They are part of ISO/IEC TR 24731 and may find their way into the CRTs at some point, at which
11  * point these functions must be removed from the engine.
12  * While these functions do not add a huge amount of benefit for heap-allocated strings, they
13  * can protect against a class of buffer overruns in stack allocated situations.
14  *
15  */
16 
17 /* There is no safe strings below VS2005
18  * scp safe_strings are used in VS2005+ DEBUG because they give more info
19  */
20 
21 
22 
23 #if !defined(NO_SAFE_STRINGS) && ( !defined( _MSC_VER ) || ( defined( _MSC_VER ) && _MSC_VER >= 1400 /* && !defined(NDEBUG) */ ))
24 
25 /* An implementation of strcpy_s
26  * We're not going to actually fully behave like the MS debug version.
27  */
28 errno_t scp_strcpy_s( const char* file, int line, char* strDest, size_t sizeInBytes, const char* strSource )
29 {
30  char* pDest;
31  const char* pSource;
32  size_t bufferLeft = sizeInBytes;
33 
34  if ( !strDest || !strSource )
35  {
36  if ( strDest )
37  *strDest = '\0';
39  return EINVAL;
40  }
41 
42  if ( sizeInBytes == 0 )
43  {
44  *strDest = '\0';
46  return ERANGE;
47  }
48 
49  pDest = strDest;
50  pSource = strSource;
51 
52  while ((*pDest++ = *pSource++) != 0 && --bufferLeft > 0);
53 
54  if ( bufferLeft == 0 )
55  {
56  *strDest = '\0';
58  return ERANGE;
59  }
60 
61  return 0;
62 }
63 
64 errno_t scp_strcat_s( const char* file, int line, char* strDest, size_t sizeInBytes, const char* strSource )
65 {
66  char* pDest;
67  const char* pSource;
68  size_t bufferLeft = sizeInBytes;
69 
70  if ( !strDest || !strSource )
71  {
72  if ( strDest )
73  *strDest = '\0';
75  return EINVAL;
76  }
77 
78  if ( bufferLeft == 0 )
79  {
80  *strDest = '\0';
82  return ERANGE;
83  }
84 
85  /* Find the terminating NULL of the input string */
86  pDest = strDest;
87  pSource = strSource;
88  while ( *pDest )
89  {
90  pDest++;
91  bufferLeft--;
92  }
93 
94  if ( bufferLeft == 0 )
95  {
96  *strDest = '\0';
98  return ERANGE;
99  }
100 
101  /* Concatenate the strings */
102  while ((*pDest++ = *pSource++) != 0 && --bufferLeft > 0);
103 
104  if ( bufferLeft == 0 )
105  {
106  *strDest = '\0';
108  return ERANGE;
109  }
110 
111  return 0;
112 }
113 
114 #endif
errno_t scp_strcat_s(const char *file, int line, char *strDest, size_t sizeInBytes, const char *strSource)
int errno_t
Definition: safe_strings.h:27
errno_t scp_strcpy_s(const char *file, int line, char *strDest, size_t sizeInBytes, const char *strSource)
#define __safe_strings_error_handler(val)
Definition: safe_strings.h:40