• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * nghttp2 - HTTP/2 C Library
3  *
4  * Copyright (c) 2014 Tatsuhiro Tsujikawa
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 #include "nghttp2_buf_test.h"
26 
27 #include <stdio.h>
28 
29 #include "munit.h"
30 
31 #include "nghttp2_buf.h"
32 #include "nghttp2_test_helper.h"
33 
34 static const MunitTest tests[] = {
35   munit_void_test(test_nghttp2_bufs_add),
36   munit_void_test(test_nghttp2_bufs_add_stack_buffer_overflow_bug),
37   munit_void_test(test_nghttp2_bufs_addb),
38   munit_void_test(test_nghttp2_bufs_orb),
39   munit_void_test(test_nghttp2_bufs_remove),
40   munit_void_test(test_nghttp2_bufs_reset),
41   munit_void_test(test_nghttp2_bufs_advance),
42   munit_void_test(test_nghttp2_bufs_next_present),
43   munit_void_test(test_nghttp2_bufs_realloc),
44   munit_test_end(),
45 };
46 
47 const MunitSuite buf_suite = {
48   "/buf", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
49 };
50 
test_nghttp2_bufs_add(void)51 void test_nghttp2_bufs_add(void) {
52   int rv;
53   nghttp2_bufs bufs;
54   uint8_t data[2048];
55   nghttp2_mem *mem;
56 
57   mem = nghttp2_mem_default();
58 
59   rv = nghttp2_bufs_init(&bufs, 1000, 3, mem);
60   assert_int(0, ==, rv);
61 
62   assert_ptr_equal(bufs.cur->buf.pos, bufs.cur->buf.last);
63 
64   rv = nghttp2_bufs_add(&bufs, data, 493);
65   assert_int(0, ==, rv);
66   assert_size(493, ==, nghttp2_buf_len(&bufs.cur->buf));
67   assert_size(493, ==, nghttp2_bufs_len(&bufs));
68   assert_size(507, ==, nghttp2_bufs_cur_avail(&bufs));
69 
70   rv = nghttp2_bufs_add(&bufs, data, 507);
71   assert_int(0, ==, rv);
72   assert_size(1000, ==, nghttp2_buf_len(&bufs.cur->buf));
73   assert_size(1000, ==, nghttp2_bufs_len(&bufs));
74   assert_ptr_equal(bufs.cur, bufs.head);
75 
76   rv = nghttp2_bufs_add(&bufs, data, 1);
77   assert_int(0, ==, rv);
78   assert_size(1, ==, nghttp2_buf_len(&bufs.cur->buf));
79   assert_size(1001, ==, nghttp2_bufs_len(&bufs));
80   assert_ptr_equal(bufs.cur, bufs.head->next);
81 
82   nghttp2_bufs_free(&bufs);
83 }
84 
85 /* Test for GH-232, stack-buffer-overflow */
test_nghttp2_bufs_add_stack_buffer_overflow_bug(void)86 void test_nghttp2_bufs_add_stack_buffer_overflow_bug(void) {
87   int rv;
88   nghttp2_bufs bufs;
89   uint8_t data[1024];
90   nghttp2_mem *mem;
91 
92   mem = nghttp2_mem_default();
93 
94   rv = nghttp2_bufs_init(&bufs, 100, 200, mem);
95   assert_int(0, ==, rv);
96 
97   rv = nghttp2_bufs_add(&bufs, data, sizeof(data));
98 
99   assert_int(0, ==, rv);
100   assert_size(sizeof(data), ==, nghttp2_bufs_len(&bufs));
101 
102   nghttp2_bufs_free(&bufs);
103 }
104 
test_nghttp2_bufs_addb(void)105 void test_nghttp2_bufs_addb(void) {
106   int rv;
107   nghttp2_bufs bufs;
108   size_t i;
109   nghttp2_mem *mem;
110 
111   mem = nghttp2_mem_default();
112 
113   rv = nghttp2_bufs_init(&bufs, 1000, 3, mem);
114   assert_int(0, ==, rv);
115 
116   rv = nghttp2_bufs_addb(&bufs, 14);
117   assert_int(0, ==, rv);
118   assert_size(1, ==, nghttp2_buf_len(&bufs.cur->buf));
119   assert_size(1, ==, nghttp2_bufs_len(&bufs));
120   assert_uint8(14, ==, *bufs.cur->buf.pos);
121 
122   for (i = 0; i < 999; ++i) {
123     rv = nghttp2_bufs_addb(&bufs, 254);
124 
125     assert_int(0, ==, rv);
126     assert_size(i + 2, ==, nghttp2_buf_len(&bufs.cur->buf));
127     assert_size(i + 2, ==, nghttp2_bufs_len(&bufs));
128     assert_uint8(254, ==, *(bufs.cur->buf.last - 1));
129     assert_ptr_equal(bufs.cur, bufs.head);
130   }
131 
132   rv = nghttp2_bufs_addb(&bufs, 253);
133   assert_int(0, ==, rv);
134   assert_size(1, ==, nghttp2_buf_len(&bufs.cur->buf));
135   assert_size(1001, ==, nghttp2_bufs_len(&bufs));
136   assert_uint8(253, ==, *(bufs.cur->buf.last - 1));
137   assert_ptr_equal(bufs.cur, bufs.head->next);
138 
139   rv = nghttp2_bufs_addb_hold(&bufs, 15);
140   assert_int(0, ==, rv);
141   assert_size(1, ==, nghttp2_buf_len(&bufs.cur->buf));
142   assert_size(1001, ==, nghttp2_bufs_len(&bufs));
143   assert_uint8(15, ==, *(bufs.cur->buf.last));
144 
145   /* test fast version */
146 
147   nghttp2_bufs_fast_addb(&bufs, 240);
148 
149   assert_size(2, ==, nghttp2_buf_len(&bufs.cur->buf));
150   assert_size(1002, ==, nghttp2_bufs_len(&bufs));
151   assert_uint8(240, ==, *(bufs.cur->buf.last - 1));
152 
153   nghttp2_bufs_fast_addb_hold(&bufs, 113);
154 
155   assert_size(2, ==, nghttp2_buf_len(&bufs.cur->buf));
156   assert_size(1002, ==, nghttp2_bufs_len(&bufs));
157   assert_uint8(113, ==, *(bufs.cur->buf.last));
158 
159   /* addb_hold when last == end */
160   bufs.cur->buf.last = bufs.cur->buf.end;
161 
162   rv = nghttp2_bufs_addb_hold(&bufs, 19);
163   assert_int(0, ==, rv);
164   assert_size(0, ==, nghttp2_buf_len(&bufs.cur->buf));
165   assert_size(2000, ==, nghttp2_bufs_len(&bufs));
166   assert_uint8(19, ==, *(bufs.cur->buf.last));
167 
168   nghttp2_bufs_free(&bufs);
169 }
170 
test_nghttp2_bufs_orb(void)171 void test_nghttp2_bufs_orb(void) {
172   int rv;
173   nghttp2_bufs bufs;
174   nghttp2_mem *mem;
175 
176   mem = nghttp2_mem_default();
177 
178   rv = nghttp2_bufs_init(&bufs, 1000, 3, mem);
179   assert_int(0, ==, rv);
180 
181   *(bufs.cur->buf.last) = 0;
182 
183   rv = nghttp2_bufs_orb_hold(&bufs, 15);
184   assert_int(0, ==, rv);
185   assert_size(0, ==, nghttp2_buf_len(&bufs.cur->buf));
186   assert_size(0, ==, nghttp2_bufs_len(&bufs));
187   assert_uint8(15, ==, *(bufs.cur->buf.last));
188 
189   rv = nghttp2_bufs_orb(&bufs, 240);
190   assert_int(0, ==, rv);
191   assert_size(1, ==, nghttp2_buf_len(&bufs.cur->buf));
192   assert_size(1, ==, nghttp2_bufs_len(&bufs));
193   assert_uint8(255, ==, *(bufs.cur->buf.last - 1));
194 
195   *(bufs.cur->buf.last) = 0;
196   nghttp2_bufs_fast_orb_hold(&bufs, 240);
197   assert_uint8(240, ==, *(bufs.cur->buf.last));
198 
199   nghttp2_bufs_fast_orb(&bufs, 15);
200   assert_uint8(255, ==, *(bufs.cur->buf.last - 1));
201 
202   nghttp2_bufs_free(&bufs);
203 }
204 
test_nghttp2_bufs_remove(void)205 void test_nghttp2_bufs_remove(void) {
206   int rv;
207   nghttp2_bufs bufs;
208   nghttp2_buf_chain *chain;
209   int i;
210   uint8_t *out;
211   nghttp2_ssize outlen;
212   nghttp2_mem *mem;
213 
214   mem = nghttp2_mem_default();
215 
216   rv = nghttp2_bufs_init(&bufs, 1000, 3, mem);
217   assert_int(0, ==, rv);
218 
219   nghttp2_buf_shift_right(&bufs.cur->buf, 10);
220 
221   rv = nghttp2_bufs_add(&bufs, "hello ", 6);
222   assert_int(0, ==, rv);
223 
224   for (i = 0; i < 2; ++i) {
225     chain = bufs.cur;
226 
227     rv = nghttp2_bufs_advance(&bufs);
228     assert_int(0, ==, rv);
229 
230     assert_ptr_equal(chain->next, bufs.cur);
231   }
232 
233   rv = nghttp2_bufs_add(&bufs, "world", 5);
234   assert_int(0, ==, rv);
235 
236   outlen = nghttp2_bufs_remove(&bufs, &out);
237   assert_ptrdiff(11, ==, outlen);
238 
239   assert_memory_equal((size_t)outlen, "hello world", out);
240   assert_size(11, ==, nghttp2_bufs_len(&bufs));
241 
242   mem->free(out, NULL);
243   nghttp2_bufs_free(&bufs);
244 }
245 
test_nghttp2_bufs_reset(void)246 void test_nghttp2_bufs_reset(void) {
247   int rv;
248   nghttp2_bufs bufs;
249   nghttp2_buf_chain *ci;
250   size_t offset = 9;
251   nghttp2_mem *mem;
252 
253   mem = nghttp2_mem_default();
254 
255   rv = nghttp2_bufs_init3(&bufs, 250, 3, 1, offset, mem);
256   assert_int(0, ==, rv);
257 
258   rv = nghttp2_bufs_add(&bufs, "foo", 3);
259   assert_int(0, ==, rv);
260 
261   rv = nghttp2_bufs_advance(&bufs);
262   assert_int(0, ==, rv);
263 
264   rv = nghttp2_bufs_add(&bufs, "bar", 3);
265   assert_int(0, ==, rv);
266 
267   assert_size(6, ==, nghttp2_bufs_len(&bufs));
268 
269   nghttp2_bufs_reset(&bufs);
270 
271   assert_size(0, ==, nghttp2_bufs_len(&bufs));
272   assert_ptr_equal(bufs.cur, bufs.head);
273 
274   for (ci = bufs.head; ci; ci = ci->next) {
275     assert_ptrdiff((ptrdiff_t)offset, ==, ci->buf.pos - ci->buf.begin);
276     assert_ptr_equal(ci->buf.pos, ci->buf.last);
277   }
278 
279   assert_null(bufs.head->next);
280 
281   nghttp2_bufs_free(&bufs);
282 }
283 
test_nghttp2_bufs_advance(void)284 void test_nghttp2_bufs_advance(void) {
285   int rv;
286   nghttp2_bufs bufs;
287   int i;
288   nghttp2_mem *mem;
289 
290   mem = nghttp2_mem_default();
291 
292   rv = nghttp2_bufs_init(&bufs, 250, 3, mem);
293   assert_int(0, ==, rv);
294 
295   for (i = 0; i < 2; ++i) {
296     rv = nghttp2_bufs_advance(&bufs);
297     assert_int(0, ==, rv);
298   }
299 
300   rv = nghttp2_bufs_advance(&bufs);
301   assert_int(NGHTTP2_ERR_BUFFER_ERROR, ==, rv);
302 
303   nghttp2_bufs_free(&bufs);
304 }
305 
test_nghttp2_bufs_next_present(void)306 void test_nghttp2_bufs_next_present(void) {
307   int rv;
308   nghttp2_bufs bufs;
309   nghttp2_mem *mem;
310 
311   mem = nghttp2_mem_default();
312 
313   rv = nghttp2_bufs_init(&bufs, 250, 3, mem);
314   assert_int(0, ==, rv);
315 
316   assert_false(nghttp2_bufs_next_present(&bufs));
317 
318   rv = nghttp2_bufs_advance(&bufs);
319   assert_int(0, ==, rv);
320 
321   nghttp2_bufs_rewind(&bufs);
322 
323   assert_false(nghttp2_bufs_next_present(&bufs));
324 
325   bufs.cur = bufs.head->next;
326 
327   rv = nghttp2_bufs_addb(&bufs, 1);
328   assert_int(0, ==, rv);
329 
330   nghttp2_bufs_rewind(&bufs);
331 
332   assert_true(nghttp2_bufs_next_present(&bufs));
333 
334   nghttp2_bufs_free(&bufs);
335 }
336 
test_nghttp2_bufs_realloc(void)337 void test_nghttp2_bufs_realloc(void) {
338   int rv;
339   nghttp2_bufs bufs;
340   nghttp2_mem *mem;
341 
342   mem = nghttp2_mem_default();
343 
344   rv = nghttp2_bufs_init3(&bufs, 266, 3, 1, 10, mem);
345   assert_int(0, ==, rv);
346 
347   /* Create new buffer to see that these buffers are deallocated on
348      realloc */
349   rv = nghttp2_bufs_advance(&bufs);
350   assert_int(0, ==, rv);
351 
352   rv = nghttp2_bufs_realloc(&bufs, 522);
353   assert_int(0, ==, rv);
354 
355   assert_size(512, ==, nghttp2_bufs_cur_avail(&bufs));
356 
357   rv = nghttp2_bufs_realloc(&bufs, 9);
358   assert_int(NGHTTP2_ERR_INVALID_ARGUMENT, ==, rv);
359 
360   nghttp2_bufs_free(&bufs);
361 }
362