Bug#644023: FTBFS on kfreebsd-i386
Petr Salinger wrote:
> It effectively test return code of
>
> fprintf (fp, "%2147483648d%2147483648d", 1, 1);
>
> The printf family returns int and should return number of written bytes.
> It therefore cannot exceed MAX_INT.
>
> But the test tries to print twice entry with width MAX_INT+1.
> I would understand the test with i.e. 2147483640
> or six time 512 MB.
Yeah, your suggested test would be a more precise test for the
original bug[1].
C99 (N1256 §7.19.6.1.4) only tells us that the field width is a
"nonnegative decimal integer". It would be nice to clarify with the C
working group whether a field width that doesn't fit into an "int"
triggers undefined behavior or if the implementation is obligated to
catch it.
> On kfreebsd-amd64, it tries to
> mmap(0,0xffffffff80001000,PROT_READ|PROT_WRITE,MAP_ANON|MAP_TYPE|MAP_PRIVATE,0xffffffff,0)
> and fails.
Sounds buggy. In fact, there are at least a couple of seemingly buggy
aspects here.
- read_int does not check for overflow
- read_int returns "unsigned int", but "prec" and "width" are ints
- the "for (; (size_t) nspecs_done < nspecs; ++nspecs_done)" loop
does not check for overflow when deciding the initial work buffer
size
- the private __parse_one_spec API (and public parse_printf_format
API) does not seem to include a way to indicate overflow
Anyway, how about this patch? It implements your 6 times 512 MiB idea
(well, 3 times 1 GiB because I'm lazy) and adds a new test for the
related bug Robert found (which gets masked on Linux by malloc() not
bothering to try to fulfill such huge requests --- maybe it would be
possible to tweak it so it can fail on Linux, too).
---
[1] http://sourceware.org/bugzilla/show_bug.cgi?id=5424
stdio-common/Makefile | 2 +-
stdio-common/bug22.c | 5 +++--
stdio-common/bug22a.c | 33 +++++++++++++++++++++++++++++++++
3 files changed, 37 insertions(+), 3 deletions(-)
create mode 100644 stdio-common/bug22a.c
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index 006f5468..3be668cc 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -60,7 +60,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \
bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
- scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24
+ bug22a scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24
test-srcs = tst-unbputc tst-printf
diff --git a/stdio-common/bug22.c b/stdio-common/bug22.c
index 2228388b..1f59c735 100644
--- a/stdio-common/bug22.c
+++ b/stdio-common/bug22.c
@@ -1,7 +1,8 @@
/* BZ #5424 */
#include <stdio.h>
-#define N 2147483648
+/* 1 GiB * 3 > INT_MAX bytes */
+#define N 1073741824
#define STRINGIFY(S) #S
#define MAKE_STR(S) STRINGIFY(S)
@@ -20,7 +21,7 @@ do_test (void)
return 1;
}
- ret = fprintf (fp, "%" SN "d%" SN "d", 1, 1);
+ ret = fprintf (fp, "%" SN "d%" SN "d%" SN "d", 1, 1);
printf ("ret = %d\n", ret);
diff --git a/stdio-common/bug22a.c b/stdio-common/bug22a.c
new file mode 100644
index 00000000..37efea39
--- /dev/null
+++ b/stdio-common/bug22a.c
@@ -0,0 +1,33 @@
+/* Not in BZ yet */
+#include <stdio.h>
+
+/* 2 GiB == INT_MAX + 1 */
+#define N 2147483648
+
+#define STRINGIFY(S) #S
+#define MAKE_STR(S) STRINGIFY(S)
+
+#define SN MAKE_STR(N)
+
+static int
+do_test (void)
+{
+ int ret;
+
+ FILE *fp = fopen ("/dev/null", "w");
+ if (fp == NULL)
+ {
+ puts ("cannot open /dev/null");
+ return 1;
+ }
+
+ ret = fprintf (fp, "%" SN "d", 1, 1);
+
+ printf ("ret = %d\n", ret);
+
+ return ret != -1;
+}
+
+#define TIMEOUT 30
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
--
1.7.7.rc1
Reply to: