internal_securecrt.h 12 KB

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