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