utf8: don't allow NUL in decoded strings.
[ccan] / tools / ccanlint / tests / info_compiles.c
1 #include <tools/ccanlint/ccanlint.h>
2 #include <tools/tools.h>
3 #include <ccan/tal/grab_file/grab_file.h>
4 #include <ccan/read_write_all/read_write_all.h>
5 #include <ccan/str/str.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <limits.h>
11 #include <errno.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <err.h>
15 #include <string.h>
16 #include <ctype.h>
17
18 static void check_info_compiles(struct manifest *m,
19                                 unsigned int *timeleft UNNEEDED,
20                                 struct score *score)
21 {
22         char *info_c_file, *info, *output;
23         int fd;
24
25         /* We don't really fail if we're in safe mode: our dependencies
26          * still run. */
27         if (safe_mode) {
28                 score->pass = true;
29                 score->score = 0;
30                 return;
31         }
32
33         /* Copy it to a file with proper .c suffix. */
34         info = grab_file(score, m->info_file->fullname);
35         if (!info) {
36                 score_file_error(score, m->info_file, 0,
37                                  "could not be read: %s", strerror(errno));
38                 return;
39         }
40
41         info_c_file = temp_file(info, ".c", "_info");
42         fd = open(info_c_file, O_WRONLY|O_CREAT|O_EXCL, 0600);
43         if (fd < 0 || !write_all(fd, info, tal_count(info)-1))
44                 err(1, "Copying _info file");
45
46         if (close(fd) != 0)
47                 err(1, "Closing _info file");
48
49         m->info_file->compiled[COMPILE_NORMAL] = temp_file(m, "", "info");
50         if (!compile_and_link(score, info_c_file, find_ccan_dir(m->dir), "",
51                               compiler, cflags, "",
52                               m->info_file->compiled[COMPILE_NORMAL],
53                               &output)) {
54                 score_file_error(score, m->info_file, 0,
55                                  "Errors compiling _info:\n%s", output);
56                 return;
57         }
58
59         score->pass = true;
60         score->score = 1;
61 }
62
63 struct ccanlint info_compiles = {
64         .key = "info_compiles",
65         .name = "_info compiles",
66         .check = check_info_compiles,
67         .needs = "info_exists",
68         .compulsory = true
69 };
70
71 REGISTER_TEST(info_compiles);