chiark / gitweb /
regress: Move case-*.in opening to shlib playback_prepare
[adns.git] / regress / hfuzz.c
1 /* nfuzz.c
2  * (part of complex test harness, not of the library)
3  * - routines used for fuzzing (a kind of playback)
4  *
5  *  This file is part of adns, which is
6  *    Copyright (C) 1997-2000,2003,2006,2014-2016  Ian Jackson
7  *    Copyright (C) 2014  Mark Wooding
8  *    Copyright (C) 1999-2000,2003,2006  Tony Finch
9  *    Copyright (C) 1991 Massachusetts Institute of Technology
10  *  (See the file INSTALL for full details.)
11  *  
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 3, or (at your option)
15  *  any later version.
16  *  
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *  
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software Foundation.
24  *
25  */
26 /*
27  * We read from stdin:
28  *  - command line arguments
29  *  - syscall stream
30  *  - stdin
31  */
32
33 #include <stdio.h>
34
35 #include "harness.h"
36
37 extern int Hmain(int argc, char **argv);
38
39 FILE *Hfopen(const char *path, const char *mode) {
40   /* we do not allow adns to open any files */
41   errno = EPERM;
42   return 0;
43 }
44
45 static int t_argc;
46 static char **t_argv;
47
48 static FILE *t_stdin;
49 static int t_sys_fd;
50
51 static int bail(const char *msg) {
52   fprintf(stderr,"adns fuzz client: %s\n", msg);
53   exit(-1);
54 }
55 static int baile(const char *msg) {
56   fprintf(stderr,"adns fuzz client: %s: %s\n", msg, strerror(errno));
57   exit(-1);
58 }
59
60 static void chkin(void) {
61   if (ferror(stdin)) baile("read stdin");
62   if (feof(stdin)) bail("eof on stdin");
63 }
64
65 static int getint(int max) {
66   int val;
67   char c;
68   chkin();
69   int r = scanf("%d%c", &val, &c);
70   chkin();
71   if (r != 2 || c != '\n') bail("bad input format: not integer");
72   if (val < 0 || val > max) bail("bad input format: wrong value");
73   return val;
74 }
75
76 static void getnl(void) {
77   chkin();
78   int c = getchar();
79   chkin();
80   if (c != '\n') bail("bad input format: expected newline");
81 }
82
83 int Ttestinputfd(void) {
84   return t_sys_fd;
85 }
86
87 void Texit(int rv) {
88   fprintf(stderr,"**Texit(%d)**\n",rv);
89   Tcommonshutdown();
90   exit(0);
91 }
92
93 int main(int argc, char **argv) {
94   int i, l;
95
96   if (argc!=1)
97     bail("usage: *_fuzz  (no arguments)");
98
99   t_argc = getint(50);
100   t_argv = calloc(t_argc+1, sizeof(*t_argv));
101   for (i=0; i<t_argc; i++) {
102     l = getint(1000);
103     t_argv[i] = calloc(1, l+1);
104     fread(t_argv[i], 1,l, stdin);
105     t_argv[i][l] = 0;
106     getnl();
107   }
108
109   t_stdin = tmpfile();
110   l = getint(100000);
111   while (l>0) {
112     int c = getchar();
113     if (c==EOF) break;
114     fputc(c, t_stdin);
115     l--;
116   }
117   getnl();
118   if (ferror(t_stdin) || fflush(t_stdin)) baile("write/flush t_stdin");
119   if (fseek(stdin, 0, SEEK_CUR)) baile("seek-flush stdin");
120   t_sys_fd = dup(0);  if (t_sys_fd < 0) baile("dup stdin");
121   if (dup2(fileno(t_stdin), 0)) baile("dup2 t_stdin");
122   if (fseek(stdin, 0, SEEK_SET)) baile("rewind t_stdin");
123
124   int estatus = Hmain(t_argc, t_argv);
125   Texit(estatus);
126 }
127
128 void Tmallocshutdown(void) { }
129 void *Hmalloc(size_t s) { assert(s); return malloc(s); }
130 void *Hrealloc(void *p, size_t s) { assert(s); return realloc(p,s); }
131 void Hfree(void *p) { free(p); }