• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved.
3  * Licensed under Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *          http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  * Description: strncat_s  function
12  * Author: lishunda
13  * Create: 2014-02-25
14  */
15 
16 #include "securecutil.h"
17 
18 /*
19  * Befor this function, the basic parameter checking has been done
20  */
SecDoCatLimit(char * strDest,size_t destMax,const char * strSrc,size_t count)21 SECUREC_INLINE errno_t SecDoCatLimit(char *strDest, size_t destMax, const char *strSrc, size_t count)
22 {
23     size_t destLen;
24     size_t srcLen;
25     SECUREC_CALC_STR_LEN(strDest, destMax, &destLen);
26     /*
27      * The strSrc is no longer optimized. The reason is that when count is small,
28      * the efficiency of strnlen is higher than that of self realization.
29      */
30     SECUREC_CALC_STR_LEN(strSrc, count, &srcLen);
31 
32     if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
33         strDest[0] = '\0';
34         if (strDest + destLen <= strSrc && destLen == destMax) {
35             SECUREC_ERROR_INVALID_PARAMTER("strncat_s");
36             return EINVAL_AND_RESET;
37         }
38         SECUREC_ERROR_BUFFER_OVERLAP("strncat_s");
39         return EOVERLAP_AND_RESET;
40     }
41     if (srcLen + destLen >= destMax || strDest == strSrc) {
42         strDest[0] = '\0';
43         if (destLen == destMax) {
44             SECUREC_ERROR_INVALID_PARAMTER("strncat_s");
45             return EINVAL_AND_RESET;
46         }
47         SECUREC_ERROR_INVALID_RANGE("strncat_s");
48         return ERANGE_AND_RESET;
49     }
50     SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen);    /* No terminator */
51     *(strDest + destLen + srcLen) = '\0';
52     return EOK;
53 }
54 
55 /*
56  * <FUNCTION DESCRIPTION>
57  *    The strncat_s function appends not more than n successive  characters
58  *    (not including the terminating null  character)
59  *     from the array pointed to by strSrc to the end of the  string pointed to by strDest
60  *    The strncat_s function try to append the first D characters of strSrc to
61  *    the end of strDest, where D is the lesser of count and the length of strSrc.
62  *    If appending those D characters will fit within strDest (whose size is given
63  *    as destMax) and still leave room for a null terminator, then those characters
64  *    are appended, starting at the original terminating null of strDest, and a
65  *    new terminating null is appended; otherwise, strDest[0] is set to the null
66  *    character.
67  *
68  * <INPUT PARAMETERS>
69  *    strDest            Null-terminated destination string.
70  *    destMax            Size of the destination buffer.
71  *    strSrc             Null-terminated source string.
72  *    count              Number of character to append, or truncate.
73  *
74  * <OUTPUT PARAMETERS>
75  *    strDest            is updated
76  *
77  * <RETURN VALUE>
78  *    EOK                Success
79  *    EINVAL             strDest is  NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
80  *    EINVAL_AND_RESET      (strDest unterminated  and all other parameters are valid)or
81  *                        (strDest !=  NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN)
82  *    ERANGE                         destMax is 0 and destMax > SECUREC_STRING_MAX_LEN
83  *    ERANGE_AND_RESET      strDest have not enough space  and all other parameters are valid  and not overlap
84  *    EOVERLAP_AND_RESET   dest buffer and source buffer are overlapped and all  parameters are valid
85  *
86  *    If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
87  */
strncat_s(char * strDest,size_t destMax,const char * strSrc,size_t count)88 errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count)
89 {
90     if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {
91         SECUREC_ERROR_INVALID_RANGE("strncat_s");
92         return ERANGE;
93     }
94 
95     if (strDest == NULL || strSrc == NULL) {
96         SECUREC_ERROR_INVALID_PARAMTER("strncat_s");
97         if (strDest != NULL) {
98             strDest[0] = '\0';
99             return EINVAL_AND_RESET;
100         }
101         return EINVAL;
102     }
103     if (count > SECUREC_STRING_MAX_LEN) {
104 #ifdef  SECUREC_COMPATIBLE_WIN_FORMAT
105         if (count == (size_t)(-1)) {
106             /* Windows internal functions may pass in -1 when calling this function */
107             return SecDoCatLimit(strDest, destMax, strSrc, destMax);
108         }
109 #endif
110         strDest[0] = '\0';
111         SECUREC_ERROR_INVALID_RANGE("strncat_s");
112         return ERANGE_AND_RESET;
113     }
114     return SecDoCatLimit(strDest, destMax, strSrc, count);
115 }
116 
117 #if SECUREC_IN_KERNEL
118 EXPORT_SYMBOL(strncat_s);
119 #endif
120 
121