• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "securecutil.h"
17 
SecDoWcscat(wchar_t * strDest,size_t destMax,const wchar_t * strSrc)18 static errno_t SecDoWcscat(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
19 {
20     wchar_t *tmpDest = strDest;
21     const wchar_t *tmpSrc = strSrc;
22     size_t availableSize = destMax;
23     SECUREC_IN_REGISTER const wchar_t *overlapGuard = NULL;
24 
25     if (tmpDest < tmpSrc) {
26         overlapGuard = tmpSrc;
27         while (availableSize > 0 && *tmpDest != '\0') {
28             if (tmpDest == overlapGuard) {
29                 strDest[0] = '\0';
30                 SECUREC_ERROR_BUFFER_OVERLAP("wcscat_s");
31                 return EOVERLAP_AND_RESET;
32             }
33             /* seek to string end */
34             ++tmpDest;
35             --availableSize;
36         }
37 
38         /* strDest unterminated, return error. */
39         if (availableSize == 0) {
40             strDest[0] = '\0';
41             SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
42             return EINVAL_AND_RESET;
43         }
44 
45         /* if 2014-2018 > 0, then execute the strcat operation */
46         while ((*tmpDest++ = *tmpSrc++) != '\0' && --availableSize > 0) {
47             if (tmpDest == overlapGuard) {
48                 strDest[0] = '\0';
49                 SECUREC_ERROR_BUFFER_OVERLAP("wcscat_s");
50                 return EOVERLAP_AND_RESET;
51             }
52         }
53     } else {
54         overlapGuard = tmpDest;
55         while (availableSize > 0 && *tmpDest != '\0') {
56             /* seek to string end, and no need to check overlap */
57             ++tmpDest;
58             --availableSize;
59         }
60         /* strDest unterminated, return error. */
61         if (availableSize == 0) {
62             strDest[0] = '\0';
63             SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
64             return EINVAL_AND_RESET;
65         }
66         while ((*tmpDest++ = *tmpSrc++) != '\0' && --availableSize > 0) {
67             if (tmpSrc == overlapGuard) {
68                 strDest[0] = '\0';
69                 SECUREC_ERROR_BUFFER_OVERLAP("wcscat_s");
70                 return EOVERLAP_AND_RESET;
71             }
72         }
73     }
74 
75     /* strDest have not enough space, return error */
76     if (availableSize == 0) {
77         strDest[0] = '\0';
78         SECUREC_ERROR_INVALID_RANGE("wcscat_s");
79         return ERANGE_AND_RESET;
80     }
81     return EOK;
82 }
83 
84 /*******************************************************************************
85  * <FUNCTION DESCRIPTION>
86  *    The wcscat_s function appends a copy of the wide string pointed to by strSrc
87 *      (including the terminating null wide character)
88  *     to the end of the wide string pointed to by strDest.
89  *    The arguments and return value of wcscat_s are wide-character strings.
90  *
91  *    The wcscat_s function appends strSrc to strDest and terminates the resulting
92  *    string with a null character. The initial character of strSrc overwrites the
93  *    terminating null character of strDest. wcscat_s will return EOVERLAP_AND_RESET if the
94  *    source and destination strings overlap.
95  *
96  *    Note that the second parameter is the total size of the buffer, not the
97  *    remaining size.
98  *
99  * <INPUT PARAMETERS>
100  *    strDest              Null-terminated destination string buffer.
101  *    destMax              Size of the destination string buffer.
102  *    strSrc               Null-terminated source string buffer.
103  *
104  * <OUTPUT PARAMETERS>
105  *    strDest               is updated
106  *
107  * <RETURN VALUE>
108  *    EOK                   Success
109  *    EINVAL                strDest is  NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
110  *    EINVAL_AND_RESET      (strDest unterminated and all other parameters are valid) or
111  *                          (strDest != NULL and strSrc is NULL and destMax != 0
112  *                           and destMax <= SECUREC_WCHAR_STRING_MAX_LEN)
113  *    ERANGE                destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
114  *    ERANGE_AND_RESET      strDest have not enough space  and all other parameters are valid  and not overlap
115  *    EOVERLAP_AND_RESET     dest buffer and source buffer are overlapped and all  parameters are valid
116  *
117  *    If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
118  *******************************************************************************
119  */
wcscat_s(wchar_t * strDest,size_t destMax,const wchar_t * strSrc)120 errno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
121 {
122     if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
123         SECUREC_ERROR_INVALID_RANGE("wcscat_s");
124         return ERANGE;
125     }
126 
127     if (strDest == NULL || strSrc == NULL) {
128         SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
129         if (strDest != NULL) {
130             strDest[0] = '\0';
131             return EINVAL_AND_RESET;
132         }
133         return EINVAL;
134     }
135 
136     return SecDoWcscat(strDest, destMax, strSrc);
137 }
138 
139 
140