1 /* Test of message digests.
2 Copyright (C) 2018-2021 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
17 static void
test_digest_on_files(int (* streamfunc)(FILE *,void *),const char * streamfunc_name,size_t digest_size,const void * expected_for_empty_file,const void * expected_for_small_file,const void * expected_for_large_file)18 test_digest_on_files (int (*streamfunc) (FILE *, void *),
19 const char *streamfunc_name,
20 size_t digest_size,
21 const void *expected_for_empty_file,
22 const void *expected_for_small_file,
23 const void *expected_for_large_file)
24 {
25 int pass;
26 unlink (TESTFILE);
27
28 for (pass = 0; pass < 5; pass++)
29 {
30 {
31 FILE *fp = fopen (TESTFILE, "wb");
32 if (fp == NULL)
33 {
34 fprintf (stderr, "Could not create file %s.\n", TESTFILE);
35 exit (1);
36 }
37 switch (pass)
38 {
39 case 0:
40 /* Nothing to do for the empty file. */
41 break;
42 case 2:
43 /* Fill the small file, with some header that will be skipped. */
44 fputs ("ABCD", fp);
45 FALLTHROUGH;
46 case 1:
47 /* Fill the small file. */
48 fputs ("The quick brown fox jumps over the lazy dog.\n", fp);
49 break;
50 case 4:
51 /* Fill the large file, with some header that will be skipped. */
52 fputs ("ABCD", fp);
53 FALLTHROUGH;
54 case 3:
55 /* Fill the large file (8 MiB). */
56 {
57 unsigned int i;
58 for (i = 0; i < 0x400000; i++)
59 {
60 unsigned char c[2];
61 unsigned int j = i * (i-1) * (i-5);
62 c[0] = (unsigned char)(j >> 6);
63 c[1] = (i % 499) + (i % 101);
64 fwrite (c, 1, 2, fp);
65 }
66 }
67 break;
68 }
69 if (ferror (fp))
70 {
71 fprintf (stderr, "Could not write data to file %s.\n", TESTFILE);
72 exit (1);
73 }
74 fclose (fp);
75 }
76 {
77 /* Test an unaligned digest. */
78 char *digest = (char *) malloc (digest_size + 1) + 1;
79 const void *expected;
80 FILE *fp;
81 int ret;
82
83 switch (pass)
84 {
85 case 0: expected = expected_for_empty_file; break;
86 case 1: case 2: expected = expected_for_small_file; break;
87 case 3: case 4: expected = expected_for_large_file; break;
88 default: abort ();
89 }
90
91 fp = fopen (TESTFILE, "rb");
92 if (fp == NULL)
93 {
94 fprintf (stderr, "Could not open file %s.\n", TESTFILE);
95 exit (1);
96 }
97 switch (pass)
98 {
99 case 2:
100 case 4:
101 {
102 char header[4];
103 if (fread (header, 1, sizeof (header), fp) != sizeof (header))
104 {
105 fprintf (stderr, "Could not read the header of %s.\n",
106 TESTFILE);
107 exit (1);
108 }
109 }
110 break;
111 }
112 ret = streamfunc (fp, digest);
113 if (ret)
114 {
115 fprintf (stderr, "%s failed with error %d\n", streamfunc_name, -ret);
116 exit (1);
117 }
118 if (memcmp (digest, expected, digest_size) != 0)
119 {
120 size_t i;
121 fprintf (stderr, "%s produced wrong result.\n", streamfunc_name);
122 fprintf (stderr, "Expected: ");
123 for (i = 0; i < digest_size; i++)
124 fprintf (stderr, "\\x%02x", ((const unsigned char *) expected)[i]);
125 fprintf (stderr, "\n");
126 fprintf (stderr, "Got: ");
127 for (i = 0; i < digest_size; i++)
128 fprintf (stderr, "\\x%02x", ((const unsigned char *) digest)[i]);
129 fprintf (stderr, "\n");
130 exit (1);
131 }
132 /* Verify that fp is now positioned at end of file. */
133 if (getc (fp) != EOF)
134 {
135 fprintf (stderr, "%s left the stream not at EOF\n", streamfunc_name);
136 exit (1);
137 }
138 fclose (fp);
139 free (digest - 1);
140 }
141 }
142
143 unlink (TESTFILE);
144 }
145