1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright © 2020 Keith Packard
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 #define _DEFAULT_SOURCE
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <errno.h>
40 #include <string.h>
41 #include <malloc.h>
42 #include <stdlib.h>
43 #include <stdint.h>
44
45 #ifndef __clang__
46 #pragma GCC diagnostic ignored "-Walloc-size-larger-than="
47 #endif
48
49 int
main(void)50 main(void)
51 {
52 void *r;
53 int result = 0;
54 int pow;
55
56 errno = 0;
57 r = malloc(0);
58 printf("malloc(0): %p\n", r);
59 if (errno != 0) {
60 printf("malloc(0) failed: %s. got %p\n", strerror(errno), r);
61 result++;
62 }
63 free(r);
64
65 r = memalign(128, 237);
66 printf("memalign(128, 237): %p\n", r);
67 if ((uintptr_t) r & 127) {
68 printf("memalign(128, 237) unaligned (%p)\n", r);
69 result++;
70 }
71 free(r);
72
73 errno = 0;
74 r = malloc(PTRDIFF_MAX);
75 printf("malloc(PTRDIFF_MAX): %p\n", r);
76 if (r || errno != ENOMEM) {
77 printf("malloc(PTRDIFF_MAX) should have failed. got %p error %s\n", r, strerror(errno));
78 result++;
79 }
80
81 errno = 0;
82 r = malloc(SIZE_MAX);
83 printf("malloc(SIZE_MAX): %p\n", r);
84 if (r || errno != ENOMEM) {
85 printf("malloc(SIZE_MAX) should have failed. got %p error %s\n", r, strerror(errno));
86 result++;
87 }
88
89 errno = 0;
90 r = calloc(1, SIZE_MAX);
91 printf("calloc(1, SIZE_MAX): %p\n", r);
92 if (r || errno != ENOMEM) {
93 printf("calloc(1, SIZE_MAX) should have failed. got %p error %s\n", r, strerror(errno));
94 result++;
95 }
96
97 errno = 0;
98 r = reallocarray(NULL, 1, SIZE_MAX);
99 printf("reallocarray(NULL, 1, SIZE_MAX): %p\n", r);
100 if (r || errno != ENOMEM) {
101 printf("reallocarray(NULL, 1, SIZE_MAX) should have failed. got %p error %s\n", r, strerror(errno));
102 result++;
103 }
104
105 for (pow = 0; pow < 4; pow++) {
106 errno = 0;
107 r = calloc(SIZE_MAX >> pow, SIZE_MAX >> pow);
108 printf("calloc(SIZE_MAX >> %d, SIZE_MAX >> %d): %p\n", pow, pow, r);
109 if (r || errno != ENOMEM) {
110 printf("calloc(SIZE_MAX >> %d, SIZE_MAX >> %d) should have failed. got %p error %s\n", pow, pow, r, strerror(errno));
111 result++;
112 }
113 r = reallocarray(NULL, SIZE_MAX >> pow, SIZE_MAX >> pow);
114 printf("reallocarray(SIZE_MAX >> %d, SIZE_MAX >> %d): %p\n", pow, pow, r);
115 if (r || errno != ENOMEM) {
116 printf("reallocarray(NULL, SIZE_MAX >> %d, SIZE_MAX >> %d) should have failed. got %p error %s\n", pow, pow, r, strerror(errno));
117 result++;
118 }
119 }
120
121 /* make sure realloc doesn't read past the source */
122
123 void *big = malloc(1024);
124 memset(big, '1', 1024);
125 printf("big %p\n", big);
126 if (big) {
127 void *small = malloc(128);
128 memset(small, '2', 128);
129 printf("small %p\n", small);
130 if (small) {
131 (void) atoi(small);
132 free(big);
133 char *med = realloc(small, 1024);
134 if (med) {
135 printf("med %p\n", med);
136 #ifdef _NANO_MALLOC
137 int i;
138 for (i = 128; i < 1024; i++)
139 if (med[i] != 0) {
140 printf("looks like realloc read past old at %d (saw %d)\n", i, med[i]);
141 ++result;
142 }
143 #endif
144 free(med);
145 small = NULL;
146 }
147 free (small);
148 }
149 }
150
151 malloc_stats();
152
153 return result;
154 }
155