memomve_s.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. //
  2. // Copyright (c) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
  4. //
  5. /***
  6. *memmove_s.c - contains memmove_s routine
  7. *
  8. *
  9. *Purpose:
  10. * memmove_s() copies a source memory buffer to a destination buffer.
  11. * Overlapping buffers are treated specially, to avoid propagation.
  12. *
  13. *Revision History:
  14. * 10-07-03 AC Module created.
  15. * 03-10-04 AC Return ERANGE when buffer is too small
  16. * 17-08-16 OB Add additional buffer (unix) for overlapping src / dst
  17. * Return ENOMEM when there is no memory for buffer
  18. *******************************************************************************/
  19. // use stdlib instead of PAL defined malloc to avoid forced Wint-to-pointer warning
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #ifdef _LIBSAFECRT_SGX_CONFIG
  23. #include "pal_mstypes.h"
  24. #endif
  25. #ifndef _VALIDATE_RETURN_ERRCODE
  26. #define _VALIDATE_RETURN_ERRCODE(c, e) \
  27. if (!(c)) return e
  28. #endif
  29. #ifndef ENOMEM
  30. #define ENOMEM 12
  31. #endif
  32. #ifndef EINVAL
  33. #define EINVAL 22
  34. #endif
  35. #ifndef ERANGE
  36. #define ERANGE 34
  37. #endif
  38. /*
  39. usage: see https://msdn.microsoft.com/en-us/library/8k35d1fx.aspx
  40. notes: uses extra buffer in case the src/dst overlaps (osx/bsd)
  41. dest
  42. Destination object.
  43. src
  44. Source object.
  45. count
  46. Number of bytes (memmove) to copy.
  47. */
  48. void* __cdecl memmove_xplat(
  49. void * dst,
  50. const void * src,
  51. size_t count
  52. )
  53. {
  54. #if defined(__APPLE__) || defined(__FreeBSD__)
  55. if (src <= dst && src + count > dst)
  56. {
  57. char *temp = (char*) malloc(count);
  58. _VALIDATE_RETURN_ERRCODE(temp != NULL, NULL);
  59. memcpy(temp, src, count);
  60. memcpy(dst, temp, count);
  61. free(temp);
  62. return dst;
  63. }
  64. #endif
  65. return memmove(dst, src, count);
  66. }
  67. /*
  68. usage: see https://msdn.microsoft.com/en-us/library/e2851we8.aspx
  69. dest
  70. Destination object.
  71. sizeInBytes
  72. Size of the destination buffer.
  73. src
  74. Source object.
  75. count
  76. Number of bytes (memmove_s) or characters (wmemmove_s) to copy.
  77. */
  78. int __cdecl memmove_s(
  79. void * dst,
  80. size_t sizeInBytes,
  81. const void * src,
  82. size_t count
  83. )
  84. {
  85. if (count == 0)
  86. {
  87. /* nothing to do */
  88. return 0;
  89. }
  90. /* validation section */
  91. _VALIDATE_RETURN_ERRCODE(dst != NULL, EINVAL);
  92. _VALIDATE_RETURN_ERRCODE(src != NULL, EINVAL);
  93. _VALIDATE_RETURN_ERRCODE(sizeInBytes >= count, ERANGE);
  94. void *ret_val = memmove_xplat(dst, src, count);
  95. return ret_val != NULL ? 0 : ENOMEM; // memmove_xplat returns `NULL` only if ENOMEM
  96. }