Reactos
at master 122 lines 3.1 kB view raw
1/*** 2*mbscat_s_l.c - Concatenate one string to another (MBCS) 3* 4* Copyright (c) Microsoft Corporation. All rights reserved. 5* 6*Purpose: 7* Concatenate 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 18 19errno_t __cdecl _mbscat_s_l(unsigned char *_Dst, size_t _SizeInBytes, const unsigned char *_Src, _LOCALE_ARG_DECL) 20{ 21 unsigned char *p; 22 size_t available; 23 BOOL fFoundInvalidMBC, fIsLeadPrefix; 24 25 /* validation section */ 26 _VALIDATE_STRING(_Dst, _SizeInBytes); 27 _VALIDATE_POINTER_RESET_STRING(_Src, _Dst, _SizeInBytes); 28 29 _LOCALE_UPDATE; 30 if (_LOCALE_SHORTCUT_TEST) 31 { 32 return strcat_s((char *)_Dst, _SizeInBytes, (const char *)_Src); 33 } 34 35 fFoundInvalidMBC = FALSE; 36 p = _Dst; 37 available = _SizeInBytes; 38 while (available > 0 && *p != 0) 39 { 40 p++; 41 available--; 42 } 43 44 /* 45 * Ran out of room while looking for end of dst string. 46 * p points 1 past end of buffer. We can't look past 47 * end of buffer so can't tell if dst ended with an 48 * invalid mbc. 49 */ 50 51 if (available == 0) 52 { 53 _RESET_STRING(_Dst, _SizeInBytes); 54 _RETURN_DEST_NOT_NULL_TERMINATED(_Dst, _SizeInBytes); 55 } 56 57 /* 58 * Otherwise we have space available, p points at null that lies 59 * within _SizeInBytes, so available > 0. Check if dst ended with 60 * an invalid MBC (lead+null), if so then clear that lead byte, 61 * move the pointer back one and increase available by one. 62 */ 63 64 _ISMBBLEADPREFIX(fIsLeadPrefix, _Dst, p-1); 65 if (fIsLeadPrefix) 66 { 67 fFoundInvalidMBC = TRUE; 68 p--; 69 *p = 0; 70 available++; 71 } 72 73 /* Append dst to src. */ 74 75 while ((*p++ = *_Src++) != 0 && --available > 0) 76 { 77 } 78 79 /* 80 * We've run out of room in the destination before finding null in the src. 81 * It could be that the src was terminated with an invalid mbc (lead+null). 82 * In that case its ok to clear the copied lead byte and return mbcs_error. 83 */ 84 85 if (available == 0) 86 { 87 if (*_Src == 0) 88 { 89 _ISMBBLEADPREFIX(fIsLeadPrefix, _Dst, p-1); 90 if (fIsLeadPrefix) 91 { 92 /* the source string ended with a lead byte: we remove it */ 93 p[-1] = 0; 94 _RETURN_MBCS_ERROR; 95 } 96 } 97 _RESET_STRING(_Dst, _SizeInBytes); 98 _RETURN_BUFFER_TOO_SMALL(_Dst, _SizeInBytes); 99 } 100 101 /* 102 * If the src string ended with an invalid mbc (lead+null) then clear the 103 * lead byte. 104 */ 105 106 _ISMBBLEADPREFIX(fIsLeadPrefix, _Dst, p-2); 107 if (fIsLeadPrefix) 108 { 109 p[-2] = 0; 110 available++; 111 fFoundInvalidMBC = TRUE; 112 } 113 114 _FILL_STRING(_Dst, _SizeInBytes, _SizeInBytes - available + 1); 115 116 if (fFoundInvalidMBC) 117 { 118 _RETURN_MBCS_ERROR; 119 } 120 121 _RETURN_NO_ERROR; 122}