test-snprintf: New test program.

We want to make testers aware that snprintf() is not behaving identically
on all platforms.  In fact, glibc offers the least robust implementation.
An observation leading to this test was reported by Zhixiong Chi.
This commit is contained in:
Mats Erik Andersson
2020-02-09 02:17:01 +01:00
parent da919de3f4
commit a1d8a1f87d
4 changed files with 95 additions and 2 deletions

View File

@@ -1,3 +1,17 @@
2020-02-09 Mats Erik Andersson <gnu@gisladisker.se>
test-snprintf: New test program.
An implementation dependent feature of snprintf() is tested.
The BSD unices and OpenSolaris relatives are known to be more
forgiving, than is Linux/glibc and kfreebsd/glibc. The issue
was brought to our attention by Zhixiong Chi in:
https://lists.gnu.org/archive/html/bug-inetutils/2019-05/msg00002.html
* tests/test-snprintf.c: New file.
* tests/Makefile.am (check_PROGRAMS, TESTS): Add `test-snprintf'.
* tests/.gitignore: Likewise.
2020-02-04 Mats Erik Andersson <gnu@gisladisker.se>
Buffer overflow in tftp and tftpd.

1
tests/.gitignore vendored
View File

@@ -5,6 +5,7 @@ ls
readutmp
runtime-ipv6
tcpget
test-snprintf
tools.sh
waitdaemon
*.log

View File

@@ -23,7 +23,7 @@ LDADD = $(iu_LIBRARIES)
noinst_PROGRAMS = identify
identify_LDADD = $(top_builddir)/lib/libgnu.a $(LIBUTIL)
check_PROGRAMS = localhost readutmp runtime-ipv6 waitdaemon
check_PROGRAMS = localhost readutmp runtime-ipv6 test-snprintf waitdaemon
dist_check_SCRIPTS = utmp.sh
@@ -86,7 +86,7 @@ if ENABLE_ifconfig
dist_check_SCRIPTS += ifconfig.sh
endif
TESTS = localhost waitdaemon $(dist_check_SCRIPTS)
TESTS = localhost test-snprintf waitdaemon $(dist_check_SCRIPTS)
TESTS_ENVIRONMENT = EXEEXT=$(EXEEXT)

78
tests/test-snprintf.c Normal file
View File

@@ -0,0 +1,78 @@
/* test-snprintf - Check whether snprintf allows doubly used strings.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of GNU Inetutils.
GNU Inetutils is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
GNU Inetutils 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
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see `http://www.gnu.org/licenses/'. */
/* Written by Mats Erik Andersson. */
/*
* It is not in violation of POSIX, but implementations of snprintf()
* differ in their ability to handle a situation where the target string
* to be produced by snprintf() is at the same time providing data, which
* are to be passed through the format string, and to be part of the new
* resulting string. The different BSD unices, as well as OpenSolaris,
* are known to correctly handle this, whereas glibc is known to fail.
*
* This test issues a warning that non-portable behaviour is possible,
* should the program detect a discrepancy on this system. If the
* program detects the macro PACKAGE to have value "inetutils", then
* get attention with the exit value 77, to fit with our testing
* frame work.
*
* When the environment variable VERBOSE is defined, an encouraging
* message is issued also in the presence of an enhanced implementation
* of snprintf().
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MESSAGE "try a fool"
#define WRONG_MESSAGE "fool"
int
main (void)
{
int err = 0;
char msg[sizeof (MESSAGE)] = "try a ";
snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
if (!strcmp (msg, WRONG_MESSAGE))
{
printf ("Warning! This implementation of snprintf() is not able\n"
"to handle string variables that appear as target and at the\n"
"same time as source. This might be a portability issue!\n");
#ifdef PACKAGE
if (!strcmp (PACKAGE, "inetutils"))
err = 77;
#endif
}
else if (getenv ("VERBOSE"))
{
printf ("The present implementation of snprintf() allows the same\n"
"string to act as target as well as source. Good news!\n");
}
/* Always return successfully, as we are only producing a reminder,
rather than a show stopper. */
return err;
}