diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2016-08-02 11:09:46 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2016-08-02 11:09:46 +0000 |
commit | 42e4191ce53a7d77deef2b37ea6b3800cf463172 (patch) | |
tree | 64ae94cf9e4cf6e08ebaadf8903a832a6658d9ac | |
parent | 63629b45891523da62daada0d2e7799efa2a897d (diff) | |
download | mandoc-42e4191ce53a7d77deef2b37ea6b3800cf463172.tar.gz |
POSIX allows PATH_MAX to not be defined, meaning "unlimited".
Found by Aaron M. Ucko <amu at alum dot mit dot edu> on the GNU Hurd,
via Bdale Garbee, https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=829624
Also add EFTYPE at two places where it was forgotten.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | TODO | 7 | ||||
-rw-r--r-- | compat_fts.c | 3 | ||||
-rwxr-xr-x | configure | 3 | ||||
-rw-r--r-- | configure.local.example | 2 | ||||
-rw-r--r-- | test-PATH_MAX.c | 30 |
6 files changed, 47 insertions, 0 deletions
@@ -20,6 +20,7 @@ VERSION = 1.14.0 # === LIST OF FILES ==================================================== TESTSRCS = test-dirent-namlen.c \ + test-EFTYPE.c \ test-err.c \ test-fts.c \ test-getline.c \ @@ -28,6 +29,7 @@ TESTSRCS = test-dirent-namlen.c \ test-mkdtemp.c \ test-nanosleep.c \ test-ohash.c \ + test-PATH_MAX.c \ test-pledge.c \ test-progname.c \ test-reallocarray.c \ @@ -620,6 +620,13 @@ Several areas can be cleaned up to make mandoc even faster. These are * structural issues ************************************************************************ +- POSIX says in the documentation of sysconf(3) that PATH_MAX + is allowed to be so large that it is a bad idea to use it + for sizing static buffers. So use dynamic buffers throughout. + See the file test-PATH_MAX.c for details. + Found by Aaron M. Ucko in the GNU Hurd via Bdale Garbee, + https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=829624 + - We use the input line number at several places to distinguish same-line from different-line input. That plainly doesn't work with user-defined macros, leading to random breakage. diff --git a/compat_fts.c b/compat_fts.c index d949f534..a56458c2 100644 --- a/compat_fts.c +++ b/compat_fts.c @@ -68,6 +68,9 @@ static unsigned short fts_stat(FTS *, FTSENT *); #ifndef O_CLOEXEC #define O_CLOEXEC 0 #endif +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif #define CLR(opt) (sp->fts_options &= ~(opt)) #define ISSET(opt) (sp->fts_options & (opt)) @@ -58,6 +58,7 @@ HAVE_ISBLANK= HAVE_MKDTEMP= HAVE_NANOSLEEP= HAVE_OHASH= +HAVE_PATH_MAX= HAVE_PLEDGE= HAVE_PROGNAME= HAVE_REALLOCARRAY= @@ -203,6 +204,7 @@ runtest getline GETLINE || true runtest getsubopt GETSUBOPT || true runtest isblank ISBLANK || true runtest mkdtemp MKDTEMP || true +runtest PATH_MAX PATH_MAX || true runtest pledge PLEDGE || true runtest sandbox_init SANDBOX_INIT || true runtest progname PROGNAME || true @@ -293,6 +295,7 @@ echo "#define MANPATH_DEFAULT \"${MANPATH_DEFAULT}\"" [ -n "${UTF8_LOCALE}" ] && echo "#define UTF8_LOCALE \"${UTF8_LOCALE}\"" [ -n "${HOMEBREWDIR}" ] && echo "#define HOMEBREWDIR \"${HOMEBREWDIR}\"" [ ${HAVE_EFTYPE} -eq 0 ] && echo "#define EFTYPE EINVAL" +[ ${HAVE_PATH_MAX} -eq 0 ] && echo "#define PATH_MAX 4096" cat << __HEREDOC__ #define HAVE_DIRENT_NAMLEN ${HAVE_DIRENT_NAMLEN} diff --git a/configure.local.example b/configure.local.example index e5d0f7a8..d9652f1d 100644 --- a/configure.local.example +++ b/configure.local.example @@ -227,6 +227,7 @@ CFLAGS="-g" # be regarded as successful). HAVE_DIRENT_NAMLEN=0 +HAVE_EFTYPE=0 HAVE_ERR=0 HAVE_FTS=0 HAVE_GETLINE=0 @@ -234,6 +235,7 @@ HAVE_GETSUBOPT=0 HAVE_ISBLANK=0 HAVE_MKDTEMP=0 HAVE_OHASH=0 +HAVE_PATH_MAX=0 HAVE_PLEDGE=0 HAVE_PROGNAME=0 HAVE_REALLOCARRAY=0 diff --git a/test-PATH_MAX.c b/test-PATH_MAX.c new file mode 100644 index 00000000..99bcc0b4 --- /dev/null +++ b/test-PATH_MAX.c @@ -0,0 +1,30 @@ +/* + * POSIX allows PATH_MAX to not be defined, see + * http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html; + * the GNU Hurd is an example of a system not having it. + * + * Arguably, it would be better to test sysconf(_SC_PATH_MAX), + * but since the individual *.c files include "config.h" before + * <limits.h>, overriding an excessive value of PATH_MAX from + * "config.h" is impossible anyway, so for now, the simplest + * fix is to provide a value only on systems not having any. + * So far, we encountered no system defining PATH_MAX to an + * impractically large value, even though POSIX explicitly + * allows that. + * + * The real fix would be to replace all static buffers of size + * PATH_MAX by dynamically allocated buffers. But that is + * somewhat intrusive because it touches several files and + * because it requires changing struct mlink in mandocdb.c. + * So i'm postponing that for now. + */ + +#include <limits.h> +#include <stdio.h> + +int +main(void) +{ + printf("PATH_MAX is defined to be %ld\n", (long)PATH_MAX); + return 0; +} |