Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/util/support/t_k5buf.c
34889 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* util/support/t_k5buf.c - Test the k5buf string buffer module */
3
/*
4
* Copyright 2008 Massachusetts Institute of Technology.
5
* All Rights Reserved.
6
*
7
* Export of this software from the United States of America may
8
* require a specific license from the United States Government.
9
* It is the responsibility of any person or organization contemplating
10
* export to obtain such a license before exporting.
11
*
12
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13
* distribute this software and its documentation for any purpose and
14
* without fee is hereby granted, provided that the above copyright
15
* notice appear in all copies and that both that copyright notice and
16
* this permission notice appear in supporting documentation, and that
17
* the name of M.I.T. not be used in advertising or publicity pertaining
18
* to distribution of the software without specific, written prior
19
* permission. Furthermore if you modify this software you must label
20
* your software as modified software and not distribute it in such a
21
* fashion that it might be confused with the original M.I.T. software.
22
* M.I.T. makes no representations about the suitability of
23
* this software for any purpose. It is provided "as is" without express
24
* or implied warranty.
25
*/
26
27
#include "k5-platform.h"
28
#include "k5-buf.h"
29
#include <stdio.h>
30
#include <stdlib.h>
31
32
static void
33
fail_if(int condition, const char *name)
34
{
35
if (condition) {
36
fprintf(stderr, "%s failed\n", name);
37
exit(1);
38
}
39
}
40
41
/* Test the invariants of a buffer. */
42
static void
43
check_buf(struct k5buf *buf, const char *name)
44
{
45
fail_if(buf->buftype != K5BUF_FIXED && buf->buftype != K5BUF_DYNAMIC &&
46
buf->buftype != K5BUF_ERROR, name);
47
if (buf->buftype == K5BUF_ERROR) {
48
fail_if(buf->data != NULL, name);
49
fail_if(buf->space != 0 || buf->len != 0, name);
50
} else {
51
fail_if(buf->space == 0, name);
52
fail_if(buf->len >= buf->space, name);
53
}
54
}
55
56
static void
57
test_basic(void)
58
{
59
struct k5buf buf;
60
char storage[1024];
61
62
k5_buf_init_fixed(&buf, storage, sizeof(storage));
63
k5_buf_add(&buf, "Hello ");
64
k5_buf_add_len(&buf, "world", 5);
65
check_buf(&buf, "basic fixed");
66
fail_if(buf.data == NULL || buf.len != 11, "basic fixed");
67
fail_if(memcmp(buf.data, "Hello world", 11) != 0, "basic fixed");
68
69
k5_buf_init_dynamic(&buf);
70
k5_buf_add_len(&buf, "Hello", 5);
71
k5_buf_add(&buf, " world");
72
check_buf(&buf, "basic dynamic");
73
fail_if(buf.data == NULL || buf.len != 11, "basic dynamic");
74
fail_if(memcmp(buf.data, "Hello world", 11) != 0, "basic dynamic");
75
k5_buf_free(&buf);
76
}
77
78
static void
79
test_realloc(void)
80
{
81
struct k5buf buf;
82
char data[1024];
83
size_t i;
84
85
for (i = 0; i < sizeof(data); i++)
86
data[i] = 'a';
87
88
/* Cause the buffer size to double from 128 to 256 bytes. */
89
k5_buf_init_dynamic(&buf);
90
k5_buf_add_len(&buf, data, 10);
91
k5_buf_add_len(&buf, data, 128);
92
fail_if(buf.space != 256, "realloc 1");
93
check_buf(&buf, "realloc 1");
94
fail_if(buf.data == NULL || buf.len != 138, "realloc 1");
95
fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 1");
96
97
/* Cause the same buffer to double in size to 512 bytes. */
98
k5_buf_add_len(&buf, data, 128);
99
fail_if(buf.space != 512, "realloc 2");
100
check_buf(&buf, "realloc 2");
101
fail_if(buf.data == NULL || buf.len != 266, "realloc 2");
102
fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 2");
103
k5_buf_free(&buf);
104
105
/* Cause a buffer to increase from 128 to 512 bytes directly. */
106
k5_buf_init_dynamic(&buf);
107
k5_buf_add_len(&buf, data, 10);
108
k5_buf_add_len(&buf, data, 256);
109
fail_if(buf.space != 512, "realloc 3");
110
check_buf(&buf, "realloc 3");
111
fail_if(buf.data == NULL || buf.len != 266, "realloc 3");
112
fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 3");
113
k5_buf_free(&buf);
114
115
/* Cause a buffer to increase from 128 to 1024 bytes directly. */
116
k5_buf_init_dynamic(&buf);
117
k5_buf_add_len(&buf, data, 10);
118
k5_buf_add_len(&buf, data, 512);
119
fail_if(buf.space != 1024, "realloc 4");
120
check_buf(&buf, "realloc 4");
121
fail_if(buf.data == NULL || buf.len != 522, "realloc 4");
122
fail_if(memcmp(buf.data, data, buf.len) != 0, "realloc 4");
123
k5_buf_free(&buf);
124
125
/* Cause a reallocation to fail by integer overflow. */
126
k5_buf_init_dynamic(&buf);
127
k5_buf_add_len(&buf, data, 100);
128
k5_buf_add_len(&buf, NULL, SIZE_MAX);
129
check_buf(&buf, "realloc 5");
130
fail_if(buf.buftype != K5BUF_ERROR, "realloc 5");
131
k5_buf_free(&buf);
132
}
133
134
static void
135
test_overflow(void)
136
{
137
struct k5buf buf;
138
char storage[10];
139
140
/* Cause a fixed-sized buffer overflow. */
141
k5_buf_init_fixed(&buf, storage, sizeof(storage));
142
k5_buf_add(&buf, "12345");
143
k5_buf_add(&buf, "123456");
144
check_buf(&buf, "overflow 1");
145
fail_if(buf.buftype != K5BUF_ERROR, "overflow 1");
146
147
/* Cause a fixed-sized buffer overflow with integer overflow. */
148
k5_buf_init_fixed(&buf, storage, sizeof(storage));
149
k5_buf_add(&buf, "12345");
150
k5_buf_add_len(&buf, NULL, SIZE_MAX);
151
check_buf(&buf, "overflow 2");
152
fail_if(buf.buftype != K5BUF_ERROR, "overflow 2");
153
}
154
155
static void
156
test_error(void)
157
{
158
struct k5buf buf;
159
char storage[1];
160
161
/* Cause an overflow and then perform actions afterwards. */
162
k5_buf_init_fixed(&buf, storage, sizeof(storage));
163
k5_buf_add(&buf, "12");
164
fail_if(buf.buftype != K5BUF_ERROR, "error");
165
check_buf(&buf, "error");
166
k5_buf_add(&buf, "test");
167
check_buf(&buf, "error");
168
k5_buf_add_len(&buf, "test", 4);
169
check_buf(&buf, "error");
170
k5_buf_truncate(&buf, 3);
171
check_buf(&buf, "error");
172
fail_if(buf.buftype != K5BUF_ERROR, "error");
173
}
174
175
static void
176
test_truncate(void)
177
{
178
struct k5buf buf;
179
180
k5_buf_init_dynamic(&buf);
181
k5_buf_add(&buf, "abcde");
182
k5_buf_add(&buf, "fghij");
183
k5_buf_truncate(&buf, 7);
184
check_buf(&buf, "truncate");
185
fail_if(buf.data == NULL || buf.len != 7, "truncate");
186
fail_if(memcmp(buf.data, "abcdefg", 7) != 0, "truncate");
187
k5_buf_free(&buf);
188
}
189
190
static void
191
test_binary(void)
192
{
193
struct k5buf buf;
194
char data[] = { 'a', 0, 'b' }, *s;
195
196
k5_buf_init_dynamic(&buf);
197
k5_buf_add_len(&buf, data, 3);
198
k5_buf_add_len(&buf, data, 3);
199
check_buf(&buf, "binary");
200
fail_if(buf.data == NULL || buf.len != 6, "binary");
201
s = buf.data;
202
fail_if(s[0] != 'a' || s[1] != 0 || s[2] != 'b', "binary");
203
fail_if(s[3] != 'a' || s[4] != 0 || s[5] != 'b', "binary");
204
k5_buf_free(&buf);
205
}
206
207
static void
208
test_fmt(void)
209
{
210
struct k5buf buf;
211
char storage[10], data[1024];
212
size_t i;
213
214
for (i = 0; i < sizeof(data) - 1; i++)
215
data[i] = 'a';
216
data[i] = '\0';
217
218
/* Format some text into a non-empty fixed buffer. */
219
k5_buf_init_fixed(&buf, storage, sizeof(storage));
220
k5_buf_add(&buf, "foo");
221
k5_buf_add_fmt(&buf, " %d ", 3);
222
check_buf(&buf, "fmt 1");
223
fail_if(buf.data == NULL || buf.len != 6, "fmt 1");
224
fail_if(memcmp(buf.data, "foo 3 ", 6) != 0, "fmt 1");
225
226
/* Overflow the same buffer with formatted text. */
227
k5_buf_add_fmt(&buf, "%d%d%d%d", 1, 2, 3, 4);
228
check_buf(&buf, "fmt 2");
229
fail_if(buf.buftype != K5BUF_ERROR, "fmt 2");
230
231
/* Format some text into a non-empty dynamic buffer. */
232
k5_buf_init_dynamic(&buf);
233
k5_buf_add(&buf, "foo");
234
k5_buf_add_fmt(&buf, " %d ", 3);
235
check_buf(&buf, "fmt 3");
236
fail_if(buf.data == NULL || buf.len != 6, "fmt 3");
237
fail_if(memcmp(buf.data, "foo 3 ", 6) != 0, "fmt 3");
238
239
/* Format more text into the same buffer, causing a big resize. */
240
k5_buf_add_fmt(&buf, "%s", data);
241
check_buf(&buf, "fmt 4");
242
fail_if(buf.space != 2048, "fmt 4");
243
fail_if(buf.data == NULL || buf.len != 1029, "fmt 4");
244
fail_if(memcmp((char *)buf.data + 6, data, 1023) != 0, "fmt 4");
245
k5_buf_free(&buf);
246
}
247
248
int
249
main(void)
250
{
251
test_basic();
252
test_realloc();
253
test_overflow();
254
test_error();
255
test_truncate();
256
test_binary();
257
test_fmt();
258
return 0;
259
}
260
261