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