wcsncat_s.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
  3. * Licensed under Mulan PSL v2.
  4. * You can use this software according to the terms and conditions of the Mulan PSL v2.
  5. * You may obtain a copy of Mulan PSL v2 at:
  6. * http://license.coscl.org.cn/MulanPSL2
  7. * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
  8. * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
  9. * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
  10. * See the Mulan PSL v2 for more details.
  11. * Description: wcsncat_s function
  12. * Create: 2014-02-25
  13. */
  14. #include "securecutil.h"
  15. /*
  16. * Befor this function, the basic parameter checking has been done
  17. */
  18. SECUREC_INLINE errno_t SecDoCatLimitW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)
  19. {
  20. /* To calculate the length of a wide character, the parameter must be a wide character */
  21. size_t destLen;
  22. size_t srcLen;
  23. SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen);
  24. SECUREC_CALC_WSTR_LEN(strSrc, count, &srcLen);
  25. if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
  26. strDest[0] = L'\0';
  27. if (strDest + destLen <= strSrc && destLen == destMax) {
  28. SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s");
  29. return EINVAL_AND_RESET;
  30. }
  31. SECUREC_ERROR_BUFFER_OVERLAP("wcsncat_s");
  32. return EOVERLAP_AND_RESET;
  33. }
  34. if (srcLen + destLen >= destMax || strDest == strSrc) {
  35. strDest[0] = L'\0';
  36. if (destLen == destMax) {
  37. SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s");
  38. return EINVAL_AND_RESET;
  39. }
  40. SECUREC_ERROR_INVALID_RANGE("wcsncat_s");
  41. return ERANGE_AND_RESET;
  42. }
  43. SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen * sizeof(wchar_t)); /* no terminator */
  44. *(strDest + destLen + srcLen) = L'\0';
  45. return EOK;
  46. }
  47. /*
  48. * <FUNCTION DESCRIPTION>
  49. * The wcsncat_s function appends not more than n successive wide characters
  50. * (not including the terminating null wide character)
  51. * from the array pointed to by strSrc to the end of the wide string pointed to by strDest.
  52. *
  53. * The wcsncat_s function try to append the first D characters of strSrc to
  54. * the end of strDest, where D is the lesser of count and the length of strSrc.
  55. * If appending those D characters will fit within strDest (whose size is
  56. * given as destMax) and still leave room for a null terminator, then those
  57. * characters are appended, starting at the original terminating null of
  58. * strDest, and a new terminating null is appended; otherwise, strDest[0] is
  59. * set to the null character.
  60. *
  61. * <INPUT PARAMETERS>
  62. * strDest Null-terminated destination string.
  63. * destMax Size of the destination buffer.
  64. * strSrc Null-terminated source string.
  65. * count Number of character to append, or truncate.
  66. *
  67. * <OUTPUT PARAMETERS>
  68. * strDest is updated
  69. *
  70. * <RETURN VALUE>
  71. * EOK Success
  72. * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
  73. * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or
  74. * (strDest != NULL and strSrc is NULL and destMax != 0 and
  75. * destMax <= SECUREC_WCHAR_STRING_MAX_LEN)
  76. * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
  77. * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
  78. * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
  79. *
  80. * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
  81. */
  82. errno_t wcsncat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)
  83. {
  84. if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
  85. SECUREC_ERROR_INVALID_RANGE("wcsncat_s");
  86. return ERANGE;
  87. }
  88. if (strDest == NULL || strSrc == NULL) {
  89. SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s");
  90. if (strDest != NULL) {
  91. strDest[0] = L'\0';
  92. return EINVAL_AND_RESET;
  93. }
  94. return EINVAL;
  95. }
  96. if (count > SECUREC_WCHAR_STRING_MAX_LEN) {
  97. #ifdef SECUREC_COMPATIBLE_WIN_FORMAT
  98. if (count == ((size_t)(-1))) {
  99. /* Windows internal functions may pass in -1 when calling this function */
  100. return SecDoCatLimitW(strDest, destMax, strSrc, destMax);
  101. }
  102. #endif
  103. strDest[0] = L'\0';
  104. SECUREC_ERROR_INVALID_RANGE("wcsncat_s");
  105. return ERANGE_AND_RESET;
  106. }
  107. return SecDoCatLimitW(strDest, destMax, strSrc, count);
  108. }