| 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 | |