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