Skip to content

Commit 42e5fa0

Browse files
authored
[CRT] Fix _mbsn(b)cat functions by using Wine 10.0 as a guide (reactos#8456)
This fixes the HeapMemView - Help - About text display. CORE-19308
1 parent 8501523 commit 42e5fa0

File tree

1 file changed

+64
-32
lines changed

1 file changed

+64
-32
lines changed

sdk/lib/crt/mbstring/mbsncat.c

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@
66
* PROGRAMER: Ariadne
77
* UPDATE HISTORY:
88
* 12/04/99: Created
9+
* 11/10/2025 Somewhat synced with Wine 10.0 by Doug Lyons
910
*/
1011

1112
#include <precomp.h>
1213
#include <mbstring.h>
1314
#include <string.h>
1415

16+
static inline unsigned char* u_strncat( unsigned char* dst, const unsigned char* src, size_t len )
17+
{
18+
return (unsigned char*)strncat( (char*)dst, (const char*)src, len);
19+
}
20+
1521
size_t _mbclen2(const unsigned int s);
1622
unsigned char *_mbset (unsigned char *string, int c);
1723

@@ -20,48 +26,74 @@ unsigned char *_mbset (unsigned char *string, int c);
2026
*/
2127
unsigned char *_mbsncat (unsigned char *dst, const unsigned char *src, size_t n)
2228
{
23-
int c;
24-
unsigned char *save = dst;
25-
26-
while ((c = _mbsnextc (dst)))
27-
dst = _mbsinc (dst);
28-
29-
while (n-- > 0 && (c = _mbsnextc (src))) {
30-
31-
_mbset (dst, c);
29+
MSVCRT_pthreadmbcinfo mbcinfo = get_mbcinfo();
3230

33-
dst = _mbsinc (dst);
31+
if (!n)
32+
return dst;
3433

35-
src = _mbsinc ((unsigned char *) src);
34+
if (!dst || !src) ERR("Bad Parameter\n");
3635

36+
if (mbcinfo->ismbcodepage)
37+
{
38+
unsigned char *res = dst;
39+
while (*dst)
40+
{
41+
if (_ismbblead(*dst++))
42+
dst++;
43+
}
44+
while (*src && n--)
45+
{
46+
*dst++ = *src;
47+
if (_ismbblead(*src++))
48+
*dst++ = *src++;
49+
}
50+
*dst = '\0';
51+
return res;
3752
}
38-
39-
*dst = '\0';
40-
41-
return save;
53+
return u_strncat(dst, src, n); /* ASCII CP */
4254
}
4355

4456
/*
4557
* @implemented
4658
*/
4759
unsigned char * _mbsnbcat(unsigned char *dst, const unsigned char *src, size_t n)
4860
{
49-
unsigned char *d;
50-
const unsigned char *s = src;
51-
if (n != 0) {
52-
d = dst + _mbslen(dst); // get the end of string
53-
d += _mbclen2(*d); // move 1 or 2 up
61+
MSVCRT_pthreadmbcinfo mbcinfo = get_mbcinfo();
62+
unsigned char *s;
63+
64+
/* replace TRACE with ERR for debug output */
65+
TRACE("Src %s\n", wine_dbgstr_an((const char*)src, n));
5466

55-
do {
56-
if ((*d++ = *s++) == 0)
57-
{
58-
while (--n != 0)
59-
*d++ = 0;
60-
break;
61-
}
62-
if ( !(n==1 && _ismbblead(*s)) )
63-
n--;
64-
} while (n > 0);
65-
}
66-
return dst;
67+
if (!dst || !src) ERR("Bad Parameter\n");
68+
69+
if (!src && !dst && !n && !MSVCRT_CHECK_PMT(dst && src))
70+
return NULL;
71+
72+
if (mbcinfo->ismbcodepage)
73+
{
74+
unsigned char *res = dst;
75+
while (*dst)
76+
{
77+
if (_ismbblead(*dst++))
78+
{
79+
if (*dst)
80+
{
81+
dst++;
82+
}
83+
else
84+
{
85+
/* as per msdn overwrite the lead byte in front of '\0' */
86+
dst--;
87+
break;
88+
}
89+
}
90+
}
91+
while (*src && n--) *dst++ = *src++;
92+
*dst = '\0';
93+
return res;
94+
}
95+
s = u_strncat(dst, src, n); /* ASCII CP */
96+
/* replace TRACE with ERR for debug output */
97+
TRACE("Dst %s\n", wine_dbgstr_an((const char*)dst, _mbslen(dst)));
98+
return s;
6799
}

0 commit comments

Comments
 (0)