• 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 
SecDoWcsncpy(wchar_t * strDest,size_t destMax,const wchar_t * strSrc,size_t count)18 static errno_t SecDoWcsncpy(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)
19 {
20     wchar_t *tmpDest = strDest;
21     const wchar_t *tmpSrc = strSrc;
22     size_t maxSize = destMax;
23     size_t maxCount = count;
24     SECUREC_IN_REGISTER const wchar_t *overlapGuard = NULL;
25 
26     if (tmpDest < tmpSrc) {
27         overlapGuard = tmpSrc;
28         while ((*(tmpDest++) = *(tmpSrc++)) != '\0' && --maxSize > 0 && --maxCount > 0) {
29             if (tmpDest == overlapGuard) {
30                 strDest[0] = '\0';
31                 SECUREC_ERROR_BUFFER_OVERLAP("wcsncpy_s");
32                 return EOVERLAP_AND_RESET;
33             }
34         }
35     } else {
36         overlapGuard = tmpDest;
37         while ((*(tmpDest++) = *(tmpSrc++)) != '\0' && --maxSize > 0 && --maxCount > 0) {
38             if (tmpSrc == overlapGuard) {
39                 strDest[0] = '\0';
40                 SECUREC_ERROR_BUFFER_OVERLAP("wcsncpy_s");
41                 return EOVERLAP_AND_RESET;
42             }
43         }
44     }
45     if (maxCount == 0) {
46         *tmpDest = '\0';
47     }
48 
49     if (maxSize == 0) {
50         strDest[0] = '\0';
51         SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
52         return ERANGE_AND_RESET;
53     }
54     return EOK;
55 }
56 
57 /*******************************************************************************
58  * <FUNCTION DESCRIPTION>
59  *    The wcsncpy_s function copies not more than n successive wide characters
60  *     (not including the terminating null wide character)
61  *     from the array pointed to by strSrc to the array pointed to by strDest
62  *
63  * <INPUT PARAMETERS>
64  *    strDest             Destination string.
65  *    destMax             The size of the destination string, in characters.
66  *    strSrc              Source string.
67  *    count                Number of characters to be copied.
68  *
69  * <OUTPUT PARAMETERS>
70  *    strDest              is updated
71  *
72  * <RETURN VALUE>
73  *    EOK                  Success
74  *    EINVAL               strDest is  NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
75  *    EINVAL_AND_RESET     strDest != NULL and strSrc is NULL and destMax != 0
76  *                         and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
77  *    ERANGE               destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
78  *    ERANGE_AND_RESET     count > SECUREC_WCHAR_STRING_MAX_LEN or
79  *                         (destMax <= length of strSrc and destMax <= count and strDest != strSrc
80  *                          and strDest != NULL and strSrc != NULL and destMax != 0 and
81  *                          destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap)
82  *    EOVERLAP_AND_RESET     dest buffer and source buffer are overlapped and  all  parameters are valid
83  *
84  *
85  *    If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
86  *******************************************************************************
87  */
wcsncpy_s(wchar_t * strDest,size_t destMax,const wchar_t * strSrc,size_t count)88 errno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)
89 {
90     if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
91         SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
92         return ERANGE;
93     }
94 
95     if (strDest == NULL || strSrc == NULL) {
96         SECUREC_ERROR_INVALID_PARAMTER("wcsncpy_s");
97         if (strDest != NULL) {
98             strDest[0] = '\0';
99             return EINVAL_AND_RESET;
100         }
101         return EINVAL;
102     }
103 #ifdef  SECUREC_COMPATIBLE_WIN_FORMAT
104     if (count > SECUREC_WCHAR_STRING_MAX_LEN && count != (size_t)-1) {
105         strDest[0] = '\0';      /* clear dest string */
106         SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
107         return ERANGE_AND_RESET;
108     }
109 #else
110     if (count > SECUREC_WCHAR_STRING_MAX_LEN) {
111         strDest[0] = '\0';      /* clear dest string */
112         SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
113         return ERANGE_AND_RESET;
114     }
115 #endif
116     if (count == 0) {
117         strDest[0] = '\0';
118         return EOK;
119     }
120 
121     return SecDoWcsncpy(strDest, destMax, strSrc, count);
122 }
123 
124 
125