diff --git a/sdk/lib/crt/mbstring/mbsncat.c b/sdk/lib/crt/mbstring/mbsncat.c index 21e63d0c0a1..a3fc0b69970 100644 --- a/sdk/lib/crt/mbstring/mbsncat.c +++ b/sdk/lib/crt/mbstring/mbsncat.c @@ -6,12 +6,18 @@ * PROGRAMER: Ariadne * UPDATE HISTORY: * 12/04/99: Created + * 11/10/2025 Somewhat synced with Wine 10.0 by Doug Lyons */ #include #include #include +static inline unsigned char* u_strncat( unsigned char* dst, const unsigned char* src, size_t len ) +{ + return (unsigned char*)strncat( (char*)dst, (const char*)src, len); +} + size_t _mbclen2(const unsigned int s); unsigned char *_mbset (unsigned char *string, int c); @@ -20,25 +26,31 @@ unsigned char *_mbset (unsigned char *string, int c); */ unsigned char *_mbsncat (unsigned char *dst, const unsigned char *src, size_t n) { - int c; - unsigned char *save = dst; + MSVCRT_pthreadmbcinfo mbcinfo = get_mbcinfo(); - while ((c = _mbsnextc (dst))) - dst = _mbsinc (dst); + if (!n) + return dst; - while (n-- > 0 && (c = _mbsnextc (src))) { - - _mbset (dst, c); - - dst = _mbsinc (dst); - - src = _mbsinc ((unsigned char *) src); + if (!dst || !src) ERR("Bad Parameter\n"); + if (mbcinfo->ismbcodepage) + { + unsigned char *res = dst; + while (*dst) + { + if (_ismbblead(*dst++)) + dst++; + } + while (*src && n--) + { + *dst++ = *src; + if (_ismbblead(*src++)) + *dst++ = *src++; + } + *dst = '\0'; + return res; } - - *dst = '\0'; - - return save; + return u_strncat(dst, src, n); /* ASCII CP */ } /* @@ -46,22 +58,42 @@ unsigned char *_mbsncat (unsigned char *dst, const unsigned char *src, size_t n) */ unsigned char * _mbsnbcat(unsigned char *dst, const unsigned char *src, size_t n) { - unsigned char *d; - const unsigned char *s = src; - if (n != 0) { - d = dst + _mbslen(dst); // get the end of string - d += _mbclen2(*d); // move 1 or 2 up + MSVCRT_pthreadmbcinfo mbcinfo = get_mbcinfo(); + unsigned char *s; - do { - if ((*d++ = *s++) == 0) - { - while (--n != 0) - *d++ = 0; - break; - } - if ( !(n==1 && _ismbblead(*s)) ) - n--; - } while (n > 0); - } - return dst; + /* replace TRACE with ERR for debug output */ + TRACE("Src %s\n", wine_dbgstr_an((const char*)src, n)); + + if (!dst || !src) ERR("Bad Parameter\n"); + + if (!src && !dst && !n && !MSVCRT_CHECK_PMT(dst && src)) + return NULL; + + if (mbcinfo->ismbcodepage) + { + unsigned char *res = dst; + while (*dst) + { + if (_ismbblead(*dst++)) + { + if (*dst) + { + dst++; + } + else + { + /* as per msdn overwrite the lead byte in front of '\0' */ + dst--; + break; + } + } + } + while (*src && n--) *dst++ = *src++; + *dst = '\0'; + return res; + } + s = u_strncat(dst, src, n); /* ASCII CP */ + /* replace TRACE with ERR for debug output */ + TRACE("Dst %s\n", wine_dbgstr_an((const char*)dst, _mbslen(dst))); + return s; }