1 /**
2 * Copyright 2020 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define SECUREC_INLINE_DO_MEMCPY 1
18
19 #include "securecutil.h"
20
21 /*
22 * Befor this function, the basic parameter checking has been done
23 */
SecDoWcscat(wchar_t * strDest,size_t destMax,const wchar_t * strSrc)24 static errno_t SecDoWcscat(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
25 {
26 size_t destLen;
27 size_t srcLen;
28 size_t maxCount; /* Store the maximum available count */
29
30 /* To calculate the length of a wide character, the parameter must be a wide character */
31 SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen);
32 maxCount = destMax - destLen;
33 SECUREC_CALC_WSTR_LEN(strSrc, maxCount, &srcLen);
34
35 if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
36 strDest[0] = L'\0';
37 if (strDest + destLen <= strSrc && destLen == destMax) {
38 SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
39 return EINVAL_AND_RESET;
40 }
41 SECUREC_ERROR_BUFFER_OVERLAP("wcscat_s");
42 return EOVERLAP_AND_RESET;
43 }
44 if (srcLen + destLen >= destMax || strDest == strSrc) {
45 strDest[0] = L'\0';
46 if (destLen == destMax) {
47 SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
48 return EINVAL_AND_RESET;
49 }
50 SECUREC_ERROR_INVALID_RANGE("wcscat_s");
51 return ERANGE_AND_RESET;
52 }
53 SecDoMemcpy(strDest + destLen, strSrc, (srcLen + 1) * sizeof(wchar_t)); /* single character length include \0 */
54 return EOK;
55 }
56
57 /*
58 * <FUNCTION DESCRIPTION>
59 * The wcscat_s function appends a copy of the wide string pointed to by strSrc
60 * (including the terminating null wide character)
61 * to the end of the wide string pointed to by strDest.
62 * The arguments and return value of wcscat_s are wide-character strings.
63 *
64 * The wcscat_s function appends strSrc to strDest and terminates the resulting
65 * string with a null character. The initial character of strSrc overwrites the
66 * terminating null character of strDest. wcscat_s will return EOVERLAP_AND_RESET if the
67 * source and destination strings overlap.
68 *
69 * Note that the second parameter is the total size of the buffer, not the
70 * remaining size.
71 *
72 * <INPUT PARAMETERS>
73 * strDest Null-terminated destination string buffer.
74 * destMax Size of the destination string buffer.
75 * strSrc Null-terminated source string buffer.
76 *
77 * <OUTPUT PARAMETERS>
78 * strDest is updated
79 *
80 * <RETURN VALUE>
81 * EOK Success
82 * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
83 * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or
84 * (strDest != NULL and strSrc is NULLL and destMax != 0
85 * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN)
86 * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
87 * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
88 * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
89 *
90 * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
91 */
wcscat_s(wchar_t * strDest,size_t destMax,const wchar_t * strSrc)92 errno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
93 {
94 if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
95 SECUREC_ERROR_INVALID_RANGE("wcscat_s");
96 return ERANGE;
97 }
98
99 if (strDest == NULL || strSrc == NULL) {
100 SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
101 if (strDest != NULL) {
102 strDest[0] = L'\0';
103 return EINVAL_AND_RESET;
104 }
105 return EINVAL;
106 }
107
108 return SecDoWcscat(strDest, destMax, strSrc);
109 }
110
111
112