Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : : #pragma once
3 : :
4 : : #include <inttypes.h>
5 : : #include <malloc.h>
6 : : #include <stdbool.h>
7 : : #include <string.h>
8 : : #include <sys/types.h>
9 : :
10 : : #include "macro.h"
11 : :
12 : : size_t page_size(void) _pure_;
13 : : #define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
14 : :
15 : : /* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */
16 : 182700 : static inline void memcpy_safe(void *dst, const void *src, size_t n) {
17 [ + + ]: 182700 : if (n == 0)
18 : 184 : return;
19 [ - + ]: 182516 : assert(src);
20 : 182516 : memcpy(dst, src, n);
21 : : }
22 : :
23 : : /* Normal memcmp requires s1 and s2 to be nonnull. We do nothing if n is 0. */
24 : 553 : static inline int memcmp_safe(const void *s1, const void *s2, size_t n) {
25 [ + + ]: 553 : if (n == 0)
26 : 16 : return 0;
27 [ - + ]: 537 : assert(s1);
28 [ - + ]: 537 : assert(s2);
29 : 537 : return memcmp(s1, s2, n);
30 : : }
31 : :
32 : : /* Compare s1 (length n1) with s2 (length n2) in lexicographic order. */
33 : 73 : static inline int memcmp_nn(const void *s1, size_t n1, const void *s2, size_t n2) {
34 : 73 : return memcmp_safe(s1, s2, MIN(n1, n2))
35 [ + + + + ]: 73 : ?: CMP(n1, n2);
36 : : }
37 : :
38 : : #define memzero(x,l) \
39 : : ({ \
40 : : size_t _l_ = (l); \
41 : : if (_l_ > 0) \
42 : : memset(x, 0, _l_); \
43 : : })
44 : :
45 : : #define zero(x) (memzero(&(x), sizeof(x)))
46 : :
47 : : bool memeqzero(const void *data, size_t length);
48 : :
49 : : #define eqzero(x) memeqzero(x, sizeof(x))
50 : :
51 : 269403 : static inline void *mempset(void *s, int c, size_t n) {
52 : 269403 : memset(s, c, n);
53 : 269403 : return (uint8_t*)s + n;
54 : : }
55 : :
56 : : /* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
57 : 342 : static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
58 : :
59 [ - + ]: 342 : if (needlelen <= 0)
60 : 0 : return (void*) haystack;
61 : :
62 [ + + ]: 342 : if (haystacklen < needlelen)
63 : 202 : return NULL;
64 : :
65 [ - + ]: 140 : assert(haystack);
66 [ - + ]: 140 : assert(needle);
67 : :
68 : 140 : return memmem(haystack, haystacklen, needle, needlelen);
69 : : }
70 : :
71 : : #if HAVE_EXPLICIT_BZERO
72 : 116 : static inline void* explicit_bzero_safe(void *p, size_t l) {
73 [ + - ]: 116 : if (l > 0)
74 : 116 : explicit_bzero(p, l);
75 : :
76 : 116 : return p;
77 : : }
78 : : #else
79 : : void *explicit_bzero_safe(void *p, size_t l);
80 : : #endif
81 : :
82 : 116 : static inline void erase_and_freep(void *p) {
83 : 116 : void *ptr = *(void**) p;
84 : :
85 [ + - ]: 116 : if (ptr) {
86 : 116 : size_t l = malloc_usable_size(ptr);
87 : 116 : explicit_bzero_safe(ptr, l);
88 : 116 : free(ptr);
89 : : }
90 : 116 : }
91 : :
92 : : /* Use with _cleanup_ to erase a single 'char' when leaving scope */
93 : 0 : static inline void erase_char(char *p) {
94 : 0 : explicit_bzero_safe(p, sizeof(char));
95 : 0 : }
|