1 /*** 2 *mbscpy_s_l.c - Copy one string to another (MBCS) 3 * 4 * Copyright (c) Microsoft Corporation. All rights reserved. 5 * 6 *Purpose: 7 * Copy one string to another (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 <corecrt_internal_securecrt.h> 16 17 errno_t __cdecl _mbscpy_s_l(unsigned char *_Dst, size_t _SizeInBytes, const unsigned char *_Src, _LOCALE_ARG_DECL) 18 { 19 unsigned char *p; 20 size_t available; 21 BOOL fIsLeadPrefix; 22 23 /* validation section */ 24 _VALIDATE_STRING(_Dst, _SizeInBytes); 25 _VALIDATE_POINTER_RESET_STRING(_Src, _Dst, _SizeInBytes); 26 27 _LOCALE_UPDATE; 28 if (_LOCALE_SHORTCUT_TEST) 29 { 30 return strcpy_s((char *)_Dst, _SizeInBytes, (const char *)_Src); 31 } 32 33 p = _Dst; 34 available = _SizeInBytes; 35 while ((*p++ = *_Src++) != 0 && --available > 0) 36 { 37 } 38 39 /* 40 * If we ran out of destination bytes then we did so before copying null. 41 * Only exception to that is if last mbc was invalid (leadbyte+null), which 42 * is treated as null. In that case clear the copied lead byte and return ok. 43 */ 44 45 if (available == 0) 46 { 47 if (*_Src == 0) { 48 _ISMBBLEADPREFIX(fIsLeadPrefix,_Dst,p-1); 49 if (fIsLeadPrefix) 50 { 51 p[-1] = 0; 52 _RETURN_MBCS_ERROR; 53 } 54 } 55 _RESET_STRING(_Dst, _SizeInBytes); 56 _RETURN_BUFFER_TOO_SMALL(_Dst, _SizeInBytes); 57 } 58 59 /* 60 * Otherwise we have space left in the dst buffer and stopped copying because 61 * we saw a null in the src. If null is part of invalid MBC (lead byte + null) 62 * then clear the lead byte also. 63 */ 64 65 _ISMBBLEADPREFIX(fIsLeadPrefix, _Dst, p-2); 66 if (fIsLeadPrefix && (p - 2) >= _Dst) 67 { 68 p[-2] = 0; 69 available++; 70 _FILL_STRING(_Dst, _SizeInBytes, _SizeInBytes - available + 1); 71 _RETURN_MBCS_ERROR; 72 } 73 74 _FILL_STRING(_Dst, _SizeInBytes, _SizeInBytes - available + 1); 75 _RETURN_NO_ERROR; 76 } 77