xref: /reactos/sdk/lib/ucrt/mbstring/mbsnbcpy.cpp (revision e3e520d1)
1 /***
2 *mbsnbcpy.c - Copy one string to another, n bytes only (MBCS)
3 *
4 *       Copyright (c) Microsoft Corporation.  All rights reserved.
5 *
6 *Purpose:
7 *       Copy one string to another, n bytes only (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 <locale.h>
16 #include <string.h>
17 
18 #pragma warning(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) // 26018
19 
20 /***
21 * _mbsnbcpy - Copy one string to another, n bytes only (MBCS)
22 *
23 *Purpose:
24 *       Copies exactly cnt bytes from src to dst.  If strlen(src) < cnt, the
25 *       remaining character are padded with null bytes.  If strlen >= cnt, no
26 *       terminating null byte is added.  2-byte MBCS characters are handled
27 *       correctly.
28 *
29 *Entry:
30 *       unsigned char *dst = destination for copy
31 *       unsigned char *src = source for copy
32 *       int cnt = number of bytes to copy
33 *
34 *Exit:
35 *       returns dst = destination of copy
36 *
37 *Exceptions:
38 *       Input parameters are validated. Refer to the validation section of the function.
39 *
40 *******************************************************************************/
41 
42 #pragma warning(suppress:6101) // Returning uninitialized memory '*dst'.  A successful path through the function does not set the named _Out_ parameter.
43 unsigned char * __cdecl _mbsnbcpy_l(
44         unsigned char *dst,
45         const unsigned char *src,
46         size_t cnt,
47         _locale_t plocinfo
48         )
49 {
50 
51         unsigned char *start = dst;
52         _LocaleUpdate _loc_update(plocinfo);
53 
54         /* validation section */
55         _VALIDATE_RETURN(dst != nullptr || cnt == 0, EINVAL, nullptr);
56         _VALIDATE_RETURN(src != nullptr || cnt == 0, EINVAL, nullptr);
57 
58         _BEGIN_SECURE_CRT_DEPRECATION_DISABLE
59         if (_loc_update.GetLocaleT()->mbcinfo->ismbcodepage == 0)
60 #pragma warning(suppress:__WARNING_BANNED_API_USAGE)
61             return (unsigned char *)strncpy((char *)dst, (const char *)src, cnt);
62         _END_SECURE_CRT_DEPRECATION_DISABLE
63 
64         while (cnt) {
65 
66             cnt--;
67             if ( _ismbblead_l(*src, _loc_update.GetLocaleT()) ) {
68                 *dst++ = *src++;
69                 if (!cnt) {
70                     dst[-1] = '\0';
71                     break;
72                 }
73                 cnt--;
74                 if ((*dst++ = *src++) == '\0') {
75                     dst[-2] = '\0';
76                     break;
77                 }
78             }
79 
80             else
81                 if ((*dst++ = *src++) == '\0')
82                     break;
83 
84         }
85 
86         /* pad with nulls as needed */
87 
88         while (cnt--)
89             *dst++ = '\0';
90 
91 #pragma warning(suppress:__WARNING_POSTCONDITION_NULLTERMINATION_VIOLATION) // 26036
92         return start;
93 }
94 unsigned char * (__cdecl _mbsnbcpy)(
95         unsigned char *dst,
96         const unsigned char *src,
97         size_t cnt
98         )
99 {
100     _BEGIN_SECURE_CRT_DEPRECATION_DISABLE
101     return _mbsnbcpy_l(dst, src, cnt, nullptr);
102     _END_SECURE_CRT_DEPRECATION_DISABLE
103 }
104