Line | Count | Source (jump to first uncovered line) |
1 | | /* $OpenBSD: xmalloc.c,v 1.37 2022/03/13 23:27:54 cheloha Exp $ */ |
2 | | /* |
3 | | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
5 | | * All rights reserved |
6 | | * Versions of malloc and friends that check their results, and never return |
7 | | * failure (they call fatal if they encounter an error). |
8 | | * |
9 | | * As far as I am concerned, the code I have written for this software |
10 | | * can be used freely for any purpose. Any derived versions of this |
11 | | * software must be clearly marked as such, and if the derived work is |
12 | | * incompatible with the protocol description in the RFC file, it must be |
13 | | * called by a name other than "ssh" or "Secure Shell". |
14 | | */ |
15 | | |
16 | | #include "includes.h" |
17 | | |
18 | | #include <stdarg.h> |
19 | | #ifdef HAVE_STDINT_H |
20 | | # include <stdint.h> |
21 | | #endif |
22 | | #include <stdio.h> |
23 | | #include <stdlib.h> |
24 | | #include <string.h> |
25 | | |
26 | | #include "xmalloc.h" |
27 | | #include "log.h" |
28 | | |
29 | | #if defined(__OpenBSD__) |
30 | | char *malloc_options = "S"; |
31 | | #endif /* __OpenBSD__ */ |
32 | | |
33 | | void * |
34 | | xmalloc(size_t size) |
35 | 32.3k | { |
36 | 32.3k | void *ptr; |
37 | | |
38 | 32.3k | if (size == 0) |
39 | 0 | fatal("xmalloc: zero size"); |
40 | 32.3k | ptr = malloc(size); |
41 | 32.3k | if (ptr == NULL) |
42 | 0 | fatal("xmalloc: out of memory (allocating %zu bytes)", size); |
43 | 32.3k | return ptr; |
44 | 32.3k | } |
45 | | |
46 | | void * |
47 | | xcalloc(size_t nmemb, size_t size) |
48 | 19.0k | { |
49 | 19.0k | void *ptr; |
50 | | |
51 | 19.0k | if (size == 0 || nmemb == 0) |
52 | 0 | fatal("xcalloc: zero size"); |
53 | 19.0k | if (SIZE_MAX / nmemb < size) |
54 | 0 | fatal("xcalloc: nmemb * size > SIZE_MAX"); |
55 | 19.0k | ptr = calloc(nmemb, size); |
56 | 19.0k | if (ptr == NULL) |
57 | 0 | fatal("xcalloc: out of memory (allocating %zu bytes)", |
58 | 19.0k | size * nmemb); |
59 | 19.0k | return ptr; |
60 | 19.0k | } |
61 | | |
62 | | void * |
63 | | xreallocarray(void *ptr, size_t nmemb, size_t size) |
64 | 0 | { |
65 | 0 | void *new_ptr; |
66 | |
|
67 | 0 | new_ptr = reallocarray(ptr, nmemb, size); |
68 | 0 | if (new_ptr == NULL) |
69 | 0 | fatal("xreallocarray: out of memory (%zu elements of %zu bytes)", |
70 | 0 | nmemb, size); |
71 | 0 | return new_ptr; |
72 | 0 | } |
73 | | |
74 | | void * |
75 | | xrecallocarray(void *ptr, size_t onmemb, size_t nmemb, size_t size) |
76 | 1.46k | { |
77 | 1.46k | void *new_ptr; |
78 | | |
79 | 1.46k | new_ptr = recallocarray(ptr, onmemb, nmemb, size); |
80 | 1.46k | if (new_ptr == NULL) |
81 | 0 | fatal("xrecallocarray: out of memory (%zu elements of %zu bytes)", |
82 | 1.46k | nmemb, size); |
83 | 1.46k | return new_ptr; |
84 | 1.46k | } |
85 | | |
86 | | char * |
87 | | xstrdup(const char *str) |
88 | 32.3k | { |
89 | 32.3k | size_t len; |
90 | 32.3k | char *cp; |
91 | | |
92 | 32.3k | len = strlen(str) + 1; |
93 | 32.3k | cp = xmalloc(len); |
94 | 32.3k | return memcpy(cp, str, len); |
95 | 32.3k | } |
96 | | |
97 | | int |
98 | | xvasprintf(char **ret, const char *fmt, va_list ap) |
99 | 0 | { |
100 | 0 | int i; |
101 | |
|
102 | 0 | i = vasprintf(ret, fmt, ap); |
103 | 0 | if (i < 0 || *ret == NULL) |
104 | 0 | fatal("xvasprintf: could not allocate memory"); |
105 | 0 | return i; |
106 | 0 | } |
107 | | |
108 | | int |
109 | | xasprintf(char **ret, const char *fmt, ...) |
110 | 0 | { |
111 | 0 | va_list ap; |
112 | 0 | int i; |
113 | |
|
114 | 0 | va_start(ap, fmt); |
115 | 0 | i = xvasprintf(ret, fmt, ap); |
116 | 0 | va_end(ap); |
117 | 0 | return i; |
118 | 0 | } |