]> git.proxmox.com Git - efi-boot-shim.git/blame - test-csv.c
Try again with includes
[efi-boot-shim.git] / test-csv.c
CommitLineData
031e5cce
SM
1// SPDX-License-Identifier: BSD-2-Clause-Patent
2/*
3 * test-csv.c - test our csv parser
4 */
5
6#ifndef SHIM_UNIT_TEST
7#define SHIM_UNIT_TEST
8#endif
9#include "shim.h"
10
11#include <stdio.h>
12
13struct test_entry {
14 size_t n_columns;
15 char *columns[7];
16};
17
18int
19test_parse_csv_line_size_0(void)
20{
21 char *s0 = "";
22 char *columns[] = { "a", "b", "c", "d" };
23 char *test_columns[] = { NULL, NULL, NULL, NULL };
24 size_t n_columns = 3;
25 size_t i;
26
27 test_columns[3] = columns[3];
28
29 parse_csv_line(s0, 0, &n_columns, (const char **)columns);
30
31 assert_equal_return(s0[0], '\0', -1, "got %#hhx expected %#hhx\n");
32 assert_equal_return(n_columns, 0, -1, "got %#hhx expected %#hhx\n");
33 for (i = 0; i < 4; i++) {
34 assert_equal_return(test_columns[i], columns[i], -1,
35 "expected %p got %p for column %d\n",
36 i);
37 }
38 return 0;
39}
40
41int
42test_parse_csv_line_size_1(void)
43{
44 char *s0 = "";
45 char *columns[] = { "a", "b", "c", "d" };
46 char *test_columns[] = { "", NULL, NULL, NULL };
47 size_t n_columns = 3;
48 size_t max = 1;
49 size_t i;
50
51 test_columns[3] = columns[3];
52
53 parse_csv_line(s0, max, &n_columns, (const char **)columns);
54
55 assert_equal_return(s0[0], '\0', -1, "got %#hhx expected %#hhx\n");
56 assert_equal_return(n_columns, 1, -1, "got %#hhx expected %#hhx\n");
57 for (i = 0; i < 4; i++) {
58 assert_equal_return(test_columns[i], columns[i], -1,
59 "expected %p got %p for column %d\n",
60 i);
61 }
62 return 0;
63}
64
65int
66test_parse_csv_line_comma_size_1(void)
67{
68 char *s0;
69 char *columns[] = { "a", "b", "c", "d" };
70 char *test_columns[] = { "", NULL, NULL, "d" };
71 size_t n_columns = 3;
72 size_t max = 1;
73 size_t i;
74
75 /*
76 * For reasons unknown, when I do this the normal way with:
77 * char *s0 = ",";
78 * gcc is putting it in .rodata,
79 * *** AND combining it with the "," from delims from parse_csv_line***.
80 */
81 s0 = alloca(2);
82 s0[0] = ',';
83 s0[1] = '\0';
84
85 parse_csv_line(s0, max, &n_columns, (const char **)columns);
86
87 assert_equal_return(s0[0], '\0', -1, "got %#hhx expected %#hhx\n");
88 assert_equal_return(n_columns, 1, -1, "got %#hhx expected %#hhx\n");
89// for (i = 0; i < 4; i++) {
90// printf("columns[%d]:%p:\"%s\"\n", i, columns[i], columns[i]);
91// }
92 for (i = 0; i < 1; i++) {
93 assert_equal_return(strcmp(test_columns[i], columns[i]), 0, -1,
94 "expected %d got %d for column %d\n", i);
95 }
96 for (i = 1; i < 3; i++) {
97 assert_equal_return(test_columns[i], columns[i], -1,
98 "expected %p got %p for column %d\n",
99 i);
100 }
101 for (i = 3; i < 4; i++) {
102 assert_equal_return(strcmp(test_columns[i], columns[i]), 0, -1,
103 "expected %d got %d for column %d\n", i);
104 }
105
106 return 0;
107}
108
109int
110test_parse_csv_line_comma_size_2(void)
111{
112 char *s0;
113 char *columns[] = { "a", "b", "c", "d" };
114 char *test_columns[] = { "", "", NULL, "d" };
115 size_t n_columns = 3;
116 size_t max = 2;
117 size_t i;
118
119 /*
120 * For reasons unknown, when I do this the normal way with:
121 * char *s0 = ",";
122 * gcc is putting it in .rodata,
123 * *** AND combining it with the "," from delims from parse_csv_line***.
124 */
125 s0 = alloca(2);
126 s0[0] = ',';
127 s0[1] = '\0';
128
129 parse_csv_line(s0, max, &n_columns, (const char **)columns);
130
131 assert_equal_return(s0[0], '\0', -1, "got %#hhx expected %#hhx\n");
132 assert_equal_return(n_columns, 2, -1, "got %#hhx expected %#hhx\n");
133 for (i = 0; i < 2; i++) {
134 assert_equal_return(strcmp(test_columns[i], columns[i]), 0, -1,
135 "expected %d got %d for column %d\n", i);
136 }
137 for (i = 2; i < 3; i++) {
138 assert_equal_return(test_columns[i], columns[i], -1,
139 "expected %p got %p for column %d\n",
140 i);
141 }
142 for (i = 3; i < 4; i++) {
143 assert_equal_return(strcmp(test_columns[i], columns[i]), 0, -1,
144 "expected %d got %d for column %d\n", i);
145 }
146
147 return 0;
148}
149
150int
151test_csv_0(void)
152{
153 char csv[] =
154 "\000\000\000"
155 "a,b,c,d,e,f,g,h\n"
156 "a,b,c\n"
157 "\n"
158 "\n"
159 "a,b,c,d,e,f,g,h\n"
160 "a,b,c";
161 struct test_entry test_entries[]= {
162 { 7, { "a", "b", "c", "d", "e", "f", "g" } },
163 { 3, { "a", "b", "c", NULL, NULL, NULL, NULL } },
164 { 7, { "a", "b", "c", "d", "e", "f", "g" } },
165 { 3, { "a", "b", "c", NULL, NULL, NULL, NULL } },
166 };
167 list_t entry_list;
168 size_t i;
169 char *current, *end;
170 list_t *pos = NULL;
171 EFI_STATUS efi_status;
172
173 INIT_LIST_HEAD(&entry_list);
174 assert_equal_return(list_size(&entry_list), 0, -1,
175 "got %d expected %d\n");
176
177 memcpy(csv, (char [])UTF8_BOM, UTF8_BOM_SIZE);
178
179 current = csv;
180 end = csv + sizeof(csv) - 1;
181
182 efi_status = parse_csv_data(current, end, 7, &entry_list);
183 assert_equal_return(efi_status, EFI_SUCCESS, -1, "got %x expected %x\n");
184
185 i = 0;
186 list_for_each(pos, &entry_list) {
187 struct csv_row *csv_row;
188 struct test_entry *test_entry = &test_entries[i++];
189 size_t j;
190
191 assert_goto(i > 0 && i <= 4, fail, "got %d expected 0 to 4\n", i);
192
193 csv_row = list_entry(pos, struct csv_row, list);
194
195 assert_equal_goto(csv_row->n_columns, test_entry->n_columns,
196 fail, "got %d expected %d\n");
197 for (j = 0; j < csv_row->n_columns; j++) {
198 assert_equal_goto(strcmp(csv_row->columns[j],
199 test_entry->columns[j]), 0,
200 fail, "got %d expected %d\n");
201 }
202 }
203
204 assert_equal_return(list_size(&entry_list), 4, -1,
205 "got %d expected %d\n");
206 free_csv_list(&entry_list);
207 assert_equal_return(list_size(&entry_list), 0, -1,
208 "got %d expected %d\n");
209 return 0;
210fail:
211 free_csv_list(&entry_list);
212 return -1;
213}
214
215int
216test_csv_1(void)
217{
218 char csv[] =
219 "a,b,c,d,e,f,g,h\n"
220 "a,b,c\n"
221 "\n"
222 "\n"
223 "a,b,c,d,e,f,g,h\n"
224 "a,b,c";
225 struct test_entry test_entries[]= {
226 { 7, { "a", "b", "c", "d", "e", "f", "g" } },
227 { 3, { "a", "b", "c", NULL, NULL, NULL, NULL } },
228 { 7, { "a", "b", "c", "d", "e", "f", "g" } },
229 { 3, { "a", "b", "c", NULL, NULL, NULL, NULL } },
230 };
231 list_t entry_list;
232 size_t i;
233 char *current, *end;
234 list_t *pos = NULL;
235 EFI_STATUS efi_status;
236
237 INIT_LIST_HEAD(&entry_list);
238 assert_equal_return(list_size(&entry_list), 0, -1,
239 "got %d expected %d\n");
240
241 current = csv;
242 end = csv + sizeof(csv) - 1;
243
244 efi_status = parse_csv_data(current, end, 7, &entry_list);
245 assert_equal_return(efi_status, EFI_SUCCESS, -1, "got %x expected %x\n");
246
247 i = 0;
248 list_for_each(pos, &entry_list) {
249 struct csv_row *csv_row;
250 struct test_entry *test_entry = &test_entries[i++];
251 size_t j;
252
253 assert_goto(i > 0 && i <= 4, fail, "got %d expected 0 to 4\n", i);
254
255 csv_row = list_entry(pos, struct csv_row, list);
256
257 assert_equal_goto(csv_row->n_columns, test_entry->n_columns,
258 fail, "got %d expected %d\n");
259 for (j = 0; j < csv_row->n_columns; j++) {
260 assert_equal_goto(strcmp(csv_row->columns[j],
261 test_entry->columns[j]), 0,
262 fail, "got %d expected %d\n");
263 }
264 }
265
266 assert_equal_return(list_size(&entry_list), 4, -1,
267 "got %d expected %d\n");
268 free_csv_list(&entry_list);
269 assert_equal_return(list_size(&entry_list), 0, -1,
270 "got %d expected %d\n");
271 return 0;
272fail:
273 free_csv_list(&entry_list);
274 return -1;
275}
276
277int
278test_csv_2(void)
279{
280 char csv[] =
281 "\000\000\000"
282 "a,b,c,d,e,f,g,h\n"
283 ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,c\n"
284 "\n"
285 "\n"
286 "a,b,c,d,e,f,g,h\n"
287 "a,b,c";
288 struct test_entry test_entries[]= {
289 { 7, { "a", "b", "c", "d", "e", "f", "g" } },
290 { 7, { "", "", "", "", "", "", "" } },
291 { 7, { "a", "b", "c", "d", "e", "f", "g" } },
292 { 3, { "a", "b", "c", NULL, NULL, NULL, NULL } },
293 };
294 list_t entry_list;
295 size_t i;
296 char *current, *end;
297 list_t *pos = NULL;
298 EFI_STATUS efi_status;
299
300 INIT_LIST_HEAD(&entry_list);
301 assert_equal_return(list_size(&entry_list), 0, -1,
302 "got %d expected %d\n");
303
304 memcpy(csv, (char [])UTF8_BOM, UTF8_BOM_SIZE);
305
306 current = csv;
307 end = csv + sizeof(csv) - 1;
308
309 efi_status = parse_csv_data(current, end, 7, &entry_list);
310 assert_equal_return(efi_status, EFI_SUCCESS, -1, "got %x expected %x\n");
311
312 i = 0;
313 list_for_each(pos, &entry_list) {
314 struct csv_row *csv_row;
315 struct test_entry *test_entry = &test_entries[i++];
316 size_t j;
317
318 assert_goto(i > 0 && i <= 7, fail, "got %d expected 0 to 7\n", i);
319 csv_row = list_entry(pos, struct csv_row, list);
320
321 assert_equal_goto(csv_row->n_columns, test_entry->n_columns,
322 fail, "got %d expected %d\n");
323 for (j = 0; j < csv_row->n_columns; j++) {
324 assert_equal_goto(strcmp(csv_row->columns[j],
325 test_entry->columns[j]), 0,
326 fail, "got %d expected %d\n");
327 }
328 }
329
330 free_csv_list(&entry_list);
331 assert_equal_return(list_size(&entry_list), 0, -1,
332 "got %d expected %d\n");
333
334 return 0;
335fail:
336 free_csv_list(&entry_list);
337 return -1;
338}
339
8529e0f7
SM
340int
341test_csv_3(void)
342{
343 char csv[] =
344 "a,b,c,d,e,f,g,h\n"
345 "a,b,c\n"
346 "\n"
347 "\n"
348 "a,b,c,d,e,f,g,h\n"
349 "a,b,c\0x,y\0z\0";
350 struct test_entry test_entries[]= {
351 { 7, { "a", "b", "c", "d", "e", "f", "g" } },
352 { 3, { "a", "b", "c", NULL, NULL, NULL, NULL } },
353 { 7, { "a", "b", "c", "d", "e", "f", "g" } },
354 { 3, { "a", "b", "c", NULL, NULL, NULL, NULL } },
355 };
356 list_t entry_list;
357 size_t i;
358 char *current, *end;
359 list_t *pos = NULL;
360 EFI_STATUS efi_status;
361
362 INIT_LIST_HEAD(&entry_list);
363 assert_equal_return(list_size(&entry_list), 0, -1,
364 "got %d expected %d\n");
365
366 current = csv;
367 end = csv + sizeof(csv) - 1;
368
369 efi_status = parse_csv_data(current, end, 7, &entry_list);
370 assert_equal_return(efi_status, EFI_SUCCESS, -1, "got %x expected %x\n");
371
372 i = 0;
373 list_for_each(pos, &entry_list) {
374 struct csv_row *csv_row;
375 struct test_entry *test_entry = &test_entries[i++];
376 size_t j;
377
378 assert_goto(i > 0 && i <= 4, fail, "got %d expected 0 to 4\n", i);
379
380 csv_row = list_entry(pos, struct csv_row, list);
381
382 assert_equal_goto(csv_row->n_columns, test_entry->n_columns,
383 fail, "got %d expected %d\n");
384 for (j = 0; j < csv_row->n_columns; j++) {
385 assert_equal_goto(strcmp(csv_row->columns[j],
386 test_entry->columns[j]), 0,
387 fail, "got %d expected %d\n");
388 }
389 }
390
391 assert_equal_return(list_size(&entry_list), 4, -1,
392 "got %d expected %d\n");
393 free_csv_list(&entry_list);
394 assert_equal_return(list_size(&entry_list), 0, -1,
395 "got %d expected %d\n");
396 return 0;
397fail:
398 free_csv_list(&entry_list);
399 return -1;
400}
401
031e5cce
SM
402int
403test_simple_sbat_csv(void)
404{
405 char csv[] =
406 "test1,1,SBAT test1,acme1,1,testURL1\n"
407 "test2,2,SBAT test2,acme2,2,testURL2\n";
408 struct test_entry test_entries[]= {
409 { 6, { "test1", "1", "SBAT test1", "acme1", "1", "testURL1" } },
410 { 6, { "test2", "2", "SBAT test2", "acme2", "2", "testURL2" } },
411 };
412 list_t entry_list;
413 size_t i;
414 char *current, *end;
415 list_t *pos = NULL;
416 EFI_STATUS efi_status;
417
418 INIT_LIST_HEAD(&entry_list);
419 assert_equal_return(list_size(&entry_list), 0, -1,
420 "got %d expected %d\n");
421
422 current = csv;
423 end = csv + sizeof(csv) - 1;
424
425 efi_status = parse_csv_data(current, end, 6, &entry_list);
426 assert_equal_return(efi_status, EFI_SUCCESS, -1,
427 "got %d expected %d\n");
428
429 i = 0;
430 list_for_each(pos, &entry_list) {
431 struct csv_row *csv_row;
432 struct test_entry *test_entry = &test_entries[i++];
433 size_t j;
434
435 csv_row = list_entry(pos, struct csv_row, list);
436
437 assert_equal_goto(csv_row->n_columns, test_entry->n_columns,
438 fail, "got %d expected %d");
439
440 for (j = 0; j < csv_row->n_columns; j++) {
441 assert_equal_goto(strcmp(csv_row->columns[j],
442 test_entry->columns[j]), 0,
443 fail, "got %d expected %d\n");
444 }
445 }
446
447 assert_equal_return(list_size(&entry_list), 2, -1,
448 "got %d expected %d\n");
449 free_csv_list(&entry_list);
450 assert_equal_return(list_size(&entry_list), 0, -1,
451 "got %d expected %d\n");
452
453 return 0;
454fail:
455 free_csv_list(&entry_list);
456 return -1;
457
458}
459
460int
461test_csv_simple_fuzz(char *random_bin, size_t random_bin_len,
462 bool assert_entries)
463{
464 list_t entry_list;
465 size_t i;
466 char *current, *end;
467 list_t *pos = NULL;
468 EFI_STATUS efi_status;
469
470 INIT_LIST_HEAD(&entry_list);
471 assert_equal_return(list_size(&entry_list), 0, -1,
472 "got %d expected %d\n");
473
474 current = &random_bin[0];
475 current = current + 1 - 1;
476 end = current + random_bin_len - 1;
477 *end = '\0';
478
479 efi_status = parse_csv_data(current, end, 7, &entry_list);
480 assert_equal_return(efi_status, EFI_SUCCESS, -1, "expected %#x got %#x\n");
481 printf("parsed %zd entries\n", list_size(&entry_list));
482 if (assert_entries)
483 assert_goto(list_size(&entry_list) > 0, fail,
484 "expected >0 entries\n");
485
486 i = 0;
487 list_for_each(pos, &entry_list) {
488 struct csv_row *csv_row;
489
490 csv_row = list_entry(pos, struct csv_row, list);
491 dprint("row[%zd]: %zd columns\n", i, csv_row->n_columns);
492 i++;
493 }
494
495 free_csv_list(&entry_list);
496 assert_equal_return(list_size(&entry_list), 0, -1,
497 "got %d expected %d\n");
498
499 return 0;
500fail:
501 free_csv_list(&entry_list);
502 return -1;
503}
504
505#include "test-random.h"
506
507int
508main(void)
509{
510 int status = 0;
511 size_t i, j;
512
513 setbuf(stdout, NULL);
514 test(test_parse_csv_line_size_0);
515 test(test_parse_csv_line_size_1);
516 test(test_parse_csv_line_comma_size_1);
517 test(test_parse_csv_line_comma_size_2);
518 test(test_csv_0);
519 test(test_csv_1);
520 test(test_csv_2);
8529e0f7 521 test(test_csv_3);
031e5cce
SM
522 test(test_simple_sbat_csv);
523 test(test_csv_simple_fuzz, random_bin, random_bin_len, false);
524 for (i = 0; i < random_bin_len; i++) {
525 j = i;
526 while (random_bin[i] == '\0')
527 random_bin[i] = j++;
528 }
529 test(test_csv_simple_fuzz, random_bin, random_bin_len, true);
530
531 return status;
532}
533
534// vim:fenc=utf-8:tw=75:noet