strlcat.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*------------------------------------------------------------------
  2. *
  3. * Module: strlcat.c
  4. *
  5. * Purpose: Safe string functions to guard against buffer overflow.
  6. *
  7. * Description: The size of character strings, especially when coming from the
  8. * outside, can sometimes exceed a fixed size storage area.
  9. *
  10. * There was one case where a MIC-E format packet had an enormous
  11. * comment that exceeded an internal buffer of 256 characters,
  12. * resulting in a crash.
  13. *
  14. * We are not always meticulous about checking sizes to avoid overflow.
  15. * Use of these functions, instead of strcpy and strcat, should
  16. * help avoid issues.
  17. *
  18. * Orgin: From OpenBSD as the copyright notice indicates.
  19. * The GNU folks didn't think it was appropriate for inclusion
  20. * in glibc. https://lwn.net/Articles/507319/
  21. *
  22. * Modifications: Added extra debug output when strings are truncated.
  23. * Not sure if I will leave this in the release version
  24. * or just let it happen silently.
  25. *
  26. *---------------------------------------------------------------*/
  27. #include "direwolf.h"
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <stdio.h>
  31. //#include "textcolor.h"
  32. /* $NetBSD: strlcat.c,v 1.5 2014/10/31 18:59:32 spz Exp $ */
  33. /* from NetBSD: strlcat.c,v 1.16 2003/10/27 00:12:42 lukem Exp */
  34. /* from OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp */
  35. /*
  36. * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
  37. *
  38. * Permission to use, copy, modify, and distribute this software for any
  39. * purpose with or without fee is hereby granted, provided that the above
  40. * copyright notice and this permission notice appear in all copies.
  41. *
  42. * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
  43. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
  44. * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
  45. * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  46. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  47. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  48. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  49. */
  50. /*
  51. * Appends src to string dst of size siz (unlike strncat, siz is the
  52. * full size of dst, not space left). At most siz-1 characters
  53. * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
  54. * Returns strlen(src) + MIN(siz, strlen(initial dst)).
  55. * If retval >= siz, truncation occurred.
  56. */
  57. #if DEBUG_STRL
  58. size_t strlcat_debug(char *__restrict__ dst, const char *__restrict__ src, size_t siz, const char *file, const char *func, int line)
  59. #else
  60. size_t strlcat_debug(char *__restrict__ dst, const char *__restrict__ src, size_t siz)
  61. #endif
  62. {
  63. char *d = dst;
  64. const char *s = src;
  65. size_t n = siz;
  66. size_t dlen;
  67. size_t retval;
  68. #if DEBUG_STRL
  69. if (dst == NULL) {
  70. //text_color_set (DW_COLOR_ERROR);
  71. printf ("ERROR: strlcat dst is NULL. (%s %s %d)\n", file, func, line);
  72. return (0);
  73. }
  74. if (src == NULL) {
  75. //text_color_set (DW_COLOR_ERROR);
  76. printf ("ERROR: strlcat src is NULL. (%s %s %d)\n", file, func, line);
  77. return (0);
  78. }
  79. if (siz == 1 || siz == 4) {
  80. //text_color_set (DW_COLOR_ERROR);
  81. printf ("Suspicious strlcat siz. Is it using sizeof a pointer variable? (%s %s %d)\n", file, func, line);
  82. }
  83. #endif
  84. /* Find the end of dst and adjust bytes left but don't go past end */
  85. while (n-- != 0 && *d != '\0')
  86. d++;
  87. dlen = d - dst;
  88. n = siz - dlen;
  89. if (n == 0) {
  90. retval = dlen + strlen(s);
  91. goto the_end;
  92. }
  93. while (*s != '\0') {
  94. if (n != 1) {
  95. *d++ = *s;
  96. n--;
  97. }
  98. s++;
  99. }
  100. *d = '\0';
  101. retval = dlen + (s - src); /* count does not include NUL */
  102. the_end:
  103. #if DEBUG_STRL
  104. if (retval >= siz) {
  105. //text_color_set (DW_COLOR_ERROR);
  106. printf ("WARNING: strlcat result length %d exceeds maximum length %d. (%s %s %d)\n",
  107. (int)retval, (int)(siz-1), file, func, line);
  108. }
  109. #endif
  110. return (retval);
  111. }