Coverage Report

Created: 2019-06-19 13:33

/src/systemd/src/basic/alloc-util.c
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: LGPL-2.1+ */
2
3
#include <malloc.h>
4
#include <stdint.h>
5
#include <string.h>
6
7
#include "alloc-util.h"
8
#include "macro.h"
9
#include "memory-util.h"
10
11
130k
void* memdup(const void *p, size_t l) {
12
130k
        void *ret;
13
130k
14
130k
        assert(l == 0 || p);
15
130k
16
130k
        ret = malloc(l ?: 1);
17
130k
        if (!ret)
18
0
                return NULL;
19
130k
20
130k
        memcpy(ret, p, l);
21
130k
        return ret;
22
130k
}
23
24
441k
void* memdup_suffix0(const void *p, size_t l) {
25
441k
        void *ret;
26
441k
27
441k
        assert(l == 0 || p);
28
441k
29
441k
        /* The same as memdup() but place a safety NUL byte after the allocated memory */
30
441k
31
441k
        if (_unlikely_(l == SIZE_MAX)) /* prevent overflow */
32
441k
                return NULL;
33
441k
34
441k
        ret = malloc(l + 1);
35
441k
        if (!ret)
36
0
                return NULL;
37
441k
38
441k
        *((uint8_t*) mempcpy(ret, p, l)) = 0;
39
441k
        return ret;
40
441k
}
41
42
562M
void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
43
562M
        size_t a, newalloc;
44
562M
        void *q;
45
562M
46
562M
        assert(p);
47
562M
        assert(allocated);
48
562M
49
562M
        if (*allocated >= need)
50
528M
                return *p;
51
34.0M
52
34.0M
        if (_unlikely_(need > SIZE_MAX/2)) /* Overflow check */
53
34.0M
                return NULL;
54
34.0M
55
34.0M
        newalloc = need * 2;
56
34.0M
        if (size_multiply_overflow(newalloc, size))
57
0
                return NULL;
58
34.0M
59
34.0M
        a = newalloc * size;
60
34.0M
        if (a < 64) /* Allocate at least 64 bytes */
61
31.8M
                a = 64;
62
34.0M
63
34.0M
        q = realloc(*p, a);
64
34.0M
        if (!q)
65
0
                return NULL;
66
34.0M
67
34.0M
        if (size > 0) {
68
34.0M
                size_t bn;
69
34.0M
70
34.0M
                /* Adjust for the 64 byte minimum */
71
34.0M
                newalloc = a / size;
72
34.0M
73
34.0M
                bn = malloc_usable_size(q) / size;
74
34.0M
                if (bn > newalloc) {
75
31.8M
                        void *qq;
76
31.8M
77
31.8M
                        /* The actual size allocated is larger than what we asked for. Let's call realloc() again to
78
31.8M
                         * take possession of the extra space. This should be cheap, since libc doesn't have to move
79
31.8M
                         * the memory for this. */
80
31.8M
81
31.8M
                        qq = realloc(q, bn * size);
82
31.8M
                        if (_likely_(qq)) {
83
31.8M
                                *p = qq;
84
31.8M
                                *allocated = bn;
85
31.8M
                                return qq;
86
31.8M
                        }
87
2.10M
                }
88
34.0M
        }
89
2.10M
90
2.10M
        *p = q;
91
2.10M
        *allocated = newalloc;
92
2.10M
        return q;
93
2.10M
}
94
95
9.62k
void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
96
9.62k
        size_t prev;
97
9.62k
        uint8_t *q;
98
9.62k
99
9.62k
        assert(p);
100
9.62k
        assert(allocated);
101
9.62k
102
9.62k
        prev = *allocated;
103
9.62k
104
9.62k
        q = greedy_realloc(p, allocated, need, size);
105
9.62k
        if (!q)
106
0
                return NULL;
107
9.62k
108
9.62k
        if (*allocated > prev)
109
9.62k
                memzero(q + prev * size, (*allocated - prev) * size);
110
9.62k
111
9.62k
        return q;
112
9.62k
}