// // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // /*** * mbusafecrt.c - implementaion of support functions and data for MBUSafeCRT * * * Purpose: * This file contains the implementation of support functions and * data for MBUSafeCRT declared in mbusafecrt.h and mbusafecrt_internal.h. ****/ #ifndef _LIBSAFECRT_SGX_CONFIG #include "pal/palinternal.h" #endif #include #include #include #include "mbusafecrt_internal.h" #ifndef _LIBSAFECRT_SGX_CONFIG /* global data */ tSafeCRT_AssertFuncPtr sMBUSafeCRTAssertFunc = NULL; /*** * MBUSafeCRTSetAssertFunc - Set the function called when an assert fails. ****/ void MBUSafeCRTSetAssertFunc( tSafeCRT_AssertFuncPtr inAssertFuncPtr ) { /* set it */ sMBUSafeCRTAssertFunc = inAssertFuncPtr; } #endif /*** * _putc_nolock - putc for the miniFILE stream. ****/ int _putc_nolock( char inChar, miniFILE* inStream ) { int returnValue = EOF; inStream->_cnt -= (int)sizeof( char ); if ( ( inStream->_cnt ) >= 0 ) { *( inStream->_ptr ) = inChar; inStream->_ptr += (int)sizeof( char ); returnValue = ( int )inChar; } return returnValue; } /*** * _putwc_nolock - putwc for the miniFILE stream. ****/ int _putwc_nolock( char16_t inChar, miniFILE* inStream ) { int returnValue = WEOF; inStream->_cnt -= (int)sizeof( char16_t ); if ( ( inStream->_cnt ) >= 0 ) { *( ( char16_t* )( inStream->_ptr ) ) = inChar; inStream->_ptr += (int)sizeof( char16_t ); returnValue = ( int )inChar; } return returnValue; } #ifndef _LIBSAFECRT_SGX_CONFIG /*** * _getc_nolock - getc for the miniFILE stream. ****/ int _getc_nolock( miniFILE* inStream ) { int returnValue = EOF; if ( ( inStream->_cnt ) >= ( int )( sizeof( char ) ) ) { inStream->_cnt -= sizeof( char ); returnValue = ( int )( *( inStream->_ptr ) ); inStream->_ptr += sizeof( char ); } return returnValue; } /*** * _getwc_nolock - getc for the miniFILE stream. ****/ int _getwc_nolock( miniFILE* inStream ) { int returnValue = EOF; if ( ( inStream->_cnt ) >= ( int )( sizeof( char16_t ) ) ) { inStream->_cnt -= sizeof( char16_t ); returnValue = ( int )( *( ( char16_t* )( inStream->_ptr ) ) ); inStream->_ptr += sizeof( char16_t ); } return returnValue; } /*** * _ungetc_nolock - ungetc for the miniFILE stream. ****/ int _ungetc_nolock( char inChar, miniFILE* inStream ) { int returnValue = EOF; if ( ( size_t )( ( inStream->_ptr ) - ( inStream->_base ) ) >= ( sizeof( char ) ) ) { inStream->_cnt += sizeof( char ); inStream->_ptr -= sizeof( char ); return ( int )inChar; } return returnValue; } /*** * _ungetwc_nolock - ungetwc for the miniFILE stream. ****/ int _ungetwc_nolock( char16_t inChar, miniFILE* inStream ) { int returnValue = WEOF; if ( ( size_t )( ( inStream->_ptr ) - ( inStream->_base ) ) >= ( sizeof( char16_t ) ) ) { inStream->_cnt += sizeof( char16_t ); inStream->_ptr -= sizeof( char16_t ); returnValue = ( unsigned short )inChar; } return returnValue; } #endif /*** * _safecrt_cfltcvt - convert a float to an ascii string. * Uses sprintf - this usage is OK. ****/ /* routine used for floating-point output */ #define FORMATSIZE 30 #define _snprintf snprintf // taken from output.inl #define FL_ALTERNATE 0x00080 /* alternate form requested */ errno_t _safecrt_cfltcvt(double *arg, char *buffer, size_t sizeInBytes, int type, int precision, int flags) { char format[FORMATSIZE]; size_t formatlen = 0; int retvalue; if (flags & 1) { type -= 'a' - 'A'; } formatlen = 0; format[formatlen++] = '%'; if (flags & FL_ALTERNATE) { format[formatlen++] = '#'; } format[formatlen++] = '.'; _itoa_s(precision, format + formatlen, FORMATSIZE - formatlen, 10); formatlen = strlen(format); format[formatlen++] = (char)type; format[formatlen] = 0; buffer[sizeInBytes - 1] = 0; retvalue = _snprintf(buffer, sizeInBytes, format, *arg); if (buffer[sizeInBytes - 1] != 0 || retvalue <= 0) { buffer[0] = 0; return EINVAL; } return 0; } #ifndef _LIBSAFECRT_SGX_CONFIG /*** * _safecrt_fassign - convert a string into a float or double. ****/ void _safecrt_fassign(int flag, void* argument, char* number ) { if ( flag != 0 ) // double { double dblValue = 0.0; (void)sscanf( number, "%lf", &dblValue ); *( ( double* )argument ) = dblValue; } else // float { float fltValue = 0.0; (void)sscanf( number, "%f", &fltValue ); *( ( float* )argument ) = fltValue; } } /*** * _safecrt_wfassign - convert a char16_t string into a float or double. ****/ void _safecrt_wfassign(int flag, void* argument, char16_t* number ) { // We cannot use system functions for this - they // assume that char16_t is four bytes, while we assume // two. So, we need to convert to a regular char string // without using any system functions. To do this, // we'll assume that the numbers are in the 0-9 range and // do a simple conversion. char* numberAsChars = ( char* )number; int position = 0; // do the convert while ( number[ position ] != 0 ) { numberAsChars[ position ] = ( char )( number[ position ] & 0x00FF ); position++; } numberAsChars[ position ] = ( char )( number[ position ] & 0x00FF ); // call the normal char version _safecrt_fassign( flag, argument, numberAsChars ); } #endif /*** * _minimal_chartowchar - do a simple char to wchar conversion. ****/ int _minimal_chartowchar( char16_t* outWChar, const char* inChar ) { *outWChar = ( char16_t )( ( unsigned short )( ( unsigned char )( *inChar ) ) ); return 1; }