diff mbox series

[v2] Add tests of fread [committed]

Message ID 075533ad-4deb-a154-845a-9eb51671e589@redhat.com
State New
Headers show
Series [v2] Add tests of fread [committed] | expand

Commit Message

Joseph Myers Sept. 24, 2024, 2:08 p.m. UTC
On Mon, 23 Sep 2024, DJ Delorie wrote:

> There are three includes you could do without, but leaving them in won't
> hurt either.  LGTM.

Removed.  Committed revised patch in the form below after retesting.

> I wonder if it would be useful to have a test that makes sure
> fread(x,-1,-1,y) doesn't blindly multply -1*-1 and read one
> byte... (yes, I know they're unsigned).

Testing overflow like that is problematic.  The handling of overflow
is arguably buggy, but apparently the Linux kernel expects a buffer as
large as the passed size even if in fact you know there will be EOF
long before then.  See bug 19165 and the past discussion referenced
therein.



Add tests of fread

There seem to be no glibc tests specifically for the fread function.
Add basic tests of that function.

Tested for x86_64.

---

Changed in v2: removed unnecessary includes.
diff mbox series

Patch

diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index 62f8b99b06..e3e5f634c5 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -217,6 +217,7 @@  tests := \
   tst-fmemopen4 \
   tst-fphex \
   tst-fphex-wide \
+  tst-fread \
   tst-freopen2 \
   tst-freopen3 \
   tst-freopen4 \
diff --git a/stdio-common/tst-fread.c b/stdio-common/tst-fread.c
new file mode 100644
index 0000000000..4d9a7895f6
--- /dev/null
+++ b/stdio-common/tst-fread.c
@@ -0,0 +1,134 @@ 
+/* Test fread.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+
+int
+do_test (void)
+{
+  char *temp_dir = support_create_temp_directory ("tst-fread");
+  char *file1 = xasprintf ("%s/file1", temp_dir);
+  support_write_file_string (file1, "file1");
+  add_temp_file (file1);
+  FILE *fp;
+  size_t ret;
+  char buf[1024];
+
+  verbose_printf ("test single-byte reads\n");
+  fp = xfopen (file1, "r");
+  memset (buf, 0, sizeof buf);
+  ret = fread (buf, 1, 2, fp);
+  TEST_COMPARE (ret, 2);
+  TEST_COMPARE (buf[0], 'f');
+  TEST_COMPARE (buf[1], 'i');
+  TEST_COMPARE (feof (fp), 0);
+  TEST_COMPARE (ftell (fp), 2);
+  memset (buf, 0, sizeof buf);
+  ret = fread (buf, 1, 3, fp);
+  TEST_COMPARE (ret, 3);
+  TEST_COMPARE (buf[0], 'l');
+  TEST_COMPARE (buf[1], 'e');
+  TEST_COMPARE (buf[2], '1');
+  TEST_COMPARE (ftell (fp), 5);
+  TEST_COMPARE (feof (fp), 0);
+  memset (buf, 0, sizeof buf);
+  ret = fread (buf, 1, 1, fp);
+  TEST_COMPARE (ret, 0);
+  TEST_COMPARE (!!feof (fp), 1);
+  TEST_COMPARE (ferror (fp), 0);
+  TEST_COMPARE (ftell (fp), 5);
+  xfclose (fp);
+
+  verbose_printf ("test single-byte reads, EOF part way through\n");
+  fp = xfopen (file1, "r");
+  memset (buf, 0, sizeof buf);
+  ret = fread (buf, 1, sizeof buf, fp);
+  TEST_COMPARE (ret, 5);
+  TEST_COMPARE (buf[0], 'f');
+  TEST_COMPARE (buf[1], 'i');
+  TEST_COMPARE (buf[2], 'l');
+  TEST_COMPARE (buf[3], 'e');
+  TEST_COMPARE (buf[4], '1');
+  TEST_COMPARE (!!feof (fp), 1);
+  TEST_COMPARE (ferror (fp), 0);
+  TEST_COMPARE (ftell (fp), 5);
+  xfclose (fp);
+
+  verbose_printf ("test multi-byte reads\n");
+  fp = xfopen (file1, "r");
+  memset (buf, 0, sizeof buf);
+  ret = fread (buf, 2, 2, fp);
+  TEST_COMPARE (ret, 2);
+  TEST_COMPARE (buf[0], 'f');
+  TEST_COMPARE (buf[1], 'i');
+  TEST_COMPARE (buf[2], 'l');
+  TEST_COMPARE (buf[3], 'e');
+  TEST_COMPARE (feof (fp), 0);
+  TEST_COMPARE (ftell (fp), 4);
+  memset (buf, 0, sizeof buf);
+  ret = fread (buf, 3, 3, fp);
+  TEST_COMPARE (ret, 0);
+  /* The bytes written for a partial element read are unspecified.  */
+  TEST_COMPARE (!!feof (fp), 1);
+  TEST_COMPARE (ferror (fp), 0);
+  TEST_COMPARE (ftell (fp), 5);
+  xfclose (fp);
+
+  verbose_printf ("test read error\n");
+  fp = xfopen (file1, "r");
+  xclose (fileno (fp));
+  memset (buf, 0, sizeof buf);
+  ret = fread (buf, 1, sizeof buf, fp);
+  TEST_COMPARE (ret, 0);
+  TEST_COMPARE (feof (fp), 0);
+  TEST_COMPARE (!!ferror (fp), 1);
+  fclose (fp);
+
+  verbose_printf ("test zero size\n");
+  fp = xfopen (file1, "r");
+  ret = fread (buf, 0, SIZE_MAX, fp);
+  TEST_COMPARE (ret, 0);
+  TEST_COMPARE (feof (fp), 0);
+  TEST_COMPARE (ferror (fp), 0);
+  TEST_COMPARE (ftell (fp), 0);
+  xfclose (fp);
+
+  verbose_printf ("test zero items\n");
+  fp = xfopen (file1, "r");
+  ret = fread (buf, SIZE_MAX, 0, fp);
+  TEST_COMPARE (ret, 0);
+  TEST_COMPARE (feof (fp), 0);
+  TEST_COMPARE (ferror (fp), 0);
+  TEST_COMPARE (ftell (fp), 0);
+  xfclose (fp);
+
+  free (temp_dir);
+  free (file1);
+  return 0;
+}
+
+#include <support/test-driver.c>