| 1 | // Licensed to the .NET Foundation under one or more agreements. | 
|---|
| 2 | // The .NET Foundation licenses this file to you under the MIT license. | 
|---|
| 3 | // See the LICENSE file in the project root for more information. | 
|---|
| 4 |  | 
|---|
| 5 | /*** | 
|---|
| 6 | *internal_securecrt.h - contains declarations of internal routines and variables for securecrt | 
|---|
| 7 | * | 
|---|
| 8 |  | 
|---|
| 9 | * | 
|---|
| 10 | *Purpose: | 
|---|
| 11 | *       Declares routines and variables used internally in the SecureCRT implementation. | 
|---|
| 12 | *       In this include file we define the macros needed to implement the secure functions | 
|---|
| 13 | *       inlined in the *.inl files like tcscpy_s.inl, etc. | 
|---|
| 14 | *       Note that this file is used for the CRT implementation, while internal_safecrt is used | 
|---|
| 15 | *       to build the downlevel library safecrt.lib. | 
|---|
| 16 | * | 
|---|
| 17 | *       [Internal] | 
|---|
| 18 | * | 
|---|
| 19 | ****/ | 
|---|
| 20 |  | 
|---|
| 21 | #pragma once | 
|---|
| 22 |  | 
|---|
| 23 | #ifndef _INC_INTERNAL_SECURECRT | 
|---|
| 24 | #define _INC_INTERNAL_SECURECRT | 
|---|
| 25 |  | 
|---|
| 26 | /* more VS specific goodness */ | 
|---|
| 27 | #define __out_ecount_z( x ) | 
|---|
| 28 | #define __out_ecount( x ) | 
|---|
| 29 | #define __in_opt | 
|---|
| 30 | #define __in_z_opt | 
|---|
| 31 | #define __out_ecount_z_opt( x ) | 
|---|
| 32 | #define __in_z | 
|---|
| 33 | #define __in | 
|---|
| 34 |  | 
|---|
| 35 | /* | 
|---|
| 36 | * The original SafeCRT implemention allows runtime control over buffer checking. | 
|---|
| 37 | * For now we'll key this off the debug flag. | 
|---|
| 38 | */ | 
|---|
| 39 | #ifdef _DEBUG | 
|---|
| 40 | #define _CrtGetCheckCount()                 ((int)1) | 
|---|
| 41 | #else | 
|---|
| 42 | #define _CrtGetCheckCount()                 ((int)0) | 
|---|
| 43 | #endif | 
|---|
| 44 |  | 
|---|
| 45 | /* Assert message and Invalid parameter */ | 
|---|
| 46 | #ifdef _DEBUG | 
|---|
| 47 | #define _ASSERT_EXPR( val, exp )                                            \ | 
|---|
| 48 | {                                                                       \ | 
|---|
| 49 | if ( ( val ) == 0 )                                                 \ | 
|---|
| 50 | {                                                                   \ | 
|---|
| 51 | if ( sMBUSafeCRTAssertFunc != NULL )                            \ | 
|---|
| 52 | {                                                               \ | 
|---|
| 53 | ( *sMBUSafeCRTAssertFunc )( #exp, "SafeCRT assert failed", __FILE__, __LINE__ );    \ | 
|---|
| 54 | }                                                               \ | 
|---|
| 55 | }                                                                   \ | 
|---|
| 56 | } | 
|---|
| 57 | #define _INVALID_PARAMETER( exp )   _ASSERT_EXPR( 0, exp ) | 
|---|
| 58 | #define _ASSERTE( exp ) _ASSERT_EXPR( exp, exp ) | 
|---|
| 59 | #else | 
|---|
| 60 | #define _ASSERT_EXPR( val, expr ) | 
|---|
| 61 | #define _INVALID_PARAMETER( exp ) | 
|---|
| 62 | #define _ASSERTE( exp ) | 
|---|
| 63 | #endif | 
|---|
| 64 |  | 
|---|
| 65 | /* _TRUNCATE */ | 
|---|
| 66 | #if !defined (_TRUNCATE) | 
|---|
| 67 | #define _TRUNCATE ((size_t)-1) | 
|---|
| 68 | #endif  /* !defined (_TRUNCATE) */ | 
|---|
| 69 |  | 
|---|
| 70 | /* #include <internal.h> */ | 
|---|
| 71 |  | 
|---|
| 72 | #define _VALIDATE_RETURN_VOID( expr, errorcode )                               \ | 
|---|
| 73 | {                                                                          \ | 
|---|
| 74 | int _Expr_val=!!(expr);                                                \ | 
|---|
| 75 | _ASSERT_EXPR( ( _Expr_val ), #expr );                       \ | 
|---|
| 76 | if ( !( _Expr_val ) )                                                  \ | 
|---|
| 77 | {                                                                      \ | 
|---|
| 78 | errno = errorcode;                                                 \ | 
|---|
| 79 | _INVALID_PARAMETER(#expr);                              \ | 
|---|
| 80 | return;                                                            \ | 
|---|
| 81 | }                                                                      \ | 
|---|
| 82 | } | 
|---|
| 83 |  | 
|---|
| 84 | /* | 
|---|
| 85 | * Assert in debug builds. | 
|---|
| 86 | * set errno and return value | 
|---|
| 87 | */ | 
|---|
| 88 |  | 
|---|
| 89 | #ifndef _VALIDATE_RETURN | 
|---|
| 90 | #define _VALIDATE_RETURN( expr, errorcode, retexpr )                           \ | 
|---|
| 91 | {                                                                          \ | 
|---|
| 92 | int _Expr_val=!!(expr);                                                \ | 
|---|
| 93 | _ASSERT_EXPR( ( _Expr_val ), #expr );                       \ | 
|---|
| 94 | if ( !( _Expr_val ) )                                                  \ | 
|---|
| 95 | {                                                                      \ | 
|---|
| 96 | errno = errorcode;                                                 \ | 
|---|
| 97 | _INVALID_PARAMETER(#expr );                             \ | 
|---|
| 98 | return ( retexpr );                                                \ | 
|---|
| 99 | }                                                                      \ | 
|---|
| 100 | } | 
|---|
| 101 | #endif  /* _VALIDATE_RETURN */ | 
|---|
| 102 |  | 
|---|
| 103 | #ifndef _VALIDATE_RETURN_NOEXC | 
|---|
| 104 | #define _VALIDATE_RETURN_NOEXC( expr, errorcode, retexpr )                     \ | 
|---|
| 105 | {                                                                          \ | 
|---|
| 106 | if ( !(expr) )                                                         \ | 
|---|
| 107 | {                                                                      \ | 
|---|
| 108 | errno = errorcode;                                                 \ | 
|---|
| 109 | return ( retexpr );                                                \ | 
|---|
| 110 | }                                                                      \ | 
|---|
| 111 | } | 
|---|
| 112 | #endif  /* _VALIDATE_RETURN_NOEXC */ | 
|---|
| 113 |  | 
|---|
| 114 | /* | 
|---|
| 115 | * Assert in debug builds. | 
|---|
| 116 | * set errno and return errorcode | 
|---|
| 117 | */ | 
|---|
| 118 |  | 
|---|
| 119 | #define _VALIDATE_RETURN_ERRCODE( expr, errorcode )                            \ | 
|---|
| 120 | {                                                                          \ | 
|---|
| 121 | int _Expr_val=!!(expr);                                                \ | 
|---|
| 122 | _ASSERT_EXPR( ( _Expr_val ), _CRT_WIDE(#expr) );                       \ | 
|---|
| 123 | if ( !( _Expr_val ) )                                                  \ | 
|---|
| 124 | {                                                                      \ | 
|---|
| 125 | errno = errorcode;                                                 \ | 
|---|
| 126 | _INVALID_PARAMETER(_CRT_WIDE(#expr));                              \ | 
|---|
| 127 | return ( errorcode );                                              \ | 
|---|
| 128 | }                                                                      \ | 
|---|
| 129 | } | 
|---|
| 130 |  | 
|---|
| 131 | /* We completely fill the buffer only in debug (see _SECURECRT__FILL_STRING | 
|---|
| 132 | * and _SECURECRT__FILL_BYTE macros). | 
|---|
| 133 | */ | 
|---|
| 134 | #if !defined (_SECURECRT_FILL_BUFFER) | 
|---|
| 135 | #ifdef _DEBUG | 
|---|
| 136 | #define _SECURECRT_FILL_BUFFER 1 | 
|---|
| 137 | #else  /* _DEBUG */ | 
|---|
| 138 | #define _SECURECRT_FILL_BUFFER 0 | 
|---|
| 139 | #endif  /* _DEBUG */ | 
|---|
| 140 | #endif  /* !defined (_SECURECRT_FILL_BUFFER) */ | 
|---|
| 141 |  | 
|---|
| 142 | /* _SECURECRT_FILL_BUFFER_PATTERN is the same as _bNoMansLandFill */ | 
|---|
| 143 | #define _SECURECRT_FILL_BUFFER_PATTERN 0xFD | 
|---|
| 144 |  | 
|---|
| 145 | #if !defined (_SECURECRT_FILL_BUFFER_THRESHOLD) | 
|---|
| 146 | #ifdef _DEBUG | 
|---|
| 147 | #define _SECURECRT_FILL_BUFFER_THRESHOLD ((size_t)8) | 
|---|
| 148 | #else  /* _DEBUG */ | 
|---|
| 149 | #define _SECURECRT_FILL_BUFFER_THRESHOLD ((size_t)0) | 
|---|
| 150 | #endif  /* _DEBUG */ | 
|---|
| 151 | #endif  /* !defined (_SECURECRT_FILL_BUFFER_THRESHOLD) */ | 
|---|
| 152 |  | 
|---|
| 153 | #if _SECURECRT_FILL_BUFFER | 
|---|
| 154 | #define _SECURECRT__FILL_STRING(_String, _Size, _Offset)                            \ | 
|---|
| 155 | if ((_Size) != ((size_t)-1) && (_Size) != INT_MAX &&                            \ | 
|---|
| 156 | ((size_t)(_Offset)) < (_Size))                                              \ | 
|---|
| 157 | {                                                                               \ | 
|---|
| 158 | memset((_String) + (_Offset),                                               \ | 
|---|
| 159 | _SECURECRT_FILL_BUFFER_PATTERN,                                         \ | 
|---|
| 160 | (_SECURECRT_FILL_BUFFER_THRESHOLD < ((size_t)((_Size) - (_Offset))) ?   \ | 
|---|
| 161 | _SECURECRT_FILL_BUFFER_THRESHOLD :                                  \ | 
|---|
| 162 | ((_Size) - (_Offset))) * sizeof(*(_String)));                       \ | 
|---|
| 163 | } | 
|---|
| 164 | #else  /* _SECURECRT_FILL_BUFFER */ | 
|---|
| 165 | #define _SECURECRT__FILL_STRING(_String, _Size, _Offset) | 
|---|
| 166 | #endif  /* _SECURECRT_FILL_BUFFER */ | 
|---|
| 167 |  | 
|---|
| 168 | #if _SECURECRT_FILL_BUFFER | 
|---|
| 169 | #define _SECURECRT__FILL_BYTE(_Position)                \ | 
|---|
| 170 | if (_SECURECRT_FILL_BUFFER_THRESHOLD > 0)           \ | 
|---|
| 171 | {                                                   \ | 
|---|
| 172 | (_Position) = _SECURECRT_FILL_BUFFER_PATTERN;   \ | 
|---|
| 173 | } | 
|---|
| 174 | #else  /* _SECURECRT_FILL_BUFFER */ | 
|---|
| 175 | #define _SECURECRT__FILL_BYTE(_Position) | 
|---|
| 176 | #endif  /* _SECURECRT_FILL_BUFFER */ | 
|---|
| 177 |  | 
|---|
| 178 | /* string resetting */ | 
|---|
| 179 | #define _FILL_STRING _SECURECRT__FILL_STRING | 
|---|
| 180 |  | 
|---|
| 181 | #define _FILL_BYTE _SECURECRT__FILL_BYTE | 
|---|
| 182 |  | 
|---|
| 183 | #define _RESET_STRING(_String, _Size)           \ | 
|---|
| 184 | {                                           \ | 
|---|
| 185 | *(_String) = 0;                         \ | 
|---|
| 186 | _FILL_STRING((_String), (_Size), 1);    \ | 
|---|
| 187 | } | 
|---|
| 188 |  | 
|---|
| 189 | /* validations */ | 
|---|
| 190 | #define _VALIDATE_STRING_ERROR(_String, _Size, _Ret) \ | 
|---|
| 191 | _VALIDATE_RETURN((_String) != NULL && (_Size) > 0, EINVAL, (_Ret)) | 
|---|
| 192 |  | 
|---|
| 193 | #define _VALIDATE_STRING(_String, _Size) \ | 
|---|
| 194 | _VALIDATE_STRING_ERROR((_String), (_Size), EINVAL) | 
|---|
| 195 |  | 
|---|
| 196 | #define _VALIDATE_POINTER_ERROR_RETURN(_Pointer, _ErrorCode, _Ret) \ | 
|---|
| 197 | _VALIDATE_RETURN((_Pointer) != NULL, (_ErrorCode), (_Ret)) | 
|---|
| 198 |  | 
|---|
| 199 | #define _VALIDATE_POINTER_ERROR(_Pointer, _Ret) \ | 
|---|
| 200 | _VALIDATE_POINTER_ERROR_RETURN((_Pointer), EINVAL, (_Ret)) | 
|---|
| 201 |  | 
|---|
| 202 | #define _VALIDATE_POINTER(_Pointer) \ | 
|---|
| 203 | _VALIDATE_POINTER_ERROR((_Pointer), EINVAL) | 
|---|
| 204 |  | 
|---|
| 205 | #define _VALIDATE_CONDITION_ERROR_RETURN(_Condition, _ErrorCode, _Ret) \ | 
|---|
| 206 | _VALIDATE_RETURN((_Condition), (_ErrorCode), (_Ret)) | 
|---|
| 207 |  | 
|---|
| 208 | #define _VALIDATE_CONDITION_ERROR(_Condition, _Ret) \ | 
|---|
| 209 | _VALIDATE_CONDITION_ERROR_RETURN((_Condition), EINVAL, (_Ret)) | 
|---|
| 210 |  | 
|---|
| 211 | #define _VALIDATE_POINTER_RESET_STRING_ERROR(_Pointer, _String, _Size, _Ret) \ | 
|---|
| 212 | if ((_Pointer) == NULL) \ | 
|---|
| 213 | { \ | 
|---|
| 214 | _RESET_STRING((_String), (_Size)); \ | 
|---|
| 215 | _VALIDATE_POINTER_ERROR_RETURN((_Pointer), EINVAL, (_Ret)) \ | 
|---|
| 216 | } | 
|---|
| 217 |  | 
|---|
| 218 | #define _VALIDATE_POINTER_RESET_STRING(_Pointer, _String, _Size) \ | 
|---|
| 219 | _VALIDATE_POINTER_RESET_STRING_ERROR((_Pointer), (_String), (_Size), EINVAL) | 
|---|
| 220 |  | 
|---|
| 221 | #define _RETURN_BUFFER_TOO_SMALL_ERROR(_String, _Size, _Ret) \ | 
|---|
| 222 | _VALIDATE_RETURN(("Buffer is too small" && 0), ERANGE, _Ret) | 
|---|
| 223 |  | 
|---|
| 224 | #define _RETURN_BUFFER_TOO_SMALL(_String, _Size) \ | 
|---|
| 225 | _RETURN_BUFFER_TOO_SMALL_ERROR((_String), (_Size), ERANGE) | 
|---|
| 226 |  | 
|---|
| 227 | #define _RETURN_DEST_NOT_NULL_TERMINATED(_String, _Size) \ | 
|---|
| 228 | _VALIDATE_RETURN(("String is not null terminated" && 0), EINVAL, EINVAL) | 
|---|
| 229 |  | 
|---|
| 230 | #define _RETURN_EINVAL \ | 
|---|
| 231 | _VALIDATE_RETURN(("Invalid parameter" && 0), EINVAL, EINVAL) | 
|---|
| 232 |  | 
|---|
| 233 | #define _RETURN_ERROR(_Msg, _Ret) \ | 
|---|
| 234 | _VALIDATE_RETURN(((_Msg), 0), EINVAL, _Ret) | 
|---|
| 235 |  | 
|---|
| 236 | /* returns without calling _invalid_parameter */ | 
|---|
| 237 | #define _RETURN_NO_ERROR \ | 
|---|
| 238 | return 0 | 
|---|
| 239 |  | 
|---|
| 240 | /* Note that _RETURN_TRUNCATE does not set errno */ | 
|---|
| 241 | #define _RETURN_TRUNCATE \ | 
|---|
| 242 | return STRUNCATE | 
|---|
| 243 |  | 
|---|
| 244 | #define _SET_MBCS_ERROR \ | 
|---|
| 245 | (errno = EILSEQ) | 
|---|
| 246 |  | 
|---|
| 247 | #define _RETURN_MBCS_ERROR \ | 
|---|
| 248 | return _SET_MBCS_ERROR | 
|---|
| 249 |  | 
|---|
| 250 | /* locale dependent */ | 
|---|
| 251 | #define _LOCALE_ARG \ | 
|---|
| 252 | _LocInfo | 
|---|
| 253 |  | 
|---|
| 254 | #define _LOCALE_ARG_DECL \ | 
|---|
| 255 | _locale_t _LOCALE_ARG | 
|---|
| 256 |  | 
|---|
| 257 | #define _LOCALE_UPDATE \ | 
|---|
| 258 | _LocaleUpdate _LocUpdate(_LOCALE_ARG) | 
|---|
| 259 |  | 
|---|
| 260 | #define _ISMBBLEAD(_Character) \ | 
|---|
| 261 | _ismbblead_l((_Character), _LocUpdate.GetLocaleT()) | 
|---|
| 262 |  | 
|---|
| 263 | #define _MBSDEC(_String, _Current) \ | 
|---|
| 264 | _mbsdec((_String), (_Current)) | 
|---|
| 265 |  | 
|---|
| 266 | #define _ISMBBLEADPREFIX(_Result, _StringStart, _BytePtr)               \ | 
|---|
| 267 | {                                                                   \ | 
|---|
| 268 | unsigned char *_Tmp_VAR, *_StringStart_VAR, *_BytePtr_VAR;      \ | 
|---|
| 269 | \ | 
|---|
| 270 | _StringStart_VAR = (_StringStart);                              \ | 
|---|
| 271 | _BytePtr_VAR = (_BytePtr);                                      \ | 
|---|
| 272 | _Tmp_VAR = _BytePtr_VAR;                                        \ | 
|---|
| 273 | while ((_Tmp_VAR >= _StringStart_VAR) && _ISMBBLEAD(*_Tmp_VAR)) \ | 
|---|
| 274 | {                                                               \ | 
|---|
| 275 | _Tmp_VAR--;                                                 \ | 
|---|
| 276 | }                                                               \ | 
|---|
| 277 | (_Result) = ((_BytePtr_VAR - _Tmp_VAR) & 1) != 0;               \ | 
|---|
| 278 | } | 
|---|
| 279 |  | 
|---|
| 280 | #define _LOCALE_SHORTCUT_TEST \ | 
|---|
| 281 | _LocUpdate.GetLocaleT()->mbcinfo->ismbcodepage == 0 | 
|---|
| 282 |  | 
|---|
| 283 | #define _USE_LOCALE_ARG 1 | 
|---|
| 284 |  | 
|---|
| 285 | /* misc */ | 
|---|
| 286 | #define _ASSIGN_IF_NOT_NULL(_Pointer, _Value) \ | 
|---|
| 287 | if ((_Pointer) != NULL) \ | 
|---|
| 288 | { \ | 
|---|
| 289 | *(_Pointer) = (_Value); \ | 
|---|
| 290 | } | 
|---|
| 291 |  | 
|---|
| 292 | #endif  /* _INC_INTERNAL_SECURECRT */ | 
|---|
| 293 |  | 
|---|