1 /*** 2 *mbsupr.c - Convert string upper case (MBCS) 3 * 4 * Copyright (c) Microsoft Corporation. All rights reserved. 5 * 6 *Purpose: 7 * Convert string upper case (MBCS) 8 * 9 *******************************************************************************/ 10 #ifndef _MBCS 11 #error This file should only be compiled with _MBCS defined 12 #endif 13 14 #include <corecrt_internal_mbstring.h> 15 #include <corecrt_internal_securecrt.h> 16 #include <locale.h> 17 #include <string.h> 18 19 #pragma warning(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) 20 21 /*** 22 * _mbsupr - Convert string upper case (MBCS) 23 * 24 *Purpose: 25 * Converts all the lower case characters in a string 26 * to upper case in place. Handles MBCS chars correctly. 27 * 28 *Entry: 29 * unsigned char *string = pointer to string 30 * 31 *Exit: 32 * Returns a pointer to the input string. 33 * Returns nullptr on error. 34 * 35 *Exceptions: 36 * Input parameters are validated. Refer to the validation section of the function. 37 * 38 *******************************************************************************/ 39 40 extern "C" errno_t __cdecl _mbsupr_s_l( 41 unsigned char *string, 42 size_t sizeInBytes, 43 _locale_t plocinfo 44 ) 45 { 46 size_t stringlen; 47 48 /* validation section */ 49 _VALIDATE_RETURN_ERRCODE((string != nullptr && sizeInBytes > 0) || (string == nullptr && sizeInBytes == 0), EINVAL); 50 51 if (string == nullptr) 52 { 53 /* nothing to do */ 54 return 0; 55 } 56 57 stringlen = strnlen((char *)string, sizeInBytes); 58 if (stringlen >= sizeInBytes) 59 { 60 _RESET_STRING(string, sizeInBytes); 61 _RETURN_DEST_NOT_NULL_TERMINATED(string, sizeInBytes); 62 } 63 _FILL_STRING(string, sizeInBytes, stringlen + 1); 64 65 unsigned char *cp, *dst; 66 _LocaleUpdate _loc_update(plocinfo); 67 68 for (cp = string, dst = string; *cp; ++cp) 69 { 70 if ( _ismbblead_l(*cp, _loc_update.GetLocaleT()) ) 71 { 72 73 74 int retval; 75 unsigned char ret[4]; 76 77 if ( (retval = __acrt_LCMapStringA( 78 _loc_update.GetLocaleT(), 79 _loc_update.GetLocaleT()->mbcinfo->mblocalename, 80 LCMAP_UPPERCASE, 81 (const char *)cp, 82 2, 83 (char *)ret, 84 2, 85 _loc_update.GetLocaleT()->mbcinfo->mbcodepage, 86 TRUE )) == 0 ) 87 { 88 errno = EILSEQ; 89 _RESET_STRING(string, sizeInBytes); 90 return errno; 91 } 92 93 *(dst++) = ret[0]; 94 ++cp; 95 if (retval > 1) 96 { 97 *(dst++) = ret[1]; 98 } 99 100 101 } 102 else 103 /* single byte, macro version */ 104 *(dst++) = (unsigned char) _mbbtoupper_l(*cp, _loc_update.GetLocaleT()); 105 } 106 /* null terminate the string */ 107 *dst = '\0'; 108 109 return 0; 110 } 111 112 extern "C" errno_t (__cdecl _mbsupr_s)( 113 unsigned char *string, 114 size_t sizeInBytes 115 ) 116 { 117 return _mbsupr_s_l(string, sizeInBytes, nullptr); 118 } 119 120 extern "C" unsigned char * (__cdecl _mbsupr_l)( 121 unsigned char *string, 122 _locale_t plocinfo 123 ) 124 { 125 return (_mbsupr_s_l(string, (string == nullptr ? 0 : (size_t)-1), plocinfo) == 0 ? string : nullptr); 126 } 127 128 extern "C" unsigned char * (__cdecl _mbsupr)( 129 unsigned char *string 130 ) 131 { 132 return (_mbsupr_s_l(string, (string == nullptr ? 0 : (size_t)-1), nullptr) == 0 ? string : nullptr); 133 } 134