You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
578 lines
21 KiB
578 lines
21 KiB
/**
|
|
* Copyright 2020 Huawei Technologies Co., Ltd
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#define SECUREC_INLINE_DO_MEMCPY 1
|
|
#include "securecutil.h"
|
|
|
|
#ifndef SECUREC_MEMCOPY_WITH_PERFORMANCE
|
|
#define SECUREC_MEMCOPY_WITH_PERFORMANCE 0
|
|
#endif
|
|
|
|
#if SECUREC_WITH_PERFORMANCE_ADDONS || SECUREC_MEMCOPY_WITH_PERFORMANCE
|
|
#ifndef SECUREC_MEMCOPY_THRESHOLD_SIZE
|
|
#define SECUREC_MEMCOPY_THRESHOLD_SIZE 64UL
|
|
#endif
|
|
/*
|
|
* Determine whether the address is 8-byte aligned, use static to increase performance
|
|
* return 0 is aligned
|
|
*/
|
|
static int SecIsAddrAligned8(const void *addr, const void *zeroAddr)
|
|
{
|
|
return (int)(((size_t)((const char*)addr - (const char*)zeroAddr)) & 7); /* use 7 to check aligned 8 */
|
|
}
|
|
|
|
#define SECUREC_SMALL_MEM_COPY do { \
|
|
if (SECUREC_ADDR_ALIGNED_8(dest) && SECUREC_ADDR_ALIGNED_8(src)) { \
|
|
/* use struct assignment */ \
|
|
switch (count) { \
|
|
case 1: \
|
|
*(SecStrBuf1 *)dest = *(const SecStrBuf1 *)src; \
|
|
break; \
|
|
case 2: \
|
|
*(SecStrBuf2 *)dest = *(const SecStrBuf2 *)src; \
|
|
break; \
|
|
case 3: \
|
|
*(SecStrBuf3 *)dest = *(const SecStrBuf3 *)src; \
|
|
break; \
|
|
case 4: \
|
|
*(SecStrBuf4 *)dest = *(const SecStrBuf4 *)src; \
|
|
break; \
|
|
case 5: \
|
|
*(SecStrBuf5 *)dest = *(const SecStrBuf5 *)src; \
|
|
break; \
|
|
case 6: \
|
|
*(SecStrBuf6 *)dest = *(const SecStrBuf6 *)src; \
|
|
break; \
|
|
case 7: \
|
|
*(SecStrBuf7 *)dest = *(const SecStrBuf7 *)src; \
|
|
break; \
|
|
case 8: \
|
|
*(SecStrBuf8 *)dest = *(const SecStrBuf8 *)src; \
|
|
break; \
|
|
case 9: \
|
|
*(SecStrBuf9 *)dest = *(const SecStrBuf9 *)src; \
|
|
break; \
|
|
case 10: \
|
|
*(SecStrBuf10 *)dest = *(const SecStrBuf10 *)src; \
|
|
break; \
|
|
case 11: \
|
|
*(SecStrBuf11 *)dest = *(const SecStrBuf11 *)src; \
|
|
break; \
|
|
case 12: \
|
|
*(SecStrBuf12 *)dest = *(const SecStrBuf12 *)src; \
|
|
break; \
|
|
case 13: \
|
|
*(SecStrBuf13 *)dest = *(const SecStrBuf13 *)src; \
|
|
break; \
|
|
case 14: \
|
|
*(SecStrBuf14 *)dest = *(const SecStrBuf14 *)src; \
|
|
break; \
|
|
case 15: \
|
|
*(SecStrBuf15 *)dest = *(const SecStrBuf15 *)src; \
|
|
break; \
|
|
case 16: \
|
|
*(SecStrBuf16 *)dest = *(const SecStrBuf16 *)src; \
|
|
break; \
|
|
case 17: \
|
|
*(SecStrBuf17 *)dest = *(const SecStrBuf17 *)src; \
|
|
break; \
|
|
case 18: \
|
|
*(SecStrBuf18 *)dest = *(const SecStrBuf18 *)src; \
|
|
break; \
|
|
case 19: \
|
|
*(SecStrBuf19 *)dest = *(const SecStrBuf19 *)src; \
|
|
break; \
|
|
case 20: \
|
|
*(SecStrBuf20 *)dest = *(const SecStrBuf20 *)src; \
|
|
break; \
|
|
case 21: \
|
|
*(SecStrBuf21 *)dest = *(const SecStrBuf21 *)src; \
|
|
break; \
|
|
case 22: \
|
|
*(SecStrBuf22 *)dest = *(const SecStrBuf22 *)src; \
|
|
break; \
|
|
case 23: \
|
|
*(SecStrBuf23 *)dest = *(const SecStrBuf23 *)src; \
|
|
break; \
|
|
case 24: \
|
|
*(SecStrBuf24 *)dest = *(const SecStrBuf24 *)src; \
|
|
break; \
|
|
case 25: \
|
|
*(SecStrBuf25 *)dest = *(const SecStrBuf25 *)src; \
|
|
break; \
|
|
case 26: \
|
|
*(SecStrBuf26 *)dest = *(const SecStrBuf26 *)src; \
|
|
break; \
|
|
case 27: \
|
|
*(SecStrBuf27 *)dest = *(const SecStrBuf27 *)src; \
|
|
break; \
|
|
case 28: \
|
|
*(SecStrBuf28 *)dest = *(const SecStrBuf28 *)src; \
|
|
break; \
|
|
case 29: \
|
|
*(SecStrBuf29 *)dest = *(const SecStrBuf29 *)src; \
|
|
break; \
|
|
case 30: \
|
|
*(SecStrBuf30 *)dest = *(const SecStrBuf30 *)src; \
|
|
break; \
|
|
case 31: \
|
|
*(SecStrBuf31 *)dest = *(const SecStrBuf31 *)src; \
|
|
break; \
|
|
case 32: \
|
|
*(SecStrBuf32 *)dest = *(const SecStrBuf32 *)src; \
|
|
break; \
|
|
case 33: \
|
|
*(SecStrBuf33 *)dest = *(const SecStrBuf33 *)src; \
|
|
break; \
|
|
case 34: \
|
|
*(SecStrBuf34 *)dest = *(const SecStrBuf34 *)src; \
|
|
break; \
|
|
case 35: \
|
|
*(SecStrBuf35 *)dest = *(const SecStrBuf35 *)src; \
|
|
break; \
|
|
case 36: \
|
|
*(SecStrBuf36 *)dest = *(const SecStrBuf36 *)src; \
|
|
break; \
|
|
case 37: \
|
|
*(SecStrBuf37 *)dest = *(const SecStrBuf37 *)src; \
|
|
break; \
|
|
case 38: \
|
|
*(SecStrBuf38 *)dest = *(const SecStrBuf38 *)src; \
|
|
break; \
|
|
case 39: \
|
|
*(SecStrBuf39 *)dest = *(const SecStrBuf39 *)src; \
|
|
break; \
|
|
case 40: \
|
|
*(SecStrBuf40 *)dest = *(const SecStrBuf40 *)src; \
|
|
break; \
|
|
case 41: \
|
|
*(SecStrBuf41 *)dest = *(const SecStrBuf41 *)src; \
|
|
break; \
|
|
case 42: \
|
|
*(SecStrBuf42 *)dest = *(const SecStrBuf42 *)src; \
|
|
break; \
|
|
case 43: \
|
|
*(SecStrBuf43 *)dest = *(const SecStrBuf43 *)src; \
|
|
break; \
|
|
case 44: \
|
|
*(SecStrBuf44 *)dest = *(const SecStrBuf44 *)src; \
|
|
break; \
|
|
case 45: \
|
|
*(SecStrBuf45 *)dest = *(const SecStrBuf45 *)src; \
|
|
break; \
|
|
case 46: \
|
|
*(SecStrBuf46 *)dest = *(const SecStrBuf46 *)src; \
|
|
break; \
|
|
case 47: \
|
|
*(SecStrBuf47 *)dest = *(const SecStrBuf47 *)src; \
|
|
break; \
|
|
case 48: \
|
|
*(SecStrBuf48 *)dest = *(const SecStrBuf48 *)src; \
|
|
break; \
|
|
case 49: \
|
|
*(SecStrBuf49 *)dest = *(const SecStrBuf49 *)src; \
|
|
break; \
|
|
case 50: \
|
|
*(SecStrBuf50 *)dest = *(const SecStrBuf50 *)src; \
|
|
break; \
|
|
case 51: \
|
|
*(SecStrBuf51 *)dest = *(const SecStrBuf51 *)src; \
|
|
break; \
|
|
case 52: \
|
|
*(SecStrBuf52 *)dest = *(const SecStrBuf52 *)src; \
|
|
break; \
|
|
case 53: \
|
|
*(SecStrBuf53 *)dest = *(const SecStrBuf53 *)src; \
|
|
break; \
|
|
case 54: \
|
|
*(SecStrBuf54 *)dest = *(const SecStrBuf54 *)src; \
|
|
break; \
|
|
case 55: \
|
|
*(SecStrBuf55 *)dest = *(const SecStrBuf55 *)src; \
|
|
break; \
|
|
case 56: \
|
|
*(SecStrBuf56 *)dest = *(const SecStrBuf56 *)src; \
|
|
break; \
|
|
case 57: \
|
|
*(SecStrBuf57 *)dest = *(const SecStrBuf57 *)src; \
|
|
break; \
|
|
case 58: \
|
|
*(SecStrBuf58 *)dest = *(const SecStrBuf58 *)src; \
|
|
break; \
|
|
case 59: \
|
|
*(SecStrBuf59 *)dest = *(const SecStrBuf59 *)src; \
|
|
break; \
|
|
case 60: \
|
|
*(SecStrBuf60 *)dest = *(const SecStrBuf60 *)src; \
|
|
break; \
|
|
case 61: \
|
|
*(SecStrBuf61 *)dest = *(const SecStrBuf61 *)src; \
|
|
break; \
|
|
case 62: \
|
|
*(SecStrBuf62 *)dest = *(const SecStrBuf62 *)src; \
|
|
break; \
|
|
case 63: \
|
|
*(SecStrBuf63 *)dest = *(const SecStrBuf63 *)src; \
|
|
break; \
|
|
case 64: \
|
|
*(SecStrBuf64 *)dest = *(const SecStrBuf64 *)src; \
|
|
break; \
|
|
default: \
|
|
break; \
|
|
} /* END switch */ \
|
|
} else { \
|
|
char *tmpDest = (char *)dest; \
|
|
const char *tmpSrc = (const char *)src; \
|
|
switch (count) { \
|
|
case 64: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 63: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 62: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 61: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 60: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 59: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 58: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 57: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 56: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 55: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 54: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 53: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 52: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 51: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 50: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 49: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 48: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 47: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 46: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 45: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 44: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 43: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 42: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 41: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 40: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 39: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 38: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 37: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 36: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 35: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 34: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 33: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 32: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 31: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 30: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 29: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 28: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 27: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 26: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 25: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 24: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 23: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 22: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 21: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 20: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 19: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 18: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 17: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 16: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 15: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 14: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 13: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 12: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 11: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 10: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 9: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 8: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 7: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 6: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 5: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 4: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 3: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 2: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
case 1: \
|
|
*(tmpDest++) = *(tmpSrc++); \
|
|
/* fall-through */ /* FALLTHRU */ \
|
|
default: \
|
|
break; \
|
|
} \
|
|
} \
|
|
} SECUREC_WHILE_ZERO
|
|
#endif
|
|
|
|
/*
|
|
* Handling errors
|
|
*/
|
|
static errno_t SecMemcpyError(void *dest, size_t destMax, const void *src, size_t count)
|
|
{
|
|
if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
|
|
SECUREC_ERROR_INVALID_RANGE("memcpy_s");
|
|
return ERANGE;
|
|
}
|
|
if (dest == NULL || src == NULL) {
|
|
SECUREC_ERROR_INVALID_PARAMTER("memcpy_s");
|
|
if (dest != NULL) {
|
|
(void)memset(dest, 0, destMax);
|
|
return EINVAL_AND_RESET;
|
|
}
|
|
return EINVAL;
|
|
}
|
|
if (count > destMax) {
|
|
(void)memset(dest, 0, destMax);
|
|
SECUREC_ERROR_INVALID_RANGE("memcpy_s");
|
|
return ERANGE_AND_RESET;
|
|
}
|
|
if (dest == src) {
|
|
return EOK;
|
|
}
|
|
if ((dest > src && dest < (const void *)((const unsigned char *)src + count)) || \
|
|
(src > dest && src < (void *)((unsigned char *)dest + count))) {
|
|
(void)memset(dest, 0, destMax);
|
|
SECUREC_ERROR_BUFFER_OVERLAP("memcpy_s");
|
|
return EOVERLAP_AND_RESET;
|
|
}
|
|
/* count == 0 also return EOK */
|
|
return EOK;
|
|
}
|
|
|
|
#if SECUREC_WITH_PERFORMANCE_ADDONS || SECUREC_MEMCOPY_WITH_PERFORMANCE
|
|
/*
|
|
* Performance optimization
|
|
*/
|
|
static void SecDoMemcpyOpt(void *dest, const void *src, size_t count)
|
|
{
|
|
if (count > SECUREC_MEMCOPY_THRESHOLD_SIZE) {
|
|
SecDoMemcpy(dest, src, count);
|
|
} else {
|
|
SECUREC_SMALL_MEM_COPY;
|
|
}
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
|
|
/* fread API in windows will call memcpy_s and pass 0xffffffff to destMax.
|
|
* To avoid the failure of fread, we don't check desMax limit.
|
|
*/
|
|
#define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \
|
|
(dest) != NULL && (src) != NULL && \
|
|
(count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count))))
|
|
#else
|
|
#define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \
|
|
(dest) != NULL && (src) != NULL && \
|
|
(destMax) <= SECUREC_MEM_MAX_LEN && \
|
|
(count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count))))
|
|
#endif
|
|
|
|
/*
|
|
* <FUNCTION DESCRIPTION>
|
|
* The memcpy_s function copies n characters from the object pointed to by src into the object pointed to by dest
|
|
*
|
|
* <INPUT PARAMETERS>
|
|
* dest Destination buffer.
|
|
* destMax Size of the destination buffer.
|
|
* src Buffer to copy from.
|
|
* count Number of characters to copy
|
|
*
|
|
* <OUTPUT PARAMETERS>
|
|
* dest buffer is updated.
|
|
*
|
|
* <RETURN VALUE>
|
|
* EOK Success
|
|
* EINVAL dest is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
|
|
* EINVAL_AND_RESET dest != NULL and src is NULLL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
|
|
* ERANGE destMax > SECUREC_MEM_MAX_LEN or destMax is 0
|
|
* ERANGE_AND_RESET count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
|
|
* and dest != NULL and src != NULL
|
|
* EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and
|
|
* count <= destMax destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL
|
|
* and src != NULL and dest != src
|
|
*
|
|
* if an error occured, dest will be filled with 0.
|
|
* If the source and destination overlap, the behavior of memcpy_s is undefined.
|
|
* Use memmove_s to handle overlapping regions.
|
|
*/
|
|
errno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count)
|
|
{
|
|
if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) {
|
|
#if SECUREC_MEMCOPY_WITH_PERFORMANCE
|
|
SecDoMemcpyOpt(dest, src, count);
|
|
#else
|
|
SecDoMemcpy(dest, src, count);
|
|
#endif
|
|
return EOK;
|
|
}
|
|
/* meet some runtime violation, return error code */
|
|
return SecMemcpyError(dest, destMax, src, count);
|
|
}
|
|
|
|
#if SECUREC_IN_KERNEL
|
|
EXPORT_SYMBOL(memcpy_s);
|
|
#endif
|
|
|
|
#if SECUREC_WITH_PERFORMANCE_ADDONS
|
|
/*
|
|
* Performance optimization
|
|
*/
|
|
errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src, size_t count)
|
|
{
|
|
if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) {
|
|
SecDoMemcpyOpt(dest, src, count);
|
|
return EOK;
|
|
}
|
|
/* meet some runtime violation, return error code */
|
|
return SecMemcpyError(dest, destMax, src, count);
|
|
}
|
|
|
|
/* trim judgement on "destMax <= SECUREC_MEM_MAX_LEN" */
|
|
errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count)
|
|
{
|
|
if (SECUREC_LIKELY(count <= destMax && dest != NULL && src != NULL && \
|
|
count > 0 && \
|
|
((dest > src && (const void *)((const unsigned char *)src + count) <= dest) || \
|
|
(src > dest && (void *)((unsigned char *)dest + count) <= src)))) {
|
|
SecDoMemcpyOpt(dest, src, count);
|
|
return EOK;
|
|
}
|
|
/* meet some runtime violation, return error code */
|
|
return SecMemcpyError(dest, destMax, src, count);
|
|
}
|
|
#endif
|
|
|