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