1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/***
6*memcpy_s.c - contains memcpy_s routine
7*
8
9*
10*Purpose:
11* memcpy_s() copies a source memory buffer to a destination buffer.
12* Overlapping buffers are not treated specially, so propagation may occur.
13*
14*Revision History:
15* 10-07-03 AC Module created.
16* 03-10-04 AC Return ERANGE when buffer is too small
17* 01-14-05 AC Prefast (espx) fixes
18*
19*******************************************************************************/
20
21#include <string.h>
22#include <errno.h>
23#include <assert.h>
24#include "internal_securecrt.h"
25#include "mbusafecrt_internal.h"
26
27/***
28*memcpy_s - Copy source buffer to destination buffer
29*
30*Purpose:
31* memcpy_s() copies a source memory buffer to a destination memory buffer.
32* This routine does NOT recognize overlapping buffers, and thus can lead
33* to propagation.
34*
35* For cases where propagation must be avoided, memmove_s() must be used.
36*
37*Entry:
38* void *dst = pointer to destination buffer
39* size_t sizeInBytes = size in bytes of the destination buffer
40* const void *src = pointer to source buffer
41* size_t count = number of bytes to copy
42*
43*Exit:
44* Returns 0 if everything is ok, else return the error code.
45*
46*Exceptions:
47* Input parameters are validated. Refer to the validation section of the function.
48* On error, the error code is returned and the destination buffer is zeroed.
49*
50*******************************************************************************/
51
52errno_t __cdecl memcpy_s(
53 void * dst,
54 size_t sizeInBytes,
55 const void * src,
56 size_t count
57)
58{
59 if (count == 0)
60 {
61 /* nothing to do */
62 return 0;
63 }
64
65 /* validation section */
66 _VALIDATE_RETURN_ERRCODE(dst != NULL, EINVAL);
67 if (src == NULL || sizeInBytes < count)
68 {
69 /* zeroes the destination buffer */
70 memset(dst, 0, sizeInBytes);
71
72 _VALIDATE_RETURN_ERRCODE(src != NULL, EINVAL);
73 _VALIDATE_RETURN_ERRCODE(sizeInBytes >= count, ERANGE);
74 /* useless, but prefast is confused */
75 return EINVAL;
76 }
77
78 UINT_PTR x = (UINT_PTR)dst, y = (UINT_PTR)src;
79 assert((x + count <= y) || (y + count <= x));
80 memcpy(dst, src, count);
81 return 0;
82}
83