1 /*** 2 *strupr.c - routine to map lower-case characters in a string to upper-case 3 * 4 * Copyright (c) Microsoft Corporation. All rights reserved. 5 * 6 *Purpose: 7 * Converts all the lower case characters in a string to upper case, 8 * in place. 9 * 10 *******************************************************************************/ 11 #include <corecrt_internal.h> 12 #include <ctype.h> 13 #include <corecrt_internal_securecrt.h> 14 #include <limits.h> 15 #include <locale.h> 16 #include <string.h> 17 18 #pragma warning(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) // 26018 19 20 /*** 21 *char *_strupr(string) - map lower-case characters in a string to upper-case 22 * 23 *Purpose: 24 * _strupr() converts lower-case characters in a null-terminated string 25 * to their upper-case equivalents. Conversion is done in place and 26 * characters other than lower-case letters are not modified. 27 * 28 * In the C locale, this function modifies only 7-bit ASCII characters 29 * in the range 0x61 through 0x7A ('a' through 'z'). 30 * 31 * If the locale is not the 'C' locale, LCMapString() is used to do 32 * the work. Assumes enough space in the string to hold result. 33 * 34 *Entry: 35 * char *string - string to change to upper case 36 * 37 *Exit: 38 * input string address 39 * 40 *Exceptions: 41 * The original string is returned unchanged on any error, and errno is set. 42 * 43 *******************************************************************************/ 44 45 extern "C" char * __cdecl _strupr_l ( 46 char * string, 47 _locale_t plocinfo 48 ) 49 { 50 _strupr_s_l(string, (size_t)(-1), plocinfo); 51 return (string); 52 } 53 54 extern "C" char * __cdecl _strupr ( 55 char * string 56 ) 57 { 58 if (!__acrt_locale_changed()) 59 { 60 /* validation section */ 61 _VALIDATE_RETURN(string != nullptr, EINVAL, nullptr); 62 63 char *cp; /* traverses string for C locale conversion */ 64 65 for ( cp = string ; *cp ; ++cp ) 66 if ( ('a' <= *cp) && (*cp <= 'z') ) 67 *cp -= 'a' - 'A'; 68 69 return(string); 70 } 71 else 72 { 73 _strupr_s_l(string, (size_t)(-1), nullptr); 74 return (string); 75 } 76 } 77 78 /*** 79 *errno_t _strupr_s(string, size_t) - map lower-case characters in a string to upper-case 80 * 81 *Purpose: 82 * _strupr() converts lower-case characters in a null-terminated string 83 * to their upper-case equivalents. Conversion is done in place and 84 * characters other than lower-case letters are not modified. 85 * 86 * In the C locale, this function modifies only 7-bit ASCII characters 87 * in the range 0x61 through 0x7A ('a' through 'z'). 88 * 89 * If the locale is not the 'C' locale, LCMapString() is used to do 90 * the work. Assumes enough space in the string to hold result. 91 * 92 *Entry: 93 * char *string - string to change to upper case 94 * size_t sizeInBytes - size of the destination buffer 95 * 96 *Exit: 97 * the error code 98 * 99 *Exceptions: 100 * The original string is returned unchanged on any error, and errno is set. 101 * 102 *******************************************************************************/ 103 104 static errno_t __cdecl _strupr_s_l_stat ( 105 _Inout_updates_z_(sizeInBytes) char * const string, 106 size_t const sizeInBytes, 107 _locale_t const plocinfo 108 ) throw() 109 { 110 int dstsize; /* size of dst string buffer (include null) */ 111 size_t stringlen; 112 113 /* validation section */ 114 _VALIDATE_RETURN_ERRCODE(string != nullptr, EINVAL); 115 stringlen = strnlen(string, sizeInBytes); 116 if (stringlen >= sizeInBytes) 117 { 118 _RESET_STRING(string, sizeInBytes); 119 _RETURN_DEST_NOT_NULL_TERMINATED(string, sizeInBytes); 120 } 121 _FILL_STRING(string, sizeInBytes, stringlen + 1); 122 123 if ( plocinfo->locinfo->locale_name[LC_CTYPE] == nullptr ) 124 { 125 char *cp=string; /* traverses string for C locale conversion */ 126 127 for ( ; *cp ; ++cp ) 128 { 129 if ( ('a' <= *cp) && (*cp <= 'z') ) 130 { 131 *cp -= 'a' - 'A'; 132 } 133 } 134 135 return 0; 136 } /* C locale */ 137 138 /* Inquire size of dst string */ 139 if ( 0 == (dstsize = __acrt_LCMapStringA( 140 plocinfo, 141 plocinfo->locinfo->locale_name[LC_CTYPE], 142 LCMAP_UPPERCASE, 143 string, 144 -1, 145 nullptr, 146 0, 147 plocinfo->locinfo->_public._locale_lc_codepage, 148 TRUE )) ) 149 { 150 errno = EILSEQ; 151 return errno; 152 } 153 154 if (sizeInBytes < (size_t)dstsize) 155 { 156 _RESET_STRING(string, sizeInBytes); 157 _RETURN_BUFFER_TOO_SMALL(string, sizeInBytes); 158 } 159 160 /* Allocate space for dst */ 161 __crt_scoped_stack_ptr<char> const dst(_malloca_crt_t(char, dstsize)); 162 if (!dst) 163 { 164 errno = ENOMEM; 165 return errno; 166 } 167 168 /* Map src string to dst string in alternate case */ 169 if (__acrt_LCMapStringA( 170 plocinfo, 171 plocinfo->locinfo->locale_name[LC_CTYPE], 172 LCMAP_UPPERCASE, 173 string, 174 -1, 175 dst.get(), 176 dstsize, 177 plocinfo->locinfo->_public._locale_lc_codepage, 178 TRUE ) != 0) 179 { 180 /* copy dst string to return string */ 181 return strcpy_s(string, sizeInBytes, dst.get()); 182 } 183 else 184 { 185 return errno = EILSEQ; 186 } 187 } 188 189 extern "C" errno_t __cdecl _strupr_s_l ( 190 char * string, 191 size_t sizeInBytes, 192 _locale_t plocinfo 193 ) 194 { 195 _LocaleUpdate _loc_update(plocinfo); 196 197 return _strupr_s_l_stat(string, sizeInBytes, _loc_update.GetLocaleT()); 198 } 199 200 extern "C" errno_t __cdecl _strupr_s ( 201 char * string, 202 size_t sizeInBytes 203 ) 204 { 205 return _strupr_s_l(string, sizeInBytes, nullptr); 206 } 207