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