1 /* $OpenBSD: test_sshbuf.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */
2 /*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8 #include <sys/types.h>
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "test_helper.h"
15
16 #include "ssherr.h"
17 #define SSHBUF_INTERNAL 1 /* access internals for testing */
18 #include "sshbuf.h"
19
20 void sshbuf_tests(void);
21
22 #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
23
24 void
sshbuf_tests(void)25 sshbuf_tests(void)
26 {
27 struct sshbuf *p1;
28 const u_char *cdp;
29 u_char *dp;
30 size_t sz;
31 int r;
32
33 TEST_START("allocate sshbuf");
34 p1 = sshbuf_new();
35 ASSERT_PTR_NE(p1, NULL);
36 TEST_DONE();
37
38 TEST_START("max size on fresh buffer");
39 ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0);
40 TEST_DONE();
41
42 TEST_START("available on fresh buffer");
43 ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0);
44 TEST_DONE();
45
46 TEST_START("len = 0 on empty buffer");
47 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
48 TEST_DONE();
49
50 TEST_START("set valid max size");
51 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0);
52 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536);
53 TEST_DONE();
54
55 TEST_START("available on limited buffer");
56 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536);
57 TEST_DONE();
58
59 TEST_START("free");
60 sshbuf_free(p1);
61 TEST_DONE();
62
63 TEST_START("consume on empty buffer");
64 p1 = sshbuf_new();
65 ASSERT_PTR_NE(p1, NULL);
66 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
67 ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
68 sshbuf_free(p1);
69 TEST_DONE();
70
71 TEST_START("consume_end on empty buffer");
72 p1 = sshbuf_new();
73 ASSERT_PTR_NE(p1, NULL);
74 ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0);
75 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
76 sshbuf_free(p1);
77 TEST_DONE();
78
79 TEST_START("reserve space");
80 p1 = sshbuf_new();
81 ASSERT_PTR_NE(p1, NULL);
82 r = sshbuf_reserve(p1, 1, &dp);
83 ASSERT_INT_EQ(r, 0);
84 ASSERT_PTR_NE(dp, NULL);
85 *dp = 0x11;
86 r = sshbuf_reserve(p1, 3, &dp);
87 ASSERT_INT_EQ(r, 0);
88 ASSERT_PTR_NE(dp, NULL);
89 *dp++ = 0x22;
90 *dp++ = 0x33;
91 *dp++ = 0x44;
92 TEST_DONE();
93
94 TEST_START("sshbuf_len on filled buffer");
95 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
96 TEST_DONE();
97
98 TEST_START("sshbuf_ptr on filled buffer");
99 cdp = sshbuf_ptr(p1);
100 ASSERT_PTR_NE(cdp, NULL);
101 ASSERT_U8_EQ(cdp[0], 0x11);
102 ASSERT_U8_EQ(cdp[1], 0x22);
103 ASSERT_U8_EQ(cdp[2], 0x33);
104 ASSERT_U8_EQ(cdp[3], 0x44);
105 TEST_DONE();
106
107 TEST_START("consume on filled buffer");
108 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
109 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
110 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
111 r = sshbuf_consume(p1, 64);
112 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
113 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
114 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
115 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
116 cdp = sshbuf_ptr(p1);
117 ASSERT_PTR_NE(p1, NULL);
118 ASSERT_U8_EQ(cdp[0], 0x22);
119 ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0);
120 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
121 cdp = sshbuf_ptr(p1);
122 ASSERT_PTR_NE(p1, NULL);
123 ASSERT_U8_EQ(cdp[0], 0x44);
124 r = sshbuf_consume(p1, 2);
125 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
126 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
127 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
128 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
129 r = sshbuf_consume(p1, 1);
130 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
131 sshbuf_free(p1);
132 TEST_DONE();
133
134 TEST_START("consume_end on filled buffer");
135 p1 = sshbuf_new();
136 ASSERT_PTR_NE(p1, NULL);
137 r = sshbuf_reserve(p1, 4, &dp);
138 ASSERT_INT_EQ(r, 0);
139 ASSERT_PTR_NE(dp, NULL);
140 *dp++ = 0x11;
141 *dp++ = 0x22;
142 *dp++ = 0x33;
143 *dp++ = 0x44;
144 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
145 r = sshbuf_consume_end(p1, 5);
146 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
147 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
148 ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0);
149 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
150 cdp = sshbuf_ptr(p1);
151 ASSERT_PTR_NE(cdp, NULL);
152 ASSERT_U8_EQ(*cdp, 0x11);
153 r = sshbuf_consume_end(p1, 2);
154 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
155 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
156 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
157 sshbuf_free(p1);
158 TEST_DONE();
159
160 TEST_START("fill limited buffer");
161 p1 = sshbuf_new();
162 ASSERT_PTR_NE(p1, NULL);
163 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
164 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
165 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
166 r = sshbuf_reserve(p1, 1223, &dp);
167 ASSERT_INT_EQ(r, 0);
168 ASSERT_PTR_NE(dp, NULL);
169 memset(dp, 0xd7, 1223);
170 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
171 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
172 r = sshbuf_reserve(p1, 1, &dp);
173 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
174 ASSERT_PTR_EQ(dp, NULL);
175 TEST_DONE();
176
177 TEST_START("consume and force compaction");
178 ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0);
179 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
180 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
181 r = sshbuf_reserve(p1, 224, &dp);
182 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
183 ASSERT_PTR_EQ(dp, NULL);
184 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
185 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
186 r = sshbuf_reserve(p1, 223, &dp);
187 ASSERT_INT_EQ(r, 0);
188 ASSERT_PTR_NE(dp, NULL);
189 memset(dp, 0x7d, 223);
190 cdp = sshbuf_ptr(p1);
191 ASSERT_PTR_NE(cdp, NULL);
192 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
193 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
194 TEST_DONE();
195
196 TEST_START("resize full buffer");
197 r = sshbuf_set_max_size(p1, 1000);
198 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
199 sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC);
200 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0);
201 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
202 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223);
203 ASSERT_INT_EQ(sshbuf_len(p1), 1223);
204 TEST_DONE();
205
206 /* NB. uses sshbuf internals */
207 TEST_START("alloc chunking");
208 r = sshbuf_reserve(p1, 1, &dp);
209 ASSERT_INT_EQ(r, 0);
210 ASSERT_PTR_NE(dp, NULL);
211 *dp = 0xff;
212 cdp = sshbuf_ptr(p1);
213 ASSERT_PTR_NE(cdp, NULL);
214 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
215 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
216 ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1);
217 ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0);
218 sshbuf_free(p1);
219 TEST_DONE();
220
221 TEST_START("reset buffer");
222 p1 = sshbuf_new();
223 ASSERT_PTR_NE(p1, NULL);
224 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
225 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
226 r = sshbuf_reserve(p1, 1223, &dp);
227 ASSERT_INT_EQ(r, 0);
228 ASSERT_PTR_NE(dp, NULL);
229 memset(dp, 0xd7, 1223);
230 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
231 sshbuf_reset(p1);
232 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
233 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
234 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
235 sshbuf_free(p1);
236 TEST_DONE();
237 }
238