puttymem.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * PuTTY memory-handling header.
  3. */
  4. #ifndef PUTTY_PUTTYMEM_H
  5. #define PUTTY_PUTTYMEM_H
  6. #include <stddef.h> /* for size_t */
  7. #include <string.h> /* for memcpy() */
  8. #include "defs.h"
  9. #define smalloc(z) safemalloc(z,1,0)
  10. #define snmalloc safemalloc
  11. #define srealloc(y,z) saferealloc(y,z,1)
  12. #define snrealloc saferealloc
  13. #define sfree safefree
  14. void *safemalloc(size_t factor1, size_t factor2, size_t addend);
  15. void *saferealloc(void *, size_t, size_t);
  16. void safefree(void *);
  17. /*
  18. * Direct use of smalloc within the code should be avoided where
  19. * possible, in favour of these type-casting macros which ensure you
  20. * don't mistakenly allocate enough space for one sort of structure
  21. * and assign it to a different sort of pointer. sresize also uses
  22. * TYPECHECK to verify that the _input_ pointer is a pointer to the
  23. * correct type.
  24. */
  25. #define snew(type) ((type *)snmalloc(1, sizeof(type), 0))
  26. #define snewn(n, type) ((type *)snmalloc((n), sizeof(type), 0))
  27. #define sresize(ptr, n, type) TYPECHECK((type *)0 == (ptr), \
  28. ((type *)snrealloc((ptr), (n), sizeof(type))))
  29. /*
  30. * For cases where you want to allocate a struct plus a subsidiary
  31. * data buffer in one step, this macro lets you add a constant to the
  32. * amount malloced.
  33. *
  34. * Since the return value is already cast to the struct type, a
  35. * pointer to that many bytes of extra data can be conveniently
  36. * obtained by simply adding 1 to the returned pointer!
  37. * snew_plus_get_aux is a handy macro that does that and casts the
  38. * result to void *, so you can assign it straight to wherever you
  39. * wanted it.
  40. */
  41. #define snew_plus(type, extra) ((type *)snmalloc(1, sizeof(type), (extra)))
  42. #define snew_plus_get_aux(ptr) ((void *)((ptr) + 1))
  43. /*
  44. * Helper macros to deal with the common use case of growing an array.
  45. *
  46. * The common setup is that 'array' is a pointer to the first element
  47. * of a dynamic array of some type, and 'size' represents the current
  48. * allocated size of that array (in elements). Both of those macro
  49. * parameters are implicitly written back to.
  50. *
  51. * Then sgrowarray(array, size, n) means: make sure the nth element of
  52. * the array exists (i.e. the size is at least n+1). You call that
  53. * before writing to the nth element, if you're looping round
  54. * appending to the array.
  55. *
  56. * If you need to grow the array by more than one element, you can
  57. * instead call sgrowarrayn(array, size, n, m), which will ensure the
  58. * size of the array is at least n+m. (So sgrowarray is just the
  59. * special case of that in which m == 1.)
  60. *
  61. * It's common to call sgrowarrayn with one of n,m equal to the
  62. * previous logical length of the array, and the other equal to the
  63. * new number of logical entries you want to add, so that n <= size on
  64. * entry. But that's not actually a mandatory precondition: the two
  65. * length parameters are just arbitrary integers that get added
  66. * together with an initial check for overflow, and the semantics are
  67. * simply 'make sure the array is big enough to take their sum, no
  68. * matter how big it was to start with'.)
  69. *
  70. * Another occasionally useful idiom is to call sgrowarray with n ==
  71. * size, i.e. sgrowarray(array, size, size). That just means: make
  72. * array bigger by _some_ amount, I don't particularly mind how much.
  73. * You might use that style if you were repeatedly calling an API
  74. * function outside your control, which would either fill your buffer
  75. * and return success, or else return a 'too big' error without
  76. * telling you how much bigger it needed to be.
  77. *
  78. * The _nm variants of the macro set the 'private' flag in the
  79. * underlying function, which forces array resizes to be done by a
  80. * manual allocate/copy/free instead of realloc, with careful clearing
  81. * of the previous memory block before we free it. This costs
  82. * performance, but if the block contains important secrets such as
  83. * private keys or passwords, it avoids the risk that a realloc that
  84. * moves the memory block might leave a copy of the data visible in
  85. * the freed memory at the previous location.
  86. */
  87. void *safegrowarray(void *array, size_t *size, size_t eltsize,
  88. size_t oldlen, size_t extralen, bool private);
  89. /* The master macro wrapper, of which all others are special cases */
  90. #define sgrowarray_general(array, size, n, m, priv) \
  91. ((array) = safegrowarray(array, &(size), sizeof(*array), n, m, priv))
  92. /* The special-case macros that are easier to use in most situations */
  93. #define sgrowarrayn( a, s, n, m) sgrowarray_general(a, s, n, m, false)
  94. #define sgrowarray( a, s, n ) sgrowarray_general(a, s, n, 1, false)
  95. #define sgrowarrayn_nm(a, s, n, m) sgrowarray_general(a, s, n, m, true )
  96. #define sgrowarray_nm( a, s, n ) sgrowarray_general(a, s, n, 1, true )
  97. /*
  98. * This function is called by the innermost safemalloc/saferealloc
  99. * functions when allocation fails. Usually it's provided by an
  100. * implementation in utils, which ties it into an application's
  101. * existing modalfatalbox() system, but standalone test applications
  102. * can reimplement it some other way if they prefer.
  103. */
  104. NORETURN void out_of_memory(void);
  105. #ifdef MINEFIELD
  106. /*
  107. * Definitions for Minefield, PuTTY's own Windows-specific malloc
  108. * debugger in the style of Electric Fence. Implemented in
  109. * windows/utils/minefield.c, and referred to by the main malloc
  110. * wrappers in memory.c.
  111. */
  112. void *minefield_c_malloc(size_t size);
  113. void minefield_c_free(void *p);
  114. void *minefield_c_realloc(void *p, size_t size);
  115. #endif
  116. #endif