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: wcscat_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 SecDoCatW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
213d58139fSopenharmony_ci{
223d58139fSopenharmony_ci    size_t destLen;
233d58139fSopenharmony_ci    size_t srcLen;
243d58139fSopenharmony_ci    size_t maxCount; /* Store the maximum available count */
253d58139fSopenharmony_ci
263d58139fSopenharmony_ci    /* To calculate the length of a wide character, the parameter must be a wide character */
273d58139fSopenharmony_ci    SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen);
283d58139fSopenharmony_ci    maxCount = destMax - destLen;
293d58139fSopenharmony_ci    SECUREC_CALC_WSTR_LEN(strSrc, maxCount, &srcLen);
303d58139fSopenharmony_ci
313d58139fSopenharmony_ci    if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
323d58139fSopenharmony_ci        strDest[0] = L'\0';
333d58139fSopenharmony_ci        if (strDest + destLen <= strSrc && destLen == destMax) {
343d58139fSopenharmony_ci            SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
353d58139fSopenharmony_ci            return EINVAL_AND_RESET;
363d58139fSopenharmony_ci        }
373d58139fSopenharmony_ci        SECUREC_ERROR_BUFFER_OVERLAP("wcscat_s");
383d58139fSopenharmony_ci        return EOVERLAP_AND_RESET;
393d58139fSopenharmony_ci    }
403d58139fSopenharmony_ci    if (srcLen + destLen >= destMax || strDest == strSrc) {
413d58139fSopenharmony_ci        strDest[0] = L'\0';
423d58139fSopenharmony_ci        if (destLen == destMax) {
433d58139fSopenharmony_ci            SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
443d58139fSopenharmony_ci            return EINVAL_AND_RESET;
453d58139fSopenharmony_ci        }
463d58139fSopenharmony_ci        SECUREC_ERROR_INVALID_RANGE("wcscat_s");
473d58139fSopenharmony_ci        return ERANGE_AND_RESET;
483d58139fSopenharmony_ci    }
493d58139fSopenharmony_ci    /* Copy single character length  include \0 */
503d58139fSopenharmony_ci    SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, (srcLen + 1) * sizeof(wchar_t));
513d58139fSopenharmony_ci    return EOK;
523d58139fSopenharmony_ci}
533d58139fSopenharmony_ci
543d58139fSopenharmony_ci/*
553d58139fSopenharmony_ci * <FUNCTION DESCRIPTION>
563d58139fSopenharmony_ci *    The wcscat_s function appends a copy of the wide string pointed to by strSrc
573d58139fSopenharmony_ci*      (including the terminating null wide character)
583d58139fSopenharmony_ci *     to the end of the wide string pointed to by strDest.
593d58139fSopenharmony_ci *    The arguments and return value of wcscat_s are wide-character strings.
603d58139fSopenharmony_ci *
613d58139fSopenharmony_ci *    The wcscat_s function appends strSrc to strDest and terminates the resulting
623d58139fSopenharmony_ci *    string with a null character. The initial character of strSrc overwrites the
633d58139fSopenharmony_ci *    terminating null character of strDest. wcscat_s will return EOVERLAP_AND_RESET if the
643d58139fSopenharmony_ci *    source and destination strings overlap.
653d58139fSopenharmony_ci *
663d58139fSopenharmony_ci *    Note that the second parameter is the total size of the buffer, not the
673d58139fSopenharmony_ci *    remaining size.
683d58139fSopenharmony_ci *
693d58139fSopenharmony_ci * <INPUT PARAMETERS>
703d58139fSopenharmony_ci *    strDest              Null-terminated destination string buffer.
713d58139fSopenharmony_ci *    destMax              Size of the destination string buffer.
723d58139fSopenharmony_ci *    strSrc               Null-terminated source string buffer.
733d58139fSopenharmony_ci *
743d58139fSopenharmony_ci * <OUTPUT PARAMETERS>
753d58139fSopenharmony_ci *    strDest               is updated
763d58139fSopenharmony_ci *
773d58139fSopenharmony_ci * <RETURN VALUE>
783d58139fSopenharmony_ci *    EOK                   Success
793d58139fSopenharmony_ci *    EINVAL                strDest is  NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
803d58139fSopenharmony_ci *    EINVAL_AND_RESET      (strDest unterminated and all other parameters are valid) or
813d58139fSopenharmony_ci *                          (strDest != NULL and strSrc is NULL and destMax != 0
823d58139fSopenharmony_ci *                           and destMax <= SECUREC_WCHAR_STRING_MAX_LEN)
833d58139fSopenharmony_ci *    ERANGE                destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
843d58139fSopenharmony_ci *    ERANGE_AND_RESET      strDest have not enough space  and all other parameters are valid  and not overlap
853d58139fSopenharmony_ci *    EOVERLAP_AND_RESET     dest buffer and source buffer are overlapped and all  parameters are valid
863d58139fSopenharmony_ci *
873d58139fSopenharmony_ci *    If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
883d58139fSopenharmony_ci */
893d58139fSopenharmony_cierrno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
903d58139fSopenharmony_ci{
913d58139fSopenharmony_ci    if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
923d58139fSopenharmony_ci        SECUREC_ERROR_INVALID_RANGE("wcscat_s");
933d58139fSopenharmony_ci        return ERANGE;
943d58139fSopenharmony_ci    }
953d58139fSopenharmony_ci
963d58139fSopenharmony_ci    if (strDest == NULL || strSrc == NULL) {
973d58139fSopenharmony_ci        SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
983d58139fSopenharmony_ci        if (strDest != NULL) {
993d58139fSopenharmony_ci            strDest[0] = L'\0';
1003d58139fSopenharmony_ci            return EINVAL_AND_RESET;
1013d58139fSopenharmony_ci        }
1023d58139fSopenharmony_ci        return EINVAL;
1033d58139fSopenharmony_ci    }
1043d58139fSopenharmony_ci
1053d58139fSopenharmony_ci    return SecDoCatW(strDest, destMax, strSrc);
1063d58139fSopenharmony_ci}
1073d58139fSopenharmony_ci
108