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