memory.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * PuTTY's memory allocation wrappers.
  3. */
  4. #include <assert.h>
  5. #include <stdlib.h>
  6. #include <limits.h>
  7. #include "defs.h"
  8. #include "puttymem.h"
  9. #include "misc.h"
  10. void *safemalloc(size_t n, size_t size)
  11. {
  12. void *p;
  13. if (n > INT_MAX / size) {
  14. p = NULL;
  15. } else {
  16. size *= n;
  17. if (size == 0) size = 1;
  18. #ifdef MINEFIELD
  19. p = minefield_c_malloc(size);
  20. #else
  21. p = malloc(size);
  22. #endif
  23. }
  24. if (!p)
  25. out_of_memory();
  26. return p;
  27. }
  28. void *saferealloc(void *ptr, size_t n, size_t size)
  29. {
  30. void *p;
  31. if (n > INT_MAX / size) {
  32. p = NULL;
  33. } else {
  34. size *= n;
  35. if (!ptr) {
  36. #ifdef MINEFIELD
  37. p = minefield_c_malloc(size);
  38. #else
  39. p = malloc(size);
  40. #endif
  41. } else {
  42. #ifdef MINEFIELD
  43. p = minefield_c_realloc(ptr, size);
  44. #else
  45. p = realloc(ptr, size);
  46. #endif
  47. }
  48. }
  49. if (!p)
  50. out_of_memory();
  51. return p;
  52. }
  53. void safefree(void *ptr)
  54. {
  55. if (ptr) {
  56. #ifdef MINEFIELD
  57. minefield_c_free(ptr);
  58. #else
  59. free(ptr);
  60. #endif
  61. }
  62. }
  63. void *safegrowarray(void *ptr, size_t *allocated, size_t eltsize,
  64. size_t oldlen, size_t extralen, bool secret)
  65. {
  66. /* The largest value we can safely multiply by eltsize */
  67. pinitassert(eltsize > 0);
  68. size_t maxsize = (~(size_t)0) / eltsize;
  69. size_t oldsize = *allocated;
  70. /* Range-check the input values */
  71. assert(oldsize <= maxsize);
  72. assert(oldlen <= maxsize);
  73. assert(extralen <= maxsize - oldlen);
  74. /* If the size is already enough, don't bother doing anything! */
  75. if (oldsize > oldlen + extralen)
  76. return ptr;
  77. /* Find out how much we need to grow the array by. */
  78. { // WINSCP
  79. size_t increment = (oldlen + extralen) - oldsize;
  80. /* Invent a new size. We want to grow the array by at least
  81. * 'increment' elements; by at least a fixed number of bytes (to
  82. * get things started when sizes are small); and by some constant
  83. * factor of its old size (to avoid repeated calls to this
  84. * function taking quadratic time overall). */
  85. if (increment < 256 / eltsize)
  86. increment = 256 / eltsize;
  87. if (increment < oldsize / 16)
  88. increment = oldsize / 16;
  89. /* But we also can't grow beyond maxsize. */
  90. { // WINSCP
  91. size_t maxincr = maxsize - oldsize;
  92. if (increment > maxincr)
  93. increment = maxincr;
  94. { // WINSCP
  95. size_t newsize = oldsize + increment;
  96. void *toret;
  97. if (secret) {
  98. toret = safemalloc(newsize, eltsize);
  99. memcpy(toret, ptr, oldsize * eltsize);
  100. smemclr(ptr, oldsize * eltsize);
  101. sfree(ptr);
  102. } else {
  103. toret = saferealloc(ptr, newsize, eltsize);
  104. }
  105. *allocated = newsize;
  106. return toret;
  107. } // WINSCP
  108. } // WINSCP
  109. } // WINSCP
  110. }