(root)/
coreutils-9.4/
gnulib-tests/
test-digest.h
       1  /* Test of message digests.
       2     Copyright (C) 2018-2023 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
      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  }