13d58139fSopenharmony_ci/* 23d58139fSopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. 33d58139fSopenharmony_ci * Licensed under Mulan PSL v2. 43d58139fSopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2. 53d58139fSopenharmony_ci * You may obtain a copy of Mulan PSL v2 at: 63d58139fSopenharmony_ci * http://license.coscl.org.cn/MulanPSL2 73d58139fSopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 83d58139fSopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 93d58139fSopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 103d58139fSopenharmony_ci * See the Mulan PSL v2 for more details. 113d58139fSopenharmony_ci * Description: strcat_s function 123d58139fSopenharmony_ci * Create: 2014-02-25 133d58139fSopenharmony_ci */ 143d58139fSopenharmony_ci 153d58139fSopenharmony_ci#include "securecutil.h" 163d58139fSopenharmony_ci 173d58139fSopenharmony_ci/* 183d58139fSopenharmony_ci * Befor this function, the basic parameter checking has been done 193d58139fSopenharmony_ci */ 203d58139fSopenharmony_ciSECUREC_INLINE errno_t SecDoCat(char *strDest, size_t destMax, const char *strSrc) 213d58139fSopenharmony_ci{ 223d58139fSopenharmony_ci size_t destLen; 233d58139fSopenharmony_ci size_t srcLen; 243d58139fSopenharmony_ci size_t maxSrcLen; 253d58139fSopenharmony_ci SECUREC_CALC_STR_LEN(strDest, destMax, &destLen); 263d58139fSopenharmony_ci /* Only optimize strSrc, do not apply this function to strDest */ 273d58139fSopenharmony_ci maxSrcLen = destMax - destLen; 283d58139fSopenharmony_ci SECUREC_CALC_STR_LEN_OPT(strSrc, maxSrcLen, &srcLen); 293d58139fSopenharmony_ci 303d58139fSopenharmony_ci if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { 313d58139fSopenharmony_ci strDest[0] = '\0'; 323d58139fSopenharmony_ci if (strDest + destLen <= strSrc && destLen == destMax) { 333d58139fSopenharmony_ci SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); 343d58139fSopenharmony_ci return EINVAL_AND_RESET; 353d58139fSopenharmony_ci } 363d58139fSopenharmony_ci SECUREC_ERROR_BUFFER_OVERLAP("strcat_s"); 373d58139fSopenharmony_ci return EOVERLAP_AND_RESET; 383d58139fSopenharmony_ci } 393d58139fSopenharmony_ci if (srcLen + destLen >= destMax || strDest == strSrc) { 403d58139fSopenharmony_ci strDest[0] = '\0'; 413d58139fSopenharmony_ci if (destLen == destMax) { 423d58139fSopenharmony_ci SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); 433d58139fSopenharmony_ci return EINVAL_AND_RESET; 443d58139fSopenharmony_ci } 453d58139fSopenharmony_ci SECUREC_ERROR_INVALID_RANGE("strcat_s"); 463d58139fSopenharmony_ci return ERANGE_AND_RESET; 473d58139fSopenharmony_ci } 483d58139fSopenharmony_ci SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen + 1); /* Single character length include \0 */ 493d58139fSopenharmony_ci return EOK; 503d58139fSopenharmony_ci} 513d58139fSopenharmony_ci 523d58139fSopenharmony_ci/* 533d58139fSopenharmony_ci * <FUNCTION DESCRIPTION> 543d58139fSopenharmony_ci * The strcat_s function appends a copy of the string pointed to by strSrc (including the terminating null character) 553d58139fSopenharmony_ci * to the end of the string pointed to by strDest. 563d58139fSopenharmony_ci * The initial character of strSrc overwrites the terminating null character of strDest. 573d58139fSopenharmony_ci * strcat_s will return EOVERLAP_AND_RESET if the source and destination strings overlap. 583d58139fSopenharmony_ci * 593d58139fSopenharmony_ci * Note that the second parameter is the total size of the buffer, not the 603d58139fSopenharmony_ci * remaining size. 613d58139fSopenharmony_ci * 623d58139fSopenharmony_ci * <INPUT PARAMETERS> 633d58139fSopenharmony_ci * strDest Null-terminated destination string buffer. 643d58139fSopenharmony_ci * destMax Size of the destination string buffer. 653d58139fSopenharmony_ci * strSrc Null-terminated source string buffer. 663d58139fSopenharmony_ci * 673d58139fSopenharmony_ci * <OUTPUT PARAMETERS> 683d58139fSopenharmony_ci * strDest is updated 693d58139fSopenharmony_ci * 703d58139fSopenharmony_ci * <RETURN VALUE> 713d58139fSopenharmony_ci * EOK Success 723d58139fSopenharmony_ci * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN 733d58139fSopenharmony_ci * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or 743d58139fSopenharmony_ci * (strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN) 753d58139fSopenharmony_ci * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN 763d58139fSopenharmony_ci * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap 773d58139fSopenharmony_ci * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid 783d58139fSopenharmony_ci * 793d58139fSopenharmony_ci * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid 803d58139fSopenharmony_ci */ 813d58139fSopenharmony_cierrno_t strcat_s(char *strDest, size_t destMax, const char *strSrc) 823d58139fSopenharmony_ci{ 833d58139fSopenharmony_ci if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { 843d58139fSopenharmony_ci SECUREC_ERROR_INVALID_RANGE("strcat_s"); 853d58139fSopenharmony_ci return ERANGE; 863d58139fSopenharmony_ci } 873d58139fSopenharmony_ci if (strDest == NULL || strSrc == NULL) { 883d58139fSopenharmony_ci SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); 893d58139fSopenharmony_ci if (strDest != NULL) { 903d58139fSopenharmony_ci strDest[0] = '\0'; 913d58139fSopenharmony_ci return EINVAL_AND_RESET; 923d58139fSopenharmony_ci } 933d58139fSopenharmony_ci return EINVAL; 943d58139fSopenharmony_ci } 953d58139fSopenharmony_ci return SecDoCat(strDest, destMax, strSrc); 963d58139fSopenharmony_ci} 973d58139fSopenharmony_ci 983d58139fSopenharmony_ci#if SECUREC_EXPORT_KERNEL_SYMBOL 993d58139fSopenharmony_ciEXPORT_SYMBOL(strcat_s); 1003d58139fSopenharmony_ci#endif 1013d58139fSopenharmony_ci 102