mbusafecrt.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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. * mbusafecrt.c - implementaion of support functions and data for MBUSafeCRT
  7. *
  8. *
  9. * Purpose:
  10. * This file contains the implementation of support functions and
  11. * data for MBUSafeCRT declared in mbusafecrt.h and mbusafecrt_internal.h.
  12. ****/
  13. #ifndef _LIBSAFECRT_SGX_CONFIG
  14. #include "pal/palinternal.h"
  15. #endif
  16. #include <string.h>
  17. #include <errno.h>
  18. #include <limits.h>
  19. #include "mbusafecrt_internal.h"
  20. #ifndef _LIBSAFECRT_SGX_CONFIG
  21. /* global data */
  22. tSafeCRT_AssertFuncPtr sMBUSafeCRTAssertFunc = NULL;
  23. /***
  24. * MBUSafeCRTSetAssertFunc - Set the function called when an assert fails.
  25. ****/
  26. void MBUSafeCRTSetAssertFunc( tSafeCRT_AssertFuncPtr inAssertFuncPtr )
  27. {
  28. /* set it */
  29. sMBUSafeCRTAssertFunc = inAssertFuncPtr;
  30. }
  31. #endif
  32. /***
  33. * _putc_nolock - putc for the miniFILE stream.
  34. ****/
  35. int _putc_nolock( char inChar, miniFILE* inStream )
  36. {
  37. int returnValue = EOF;
  38. inStream->_cnt -= (int)sizeof( char );
  39. if ( ( inStream->_cnt ) >= 0 )
  40. {
  41. *( inStream->_ptr ) = inChar;
  42. inStream->_ptr += (int)sizeof( char );
  43. returnValue = ( int )inChar;
  44. }
  45. return returnValue;
  46. }
  47. /***
  48. * _putwc_nolock - putwc for the miniFILE stream.
  49. ****/
  50. int _putwc_nolock( char16_t inChar, miniFILE* inStream )
  51. {
  52. int returnValue = WEOF;
  53. inStream->_cnt -= (int)sizeof( char16_t );
  54. if ( ( inStream->_cnt ) >= 0 )
  55. {
  56. *( ( char16_t* )( inStream->_ptr ) ) = inChar;
  57. inStream->_ptr += (int)sizeof( char16_t );
  58. returnValue = ( int )inChar;
  59. }
  60. return returnValue;
  61. }
  62. #ifndef _LIBSAFECRT_SGX_CONFIG
  63. /***
  64. * _getc_nolock - getc for the miniFILE stream.
  65. ****/
  66. int _getc_nolock( miniFILE* inStream )
  67. {
  68. int returnValue = EOF;
  69. if ( ( inStream->_cnt ) >= ( int )( sizeof( char ) ) )
  70. {
  71. inStream->_cnt -= sizeof( char );
  72. returnValue = ( int )( *( inStream->_ptr ) );
  73. inStream->_ptr += sizeof( char );
  74. }
  75. return returnValue;
  76. }
  77. /***
  78. * _getwc_nolock - getc for the miniFILE stream.
  79. ****/
  80. int _getwc_nolock( miniFILE* inStream )
  81. {
  82. int returnValue = EOF;
  83. if ( ( inStream->_cnt ) >= ( int )( sizeof( char16_t ) ) )
  84. {
  85. inStream->_cnt -= sizeof( char16_t );
  86. returnValue = ( int )( *( ( char16_t* )( inStream->_ptr ) ) );
  87. inStream->_ptr += sizeof( char16_t );
  88. }
  89. return returnValue;
  90. }
  91. /***
  92. * _ungetc_nolock - ungetc for the miniFILE stream.
  93. ****/
  94. int _ungetc_nolock( char inChar, miniFILE* inStream )
  95. {
  96. int returnValue = EOF;
  97. if ( ( size_t )( ( inStream->_ptr ) - ( inStream->_base ) ) >= ( sizeof( char ) ) )
  98. {
  99. inStream->_cnt += sizeof( char );
  100. inStream->_ptr -= sizeof( char );
  101. return ( int )inChar;
  102. }
  103. return returnValue;
  104. }
  105. /***
  106. * _ungetwc_nolock - ungetwc for the miniFILE stream.
  107. ****/
  108. int _ungetwc_nolock( char16_t inChar, miniFILE* inStream )
  109. {
  110. int returnValue = WEOF;
  111. if ( ( size_t )( ( inStream->_ptr ) - ( inStream->_base ) ) >= ( sizeof( char16_t ) ) )
  112. {
  113. inStream->_cnt += sizeof( char16_t );
  114. inStream->_ptr -= sizeof( char16_t );
  115. returnValue = ( unsigned short )inChar;
  116. }
  117. return returnValue;
  118. }
  119. #endif
  120. /***
  121. * _safecrt_cfltcvt - convert a float to an ascii string.
  122. * Uses sprintf - this usage is OK.
  123. ****/
  124. /* routine used for floating-point output */
  125. #define FORMATSIZE 30
  126. #define _snprintf snprintf
  127. // taken from output.inl
  128. #define FL_ALTERNATE 0x00080 /* alternate form requested */
  129. errno_t _safecrt_cfltcvt(double *arg, char *buffer, size_t sizeInBytes, int type, int precision, int flags)
  130. {
  131. char format[FORMATSIZE];
  132. size_t formatlen = 0;
  133. int retvalue;
  134. if (flags & 1)
  135. {
  136. type -= 'a' - 'A';
  137. }
  138. formatlen = 0;
  139. format[formatlen++] = '%';
  140. if (flags & FL_ALTERNATE)
  141. {
  142. format[formatlen++] = '#';
  143. }
  144. format[formatlen++] = '.';
  145. _itoa_s(precision, format + formatlen, FORMATSIZE - formatlen, 10);
  146. formatlen = strlen(format);
  147. format[formatlen++] = (char)type;
  148. format[formatlen] = 0;
  149. buffer[sizeInBytes - 1] = 0;
  150. retvalue = _snprintf(buffer, sizeInBytes, format, *arg);
  151. if (buffer[sizeInBytes - 1] != 0 || retvalue <= 0)
  152. {
  153. buffer[0] = 0;
  154. return EINVAL;
  155. }
  156. return 0;
  157. }
  158. #ifndef _LIBSAFECRT_SGX_CONFIG
  159. /***
  160. * _safecrt_fassign - convert a string into a float or double.
  161. ****/
  162. void _safecrt_fassign(int flag, void* argument, char* number )
  163. {
  164. if ( flag != 0 ) // double
  165. {
  166. double dblValue = 0.0;
  167. (void)sscanf( number, "%lf", &dblValue );
  168. *( ( double* )argument ) = dblValue;
  169. }
  170. else // float
  171. {
  172. float fltValue = 0.0;
  173. (void)sscanf( number, "%f", &fltValue );
  174. *( ( float* )argument ) = fltValue;
  175. }
  176. }
  177. /***
  178. * _safecrt_wfassign - convert a char16_t string into a float or double.
  179. ****/
  180. void _safecrt_wfassign(int flag, void* argument, char16_t* number )
  181. {
  182. // We cannot use system functions for this - they
  183. // assume that char16_t is four bytes, while we assume
  184. // two. So, we need to convert to a regular char string
  185. // without using any system functions. To do this,
  186. // we'll assume that the numbers are in the 0-9 range and
  187. // do a simple conversion.
  188. char* numberAsChars = ( char* )number;
  189. int position = 0;
  190. // do the convert
  191. while ( number[ position ] != 0 )
  192. {
  193. numberAsChars[ position ] = ( char )( number[ position ] & 0x00FF );
  194. position++;
  195. }
  196. numberAsChars[ position ] = ( char )( number[ position ] & 0x00FF );
  197. // call the normal char version
  198. _safecrt_fassign( flag, argument, numberAsChars );
  199. }
  200. #endif
  201. /***
  202. * _minimal_chartowchar - do a simple char to wchar conversion.
  203. ****/
  204. int _minimal_chartowchar( char16_t* outWChar, const char* inChar )
  205. {
  206. *outWChar = ( char16_t )( ( unsigned short )( ( unsigned char )( *inChar ) ) );
  207. return 1;
  208. }