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: wcsncpy_s  function
123d58139fSopenharmony_ci * Create: 2014-02-25
133d58139fSopenharmony_ci */
143d58139fSopenharmony_ci
153d58139fSopenharmony_ci#include "securecutil.h"
163d58139fSopenharmony_ci
173d58139fSopenharmony_ciSECUREC_INLINE errno_t SecDoCpyLimitW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)
183d58139fSopenharmony_ci{
193d58139fSopenharmony_ci    size_t srcStrLen;
203d58139fSopenharmony_ci    if (count < destMax) {
213d58139fSopenharmony_ci        SECUREC_CALC_WSTR_LEN(strSrc, count, &srcStrLen);
223d58139fSopenharmony_ci    } else {
233d58139fSopenharmony_ci        SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen);
243d58139fSopenharmony_ci    }
253d58139fSopenharmony_ci    if (srcStrLen == destMax) {
263d58139fSopenharmony_ci        strDest[0] = L'\0';
273d58139fSopenharmony_ci        SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
283d58139fSopenharmony_ci        return ERANGE_AND_RESET;
293d58139fSopenharmony_ci    }
303d58139fSopenharmony_ci    if (strDest == strSrc) {
313d58139fSopenharmony_ci        return EOK;
323d58139fSopenharmony_ci    }
333d58139fSopenharmony_ci    if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) {
343d58139fSopenharmony_ci        /* Performance optimization srcStrLen not include '\0' */
353d58139fSopenharmony_ci        SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, srcStrLen * sizeof(wchar_t));
363d58139fSopenharmony_ci        *(strDest + srcStrLen) = L'\0';
373d58139fSopenharmony_ci        return EOK;
383d58139fSopenharmony_ci    } else {
393d58139fSopenharmony_ci        strDest[0] = L'\0';
403d58139fSopenharmony_ci        SECUREC_ERROR_BUFFER_OVERLAP("wcsncpy_s");
413d58139fSopenharmony_ci        return EOVERLAP_AND_RESET;
423d58139fSopenharmony_ci    }
433d58139fSopenharmony_ci}
443d58139fSopenharmony_ci
453d58139fSopenharmony_ci/*
463d58139fSopenharmony_ci * <FUNCTION DESCRIPTION>
473d58139fSopenharmony_ci *    The wcsncpy_s function copies not more than n successive wide characters
483d58139fSopenharmony_ci *     (not including the terminating null wide character)
493d58139fSopenharmony_ci *     from the array pointed to by strSrc to the array pointed to by strDest
503d58139fSopenharmony_ci *
513d58139fSopenharmony_ci * <INPUT PARAMETERS>
523d58139fSopenharmony_ci *    strDest             Destination string.
533d58139fSopenharmony_ci *    destMax             The size of the destination string, in characters.
543d58139fSopenharmony_ci *    strSrc              Source string.
553d58139fSopenharmony_ci *    count                Number of characters to be copied.
563d58139fSopenharmony_ci *
573d58139fSopenharmony_ci * <OUTPUT PARAMETERS>
583d58139fSopenharmony_ci *    strDest              is updated
593d58139fSopenharmony_ci *
603d58139fSopenharmony_ci * <RETURN VALUE>
613d58139fSopenharmony_ci *    EOK                  Success
623d58139fSopenharmony_ci *    EINVAL               strDest is  NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
633d58139fSopenharmony_ci *    EINVAL_AND_RESET     strDest != NULL and strSrc is NULL and destMax != 0
643d58139fSopenharmony_ci *                         and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
653d58139fSopenharmony_ci *    ERANGE               destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
663d58139fSopenharmony_ci *    ERANGE_AND_RESET     count > SECUREC_WCHAR_STRING_MAX_LEN or
673d58139fSopenharmony_ci *                         (destMax <= length of strSrc and destMax <= count and strDest != strSrc
683d58139fSopenharmony_ci *                          and strDest != NULL and strSrc != NULL and destMax != 0 and
693d58139fSopenharmony_ci *                          destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap)
703d58139fSopenharmony_ci *    EOVERLAP_AND_RESET     dest buffer and source buffer are overlapped and  all  parameters are valid
713d58139fSopenharmony_ci *
723d58139fSopenharmony_ci *
733d58139fSopenharmony_ci *    If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
743d58139fSopenharmony_ci */
753d58139fSopenharmony_cierrno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)
763d58139fSopenharmony_ci{
773d58139fSopenharmony_ci    if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
783d58139fSopenharmony_ci        SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
793d58139fSopenharmony_ci        return ERANGE;
803d58139fSopenharmony_ci    }
813d58139fSopenharmony_ci    if (strDest == NULL || strSrc == NULL) {
823d58139fSopenharmony_ci        SECUREC_ERROR_INVALID_PARAMTER("wcsncpy_s");
833d58139fSopenharmony_ci        if (strDest != NULL) {
843d58139fSopenharmony_ci            strDest[0] = L'\0';
853d58139fSopenharmony_ci            return EINVAL_AND_RESET;
863d58139fSopenharmony_ci        }
873d58139fSopenharmony_ci        return EINVAL;
883d58139fSopenharmony_ci    }
893d58139fSopenharmony_ci    if (count > SECUREC_WCHAR_STRING_MAX_LEN) {
903d58139fSopenharmony_ci#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
913d58139fSopenharmony_ci        if (count == (size_t)(-1)) {
923d58139fSopenharmony_ci            return SecDoCpyLimitW(strDest, destMax, strSrc, destMax - 1);
933d58139fSopenharmony_ci        }
943d58139fSopenharmony_ci#endif
953d58139fSopenharmony_ci        strDest[0] = L'\0';      /* Clear dest string */
963d58139fSopenharmony_ci        SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
973d58139fSopenharmony_ci        return ERANGE_AND_RESET;
983d58139fSopenharmony_ci    }
993d58139fSopenharmony_ci
1003d58139fSopenharmony_ci    if (count == 0) {
1013d58139fSopenharmony_ci        strDest[0] = L'\0';
1023d58139fSopenharmony_ci        return EOK;
1033d58139fSopenharmony_ci    }
1043d58139fSopenharmony_ci
1053d58139fSopenharmony_ci    return SecDoCpyLimitW(strDest, destMax, strSrc, count);
1063d58139fSopenharmony_ci}
1073d58139fSopenharmony_ci
108