From 5c2a5d72aefb44e00cedacd01f91a243ca931936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Forr=C3=B3?= Date: Fri, 30 Jul 2021 17:07:25 +0200 Subject: [PATCH] Fix important Covscan defects - resolves: #1938814 --- man-db-2.9.3-coverity.patch | 58 ++++++ man-db.spec | 9 +- tests/man-db/Makefile | 45 +++++ tests/man-db/README | 7 + tests/man-db/fspause.c | 133 ++++++++++++++ tests/man-db/lexgrog-backslash-dash-rhs | 20 ++ tests/man-db/lexgrog-basic | 18 ++ tests/man-db/lexgrog-multiple-whatis | 26 +++ tests/man-db/man-deleted-directory | 26 +++ tests/man-db/man-exact-section-matches | 41 +++++ tests/man-db/man-executable-page-on-path | 23 +++ tests/man-db/man-invalid-db-entry | 31 ++++ tests/man-db/man-language-specific-requests | 58 ++++++ tests/man-db/man-mandatory-manpath | 173 ++++++++++++++++++ tests/man-db/man-missing-locales | 28 +++ tests/man-db/man-override-dir | 46 +++++ tests/man-db/man-recode-in-place | 46 +++++ tests/man-db/man-recode-suffix | 43 +++++ tests/man-db/man-so-links-same-section | 90 +++++++++ tests/man-db/man-suffixed-extension | 53 ++++++ tests/man-db/man-symlinks-with-matching-names | 31 ++++ tests/man-db/manconv-coding-tags | 61 ++++++ tests/man-db/manconv-guess-from-encoding | 38 ++++ tests/man-db/manconv-incomplete-char-at-eof | 15 ++ tests/man-db/manconv-odd-combinations | 78 ++++++++ tests/man-db/mandb-basic | 24 +++ tests/man-db/mandb-bogus-symlink | 25 +++ tests/man-db/mandb-cachedir-tag | 28 +++ tests/man-db/mandb-empty-page | 30 +++ .../man-db/mandb-regular-file-symlink-changes | 67 +++++++ tests/man-db/mandb-symlink-beats-whatis-ref | 60 ++++++ tests/man-db/mandb-whatis-broken-link-changes | 55 ++++++ tests/man-db/testlib.sh | 105 +++++++++++ tests/man-db/whatis-path-to-executable | 56 ++++++ tests/man-db/zsoelim-so-includes | 61 ++++++ tests/tests.yml | 13 ++ tests/upstream-test-suite | 27 +++ 37 files changed, 1747 insertions(+), 1 deletion(-) create mode 100644 man-db-2.9.3-coverity.patch create mode 100644 tests/man-db/Makefile create mode 100644 tests/man-db/README create mode 100644 tests/man-db/fspause.c create mode 100644 tests/man-db/lexgrog-backslash-dash-rhs create mode 100755 tests/man-db/lexgrog-basic create mode 100755 tests/man-db/lexgrog-multiple-whatis create mode 100755 tests/man-db/man-deleted-directory create mode 100755 tests/man-db/man-exact-section-matches create mode 100755 tests/man-db/man-executable-page-on-path create mode 100755 tests/man-db/man-invalid-db-entry create mode 100755 tests/man-db/man-language-specific-requests create mode 100755 tests/man-db/man-mandatory-manpath create mode 100755 tests/man-db/man-missing-locales create mode 100755 tests/man-db/man-override-dir create mode 100755 tests/man-db/man-recode-in-place create mode 100755 tests/man-db/man-recode-suffix create mode 100755 tests/man-db/man-so-links-same-section create mode 100755 tests/man-db/man-suffixed-extension create mode 100755 tests/man-db/man-symlinks-with-matching-names create mode 100755 tests/man-db/manconv-coding-tags create mode 100755 tests/man-db/manconv-guess-from-encoding create mode 100755 tests/man-db/manconv-incomplete-char-at-eof create mode 100755 tests/man-db/manconv-odd-combinations create mode 100755 tests/man-db/mandb-basic create mode 100755 tests/man-db/mandb-bogus-symlink create mode 100755 tests/man-db/mandb-cachedir-tag create mode 100755 tests/man-db/mandb-empty-page create mode 100755 tests/man-db/mandb-regular-file-symlink-changes create mode 100755 tests/man-db/mandb-symlink-beats-whatis-ref create mode 100755 tests/man-db/mandb-whatis-broken-link-changes create mode 100644 tests/man-db/testlib.sh create mode 100755 tests/man-db/whatis-path-to-executable create mode 100755 tests/man-db/zsoelim-so-includes create mode 100644 tests/tests.yml create mode 100755 tests/upstream-test-suite diff --git a/man-db-2.9.3-coverity.patch b/man-db-2.9.3-coverity.patch new file mode 100644 index 0000000..1adfbd7 --- /dev/null +++ b/man-db-2.9.3-coverity.patch @@ -0,0 +1,58 @@ +diff --git a/src/man.c b/src/man.c +index b3d13d1..030a5d1 100644 +--- a/src/man.c ++++ b/src/man.c +@@ -991,11 +991,17 @@ static char *get_preprocessors_from_file (pipeline *decomp, int prefixes) + + if (!strncmp (line, PP_COOKIE, 4)) { + const char *newline = strchr (line, '\n'); +- if (newline) +- return xstrndup (line + 4, newline - (line + 4)); +- else +- return xstrdup (line + 4); ++ if (newline) { ++ char *ret = xstrndup (line + 4, newline - (line + 4)); ++ free (line); ++ return ret; ++ } else { ++ char *ret = xstrdup (line + 4); ++ free (line); ++ return ret; ++ } + } ++ free (line); + return NULL; + } + +@@ -2401,6 +2407,7 @@ static int display (const char *dir, const char *man_file, + if (!found) { + pipeline_free (format_cmd); + pipeline_free (decomp); ++ free (formatted_encoding); + return found; + } + +diff --git a/src/zsoelim.c b/src/zsoelim.c +index bf5c8ff..6a484c4 100644 +--- a/src/zsoelim.c ++++ b/src/zsoelim.c +@@ -2528,6 +2528,7 @@ int zsoelim_open_file (const char *filename, gl_list_t manpathlist, + if (decomp) { + NAME = xstrdup (found_name); + gl_list_free (names); ++ free (name); + goto out; + } + } GL_LIST_FOREACH_END (names); +diff --git a/src/zsoelim.l b/src/zsoelim.l +index a8a7e3b..3cb552b 100644 +--- a/src/zsoelim.l ++++ b/src/zsoelim.l +@@ -473,6 +473,7 @@ int zsoelim_open_file (const char *filename, gl_list_t manpathlist, + if (decomp) { + NAME = xstrdup (found_name); + gl_list_free (names); ++ free (name); + goto out; + } + } GL_LIST_FOREACH_END (names); diff --git a/man-db.spec b/man-db.spec index 77f2b6b..97fbf61 100644 --- a/man-db.spec +++ b/man-db.spec @@ -4,7 +4,7 @@ Summary: Tools for searching and reading man pages Name: man-db Version: 2.9.3 -Release: 4%{?dist} +Release: 5%{?dist} # GPLv2+ .. man-db # GPLv3+ .. gnulib License: GPLv2+ and GPLv3+ @@ -24,6 +24,9 @@ Patch1: man-db-2.8.7-fix-override-dir-handling.patch # https://lists.gnu.org/archive/html/man-db-devel/2020-02/msg00000.html Patch2: man-db-2.9.1-snap.patch +# fix important Covscan defects +Patch3: man-db-2.9.3-coverity.patch + Obsoletes: man < 2.0 Provides: man = %{version} Provides: man-pages-reader = %{version} @@ -232,6 +235,10 @@ fi %config(noreplace) %{_sysconfdir}/cron.daily/man-db.cron %changelog +* Fri Jul 30 2021 Nikola Forró - 2.9.3-5 +- fix important Covscan defects + resolves #1938814 + * Fri Apr 16 2021 Mohan Boddu - 2.9.3-4 - Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 diff --git a/tests/man-db/Makefile b/tests/man-db/Makefile new file mode 100644 index 0000000..5cb0479 --- /dev/null +++ b/tests/man-db/Makefile @@ -0,0 +1,45 @@ +SH ?= sh + +TESTS = \ + lexgrog-backslash-dash-rhs \ + lexgrog-basic \ + lexgrog-multiple-whatis \ + man-deleted-directory \ + man-exact-section-matches \ + man-executable-page-on-path \ + man-invalid-db-entry \ + man-language-specific-requests \ + man-mandatory-manpath \ + man-missing-locales \ + man-override-dir \ + man-recode-in-place \ + man-recode-suffix \ + man-so-links-same-section \ + man-suffixed-extension \ + man-symlinks-with-matching-names \ + manconv-coding-tags \ + manconv-guess-from-encoding \ + manconv-incomplete-char-at-eof \ + manconv-odd-combinations \ + mandb-basic \ + mandb-bogus-symlink \ + mandb-cachedir-tag \ + mandb-empty-page \ + mandb-regular-file-symlink-changes \ + mandb-symlink-beats-whatis-ref \ + mandb-whatis-broken-link-changes \ + whatis-path-to-executable \ + zsoelim-so-includes + +export DBTYPE = gdbm +export MANCONV = /usr/libexec/man-db/manconv + +.PHONY: test $(TESTS) + +test: $(TESTS) + +fspause: fspause.c + $(CC) $(CFLAGS) -o $@ $< + +$(TESTS): %: fspause + $(SH) $@ diff --git a/tests/man-db/README b/tests/man-db/README new file mode 100644 index 0000000..a70c6d5 --- /dev/null +++ b/tests/man-db/README @@ -0,0 +1,7 @@ +man-db test suite modified to run against installed man-db + +All files except the following are taken unmodified from upstream tarball: + +Makefile +fspause.c +testlib.sh diff --git a/tests/man-db/fspause.c b/tests/man-db/fspause.c new file mode 100644 index 0000000..be5cf2d --- /dev/null +++ b/tests/man-db/fspause.c @@ -0,0 +1,133 @@ +/* + * fspause.c: pause until a file timestamp updates + * + * Copyright (C) 2014 Colin Watson. + * + * This file is part of man-db. + * + * man-db 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 2 of the License, or + * (at your option) any later version. + * + * man-db 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 man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static char *filename; +static int fd = -1; + +#define MUST(name, cond) \ + do { \ + if (!(cond)) { \ + fprintf (stderr, "fspause: " name " failed\n"); \ + abort (); \ + } \ + } while (0) + +struct timespec get_stat_mtime (struct stat const *st) +{ + return st->st_mtim; +} + +int timespec_cmp (struct timespec a, struct timespec b) +{ + if (a.tv_sec < b.tv_sec) + return -1; + if (a.tv_sec > b.tv_sec) + return 1; + + return a.tv_nsec - b.tv_nsec; +} + +char *xstrdup (char const *string) +{ + size_t n = strlen (string) + 1; + void *p = malloc (n); + + if (!p && n != 0) { + fprintf (stderr, "fspause: memory exhausted\n"); + abort (); + } + + return memcpy (p, string, n); +} + +static void unlink_tempfile (void) +{ + if (fd >= 0) { + MUST ("close", close (fd) >= 0); + MUST ("unlink", unlink (filename) >= 0); + } +} + +static void delay (int delay_ns) +{ + struct timespec delay_ts; + + delay_ts.tv_sec = delay_ns / 1000000000; + delay_ts.tv_nsec = delay_ns % 1000000000; + for (;;) { + errno = 0; + if (nanosleep (&delay_ts, NULL) == 0) + break; + MUST ("nanosleep", errno == 0 || errno == EINTR); + } +} + +static int try_delay (struct stat *st, int delay_ns) +{ + struct timespec start_ts, end_ts; + + start_ts = get_stat_mtime (st); + delay (delay_ns); + MUST ("write", write (fd, "\n", 1) == 1); + MUST ("fstat", fstat (fd, st) >= 0); + end_ts = get_stat_mtime (st); + return timespec_cmp (start_ts, end_ts) != 0; +} + +int main (int argc, char **argv) +{ + struct stat st; + int delay_ns; + + filename = xstrdup ("fspause.tmp.XXXXXX"); + MUST ("mkstemp", (fd = mkstemp (filename)) >= 0); + atexit (unlink_tempfile); + MUST ("fstat", fstat (fd, &st) >= 0); + + /* 0x40000000 nanoseconds is just over a second. The effective + * maximum delay we will allow is thus about two seconds. This + * saves us having to keep track of anything more complicated than a + * single signed 32-bit int. + */ + for (delay_ns = 1; delay_ns < 0x40000000; delay_ns *= 2) { + if (try_delay (&st, delay_ns)) + return 0; + } + + fprintf (stderr, + "fspause: temporary file timestamp refuses to change!\n"); + return 1; +} diff --git a/tests/man-db/lexgrog-backslash-dash-rhs b/tests/man-db/lexgrog-backslash-dash-rhs new file mode 100644 index 0000000..a6a66a9 --- /dev/null +++ b/tests/man-db/lexgrog-backslash-dash-rhs @@ -0,0 +1,20 @@ +#! /bin/sh + +# Test handling of \- in the right-hand side of a NAME section. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${LEXGROG=lexgrog} + +init + +write_page lextest 1 "$tmpdir/usr/share/man/man1/lextest.1.gz" UTF-8 gz '' \ + 'lextest \- see lextest \-\-help' +cat >"$tmpdir/3.exp" <"$tmpdir/3.out" +expect_pass 'multiple whatis definitions' 'diff -u "$tmpdir/3.exp" "$tmpdir/3.out"' + +finish diff --git a/tests/man-db/lexgrog-basic b/tests/man-db/lexgrog-basic new file mode 100755 index 0000000..8ab8a0f --- /dev/null +++ b/tests/man-db/lexgrog-basic @@ -0,0 +1,18 @@ +#! /bin/sh + +# Basic lexgrog tests. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${LEXGROG=lexgrog} + +init + +write_page lextest 1 "$tmpdir/usr/share/man/man1/lextest.1.gz" UTF-8 gz '' \ + 'lextest \- simple lexgrog test' +echo "$tmpdir/usr/share/man/man1/lextest.1.gz: \"lextest - simple lexgrog test\"" >"$tmpdir/1.exp" +run $LEXGROG "$tmpdir/usr/share/man/man1/lextest.1.gz" >"$tmpdir/1.out" +expect_pass 'simple lexgrog test' 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +finish diff --git a/tests/man-db/lexgrog-multiple-whatis b/tests/man-db/lexgrog-multiple-whatis new file mode 100755 index 0000000..eac8dbd --- /dev/null +++ b/tests/man-db/lexgrog-multiple-whatis @@ -0,0 +1,26 @@ +#! /bin/sh + +# Test multiple whatis definitions. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${LEXGROG=lexgrog} + +init + +name_section="\ +lextest \\- one whatis definition +.br +lextest2 \\- another whatis definition" + +write_page lextest 1 "$tmpdir/usr/share/man/man1/lextest.1.gz" UTF-8 gz '' \ + "$name_section" +cat >"$tmpdir/2.exp" <"$tmpdir/2.out" +expect_pass 'multiple whatis definitions' 'diff -u "$tmpdir/2.exp" "$tmpdir/2.out"' + +finish diff --git a/tests/man-db/man-deleted-directory b/tests/man-db/man-deleted-directory new file mode 100755 index 0000000..75ec2a5 --- /dev/null +++ b/tests/man-db/man-deleted-directory @@ -0,0 +1,26 @@ +#! /bin/sh + +# Test that man can run from a deleted directory. +# https://bugs.debian.org/764384 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN=man} + +init +echo "MANDATORY_MANPATH $abstmpdir/usr/share/man" >"$tmpdir/manpath.config" +MANPATH="$abstmpdir/usr/share/man" +export MANPATH + +write_page test 1 "$tmpdir/usr/share/man/man1/test.1" \ + UTF-8 '' '' 'test \- test' +mkdir "$tmpdir/zombie" +cd "$tmpdir/zombie" +rmdir "$abstmpdir/zombie" || \ + skip "can't remove current working directory on this system" +run $MAN -C "$abstmpdir/manpath.config" test >/dev/null +code=$? +expect_pass 'run from deleted directory' 'test "$code" = 0' + +finish diff --git a/tests/man-db/man-exact-section-matches b/tests/man-db/man-exact-section-matches new file mode 100755 index 0000000..d2bac98 --- /dev/null +++ b/tests/man-db/man-exact-section-matches @@ -0,0 +1,41 @@ +#! /bin/sh + +# Test for: +# https://bugzilla.redhat.com/show_bug.cgi?id=684977 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +case $MANDIR_LAYOUT in + ""|GNU) + ;; + *) + skip "only applicable to GNU layout" + ;; +esac + +: ${MAN=man} + +init +fake_config /usr/share/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH + +# Force default section order. +cat >>"$tmpdir/manpath.config" <"$tmpdir/1.exp" <"$tmpdir/1.out" +expect_pass 'exact section matches win' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +finish diff --git a/tests/man-db/man-executable-page-on-path b/tests/man-db/man-executable-page-on-path new file mode 100755 index 0000000..f05291b --- /dev/null +++ b/tests/man-db/man-executable-page-on-path @@ -0,0 +1,23 @@ +#! /bin/sh + +# Test for: +# https://bugs.debian.org/608490 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN=man} + +init +fake_config /usr/share/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH + +write_page file 1 "$tmpdir/file.1" UTF-8 '' '' 'file \- test' +chmod +x "$tmpdir/file.1" +PATH="$PATH:$tmpdir" run $MAN \ + -C "$tmpdir/manpath.config" "$tmpdir/file.1" >/dev/null +code=$? +expect_pass 'executable page on path' 'test "$code" = 0' + +finish diff --git a/tests/man-db/man-invalid-db-entry b/tests/man-db/man-invalid-db-entry new file mode 100755 index 0000000..8c32e3d --- /dev/null +++ b/tests/man-db/man-invalid-db-entry @@ -0,0 +1,31 @@ +#! /bin/sh + +# Test for invalid DB entry. +# https://bugzilla.redhat.com/show_bug.cgi?id=841431 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN=man} +: ${MANDB=mandb} + +init +fake_config /usr/share/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH + +MAN_TEST_DISABLE_UNDOCUMENTED=1 +export MAN_TEST_DISABLE_UNDOCUMENTED + +write_page test 1 "$tmpdir/usr/share/man/man1/test.1" \ + UTF-8 '' '' 'test \- top-level test page' +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" + +rm -f "$tmpdir/usr/share/man/man1/test.1" + +echo "No manual entry for test" > "$tmpdir/1.exp" +LC_ALL=C run $MAN -C "$tmpdir/manpath.config" test 2> "$tmpdir/1.out" +expect_pass 'invalid DB entry' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +finish diff --git a/tests/man-db/man-language-specific-requests b/tests/man-db/man-language-specific-requests new file mode 100755 index 0000000..cb19790 --- /dev/null +++ b/tests/man-db/man-language-specific-requests @@ -0,0 +1,58 @@ +#! /bin/sh + +# Test additional language-specific requests for localized man pages. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN=man} + +init +fake_config /usr/share/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH + +cat >"$tmpdir/fake-program" <>"$tmpdir/manpath.config" <"$tmpdir/1.exp" <<'EOF' +. mso xyzzy.tmac +.hla xyzzy +test \- xyzzy language page for test +EOF + +cat >"$tmpdir/2.exp" <<'EOF' +.TH xyz 1 +test \- top-level xyz page +EOF + +run $MAN -L xyzzy_foo.bar -C "$tmpdir/manpath.config" test |\ + grep 'xyzzy' >"$tmpdir/1.out" +expect_pass 'language-specific requests for localized man page' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +run $MAN -L xyzzy_foo.bar -C "$tmpdir/manpath.config" xyz |\ + grep 'xyz' >"$tmpdir/2.out" +expect_pass 'no language-specific requests for top-level man page' \ + 'diff -u "$tmpdir/2.exp" "$tmpdir/2.out"' + +finish diff --git a/tests/man-db/man-mandatory-manpath b/tests/man-db/man-mandatory-manpath new file mode 100755 index 0000000..75633ac --- /dev/null +++ b/tests/man-db/man-mandatory-manpath @@ -0,0 +1,173 @@ +#! /bin/sh + +# Test for wildcards in MANDATORY_MANPATH in config file and in MANPATH. +# https://bugzilla.redhat.com/show_bug.cgi?id=677669 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN=man} + +init +> "$tmpdir/manpath.config" + +MAN_TEST_DISABLE_PATH=1 +export MAN_TEST_DISABLE_PATH + +write_page manx 1 "$tmpdir/usr/share/man/man1/manx.1.gz" \ + UTF-8 gz '' 'manx \- an interface to the system reference manuals' +write_page manpathx 1 "$tmpdir/usr/share/prog/a/man/man1/manpathx.1.gz" \ + UTF-8 gz '' 'manpathx \- determine search path for manual pages' +write_page whatisx 1 "$tmpdir/usr/share/prog/b/man/man1/whatisx.1.gz" \ + UTF-8 gz '' 'whatisx \- display manual page descriptions' + +# +# Testing -M option +# + +# Without wildcards +Mpath="$tmpdir/usr/share/man" + +run $MAN -C "$tmpdir/manpath.config" \ + -aw -M "${Mpath}" manpathx > "$tmpdir/1.out" 2> /dev/null +> "$tmpdir/1.exp" +expect_pass 'wildcards: -M option: without wildcards: check missing man page' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +run $MAN -C "$tmpdir/manpath.config" \ + -aw -M "${Mpath}" manx > "$tmpdir/1.out" +cat > "$tmpdir/1.exp" < "$tmpdir/1.out" 2> /dev/null +> "$tmpdir/1.exp" +expect_pass 'wildcards: -M option: with wildcards: check missing man page' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +run $MAN -C "$tmpdir/manpath.config" \ + -aw -M "${Mpath}" manpathx > "$tmpdir/1.out" +cat > "$tmpdir/1.exp" < "$tmpdir/1.out" +cat > "$tmpdir/1.exp" < "$tmpdir/1.out" 2> /dev/null +> "$tmpdir/1.exp" +expect_pass 'wildcards: MANPATH: without wildcards: check missing man page' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +run $MAN -C "$tmpdir/manpath.config" \ + -aw manx > "$tmpdir/1.out" +cat > "$tmpdir/1.exp" < "$tmpdir/1.out" 2> /dev/null +> "$tmpdir/1.exp" +expect_pass 'wildcards: MANPATH: with wildcards: check missing man page' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +run $MAN -C "$tmpdir/manpath.config" \ + -aw manpathx > "$tmpdir/1.out" +cat > "$tmpdir/1.exp" < "$tmpdir/1.out" +cat > "$tmpdir/1.exp" < "$tmpdir/1.out" 2> /dev/null +> "$tmpdir/1.exp" +expect_pass 'wildcards: MANDATORY_MANPATH: without wildcards: check missing man page' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +run $MAN -C "$tmpdir/manpath.config" \ + -aw manx > "$tmpdir/1.out" +cat > "$tmpdir/1.exp" < "$tmpdir/1.out" 2> /dev/null +> "$tmpdir/1.exp" +expect_pass 'wildcards: MANDATORY_MANPATH: with wildcards: check missing man page' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +run $MAN -C "$tmpdir/manpath.config" \ + -aw manpathx > "$tmpdir/1.out" +cat > "$tmpdir/1.exp" < "$tmpdir/1.out" +cat > "$tmpdir/1.exp" < /dev/null +# $? is deliberately expanded here. +expect_pass 'missing locales' "test $? -eq 0" + +finish + diff --git a/tests/man-db/man-override-dir b/tests/man-db/man-override-dir new file mode 100755 index 0000000..4dc0331 --- /dev/null +++ b/tests/man-db/man-override-dir @@ -0,0 +1,46 @@ +#! /bin/sh + +# Testing override dir. This test covers both use cases - when override dir is +# enabled and when it's not. +# + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN=man} + +if [ -n "$OVERRIDE_DIR" ]; then + OVERRIDE=$OVERRIDE_DIR +else + OVERRIDE="override" +fi + +init +fake_config /usr/share/man +mkdir -p "${tmpdir}/usr/share/man/${OVERRIDE}/man1" +MANPATH="$tmpdir/usr/share/man" +export MANPATH + + +write_page abc 1 "${tmpdir}/usr/share/man/man1/abc.1" \ + UTF-8 '' '' 'abc \- top-level test page' +write_page abc 1 "${tmpdir}/usr/share/man/${OVERRIDE}/man1/abc.1" \ + UTF-8 '' '' 'abc \- modified test page' + +if [ -n "$OVERRIDE_DIR" ]; then +cat >"$tmpdir/1.exp" <"$tmpdir/1.exp" <"$tmpdir/1.out" +expect_pass 'testing override dir' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +finish diff --git a/tests/man-db/man-recode-in-place b/tests/man-db/man-recode-in-place new file mode 100755 index 0000000..bb75aa7 --- /dev/null +++ b/tests/man-db/man-recode-in-place @@ -0,0 +1,46 @@ +#! /bin/sh + +# Test man-recode's --in-place behaviour. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN_RECODE=man-recode} + +init + +cat >"$tmpdir/a.1.exp" <<'EOF' +.SH NAME +a \- á +EOF +cp "$tmpdir/a.1.exp" "$tmpdir/a.1" +cat >"$tmpdir/b.1.exp" <<'EOF' +'\" -*- coding: UTF-8 -*- +.SH NAME +b \- é +EOF +gzip -c <"$tmpdir/b.1.exp" >"$tmpdir/b.1.gz" +cat >"$tmpdir/c.1.exp" <<'EOF' +'\" -*- coding: UTF-8 +.SH NAME +b \- é +EOF +cat >"$tmpdir/c.1" <<'EOF' +'\" -*- coding: ISO-8859-1 +EOF +<"$tmpdir/c.1.exp" tail -n +2 | iconv -f UTF-8 -t ISO-8859-1 >>"$tmpdir/c.1" +gzip "$tmpdir/c.1" + +run $MAN_RECODE -t UTF-8 --in-place \ + "$tmpdir/a.1" "$tmpdir/b.1.gz" "$tmpdir/c.1.gz" +expect_pass '--in-place with no coding tag' \ + 'diff -u "$tmpdir/a.1.exp" "$tmpdir/a.1"' +expect_pass '--in-place with gzip and coding tag matching target encoding' \ + 'diff -u "$tmpdir/b.1.exp" "$tmpdir/b.1"' +expect_pass \ + '--in-place with gzip and coding tag not matching target encoding' \ + 'diff -u "$tmpdir/c.1.exp" "$tmpdir/c.1"' +expect_pass '--in-place removes compressed input files' \ + 'test ! -f "$tmpdir/b.1.gz" && test ! -f "$tmpdir/c.1.gz"' + +finish diff --git a/tests/man-db/man-recode-suffix b/tests/man-db/man-recode-suffix new file mode 100755 index 0000000..c00be13 --- /dev/null +++ b/tests/man-db/man-recode-suffix @@ -0,0 +1,43 @@ +#! /bin/sh + +# Test man-recode's --suffix behaviour. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN_RECODE=man-recode} + +init + +cat >"$tmpdir/a.1.exp" <<'EOF' +.SH NAME +a \- á +EOF +cp "$tmpdir/a.1.exp" "$tmpdir/a.1" +cat >"$tmpdir/b.1.exp" <<'EOF' +'\" -*- coding: UTF-8 -*- +.SH NAME +b \- é +EOF +gzip -c <"$tmpdir/b.1.exp" >"$tmpdir/b.1.gz" +cat >"$tmpdir/c.1.exp" <<'EOF' +'\" -*- coding: UTF-8 +.SH NAME +b \- é +EOF +cat >"$tmpdir/c.1" <<'EOF' +'\" -*- coding: ISO-8859-1 +EOF +<"$tmpdir/c.1.exp" tail -n +2 | iconv -f UTF-8 -t ISO-8859-1 >>"$tmpdir/c.1" +gzip "$tmpdir/c.1" + +run $MAN_RECODE -t UTF-8 --suffix .out \ + "$tmpdir/a.1" "$tmpdir/b.1.gz" "$tmpdir/c.1.gz" +expect_pass '--suffix with no coding tag' \ + 'diff -u "$tmpdir/a.1.exp" "$tmpdir/a.1.out"' +expect_pass '--suffix with gzip and coding tag matching target encoding' \ + 'diff -u "$tmpdir/b.1.exp" "$tmpdir/b.1.out"' +expect_pass '--suffix with gzip and coding tag not matching target encoding' \ + 'diff -u "$tmpdir/c.1.exp" "$tmpdir/c.1.out"' + +finish diff --git a/tests/man-db/man-so-links-same-section b/tests/man-db/man-so-links-same-section new file mode 100755 index 0000000..32eddaa --- /dev/null +++ b/tests/man-db/man-so-links-same-section @@ -0,0 +1,90 @@ +#! /bin/sh + +# Test for relative .so links between man pages in the same section (e.g. ".so bar.1"). +# https://bugzilla.redhat.com/show_bug.cgi?id=693458 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN=man} + +init +fake_config /usr/share/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH + +cat >"$tmpdir/fake-program" <>"$tmpdir/manpath.config" <"$tmpdir/usr/share/man/man1/test-fullso.1" +echo '.so test.1' >"$tmpdir/usr/share/man/man1/test-relso.1" + +write_page testb 1 "$tmpdir/usr/share/man/man1/testb.1.gz" \ + UTF-8 'gz' '' 'testb \- top-level test page' +echo '.so man1/testb.1' >"$tmpdir/usr/share/man/man1/test-fullsob.1" +echo '.so testb.1' >"$tmpdir/usr/share/man/man1/test-relsob.1" + +cat >"$tmpdir/1.exp" <<'EOF' +.TH test 1 +.SH NAME +test \- top-level test page +.SH DESCRIPTION +test +EOF + +cat >"$tmpdir/2.exp" <<'EOF' +.TH testb 1 +.SH NAME +testb \- top-level test page +.SH DESCRIPTION +test +EOF + +run $MAN -C "$tmpdir/manpath.config" test | \ + grep -v '^\.l[flt] ' >"$tmpdir/1.out" +expect_pass 'test(1) without .so link' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +run $MAN -C "$tmpdir/manpath.config" test-fullso | \ + grep -v '^\.l[flt] ' >"$tmpdir/2.out" +expect_pass 'test-fullso(1) .so link with section' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/2.out"' + +run $MAN -C "$tmpdir/manpath.config" test-relso | \ + grep -v '^\.l[flt] ' >"$tmpdir/3.out" +expect_pass 'test-relso(1) .so link without section' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/3.out"' + + +run $MAN -C "$tmpdir/manpath.config" testb | \ + grep -v '^\.l[flt] ' >"$tmpdir/4.out" +expect_pass 'testb(1) without .so link; gzipped' \ + 'diff -u "$tmpdir/2.exp" "$tmpdir/4.out"' + +run $MAN -C "$tmpdir/manpath.config" test-fullsob | \ + grep -v '^\.l[flt] ' >"$tmpdir/5.out" +expect_pass 'test-fullsob(1) .so link with section; gzipped' \ + 'diff -u "$tmpdir/2.exp" "$tmpdir/5.out"' + +run $MAN -C "$tmpdir/manpath.config" test-relsob | \ + grep -v '^\.l[flt] ' >"$tmpdir/6.out" +expect_pass 'test-relsob(1) .so link without section; gzipped' \ + 'diff -u "$tmpdir/2.exp" "$tmpdir/6.out"' + +finish diff --git a/tests/man-db/man-suffixed-extension b/tests/man-db/man-suffixed-extension new file mode 100755 index 0000000..100efff --- /dev/null +++ b/tests/man-db/man-suffixed-extension @@ -0,0 +1,53 @@ +#!/bin/sh + +# Test for: +# man chmod.2 => man 2 chmod +# man 'chmod(2)' => man 2 chmod +# man chmod.2p => man 2p chmod +# man 'chmod(2p)' => man 2p chmod + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN=man} + +init +fake_config /usr/share/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH + +page_name="chmod" + +write_page "$page_name" 1 "$tmpdir/usr/share/man/man1/${page_name}.1.gz" \ + UTF-8 gz '' "$page_name \- coreutils $page_name manual page" +write_page "$page_name" 2 "$tmpdir/usr/share/man/man2/${page_name}.2.gz" \ + UTF-8 gz '' "$page_name \- $page_name() syscall manual page" + +cat >"$tmpdir/2.exp" <"$tmpdir/2.out" +expect_pass '"man name.2" is the same as "man 2 name"' \ + 'diff -u "$tmpdir/2.exp" "$tmpdir/2.out"' +run $MAN -C "$tmpdir/manpath.config" -aw "$page_name(2)" >"$tmpdir/2.out" +expect_pass '"man '\''name(2)'\''" is the same as "man 2 name"' \ + 'diff -u "$tmpdir/2.exp" "$tmpdir/2.out"' + +( + cd "$tmpdir/usr/share/man/man2/" + mv "${page_name}.2.gz" "${page_name}.2p.gz" +) + +cat >"$tmpdir/2p.exp" <"$tmpdir/2p.out" +expect_pass '"man name.2p" is the same as "man 2p name"' \ + 'diff -u "$tmpdir/2p.exp" "$tmpdir/2p.out"' +run $MAN -C "$tmpdir/manpath.config" -aw "$page_name(2p)" >"$tmpdir/2p.out" +expect_pass '"man '\''name(2p)'\''" is the same as "man 2p name"' \ + 'diff -u "$tmpdir/2p.exp" "$tmpdir/2p.out"' + +finish diff --git a/tests/man-db/man-symlinks-with-matching-names b/tests/man-db/man-symlinks-with-matching-names new file mode 100755 index 0000000..ff264d6 --- /dev/null +++ b/tests/man-db/man-symlinks-with-matching-names @@ -0,0 +1,31 @@ +#! /bin/sh + +# Test for: +# https://bugs.debian.org/163347 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN=man} + +init +fake_config /usr/local/man /usr/share/man +MANPATH="$tmpdir/usr/local/man:$tmpdir/usr/share/man" +export MANPATH + +write_page md5sum 1 "$tmpdir/usr/share/man/man1/md5sum.1.gz" \ + UTF-8 gz '' 'md5sum \- Debian md5sum manual page' +write_page md5sum 1 "$tmpdir/usr/share/man/man1/md5sum.textutils.1.gz" \ + UTF-8 gz '' 'md5sum \- coreutils md5sum manual page' +mkdir -p "$tmpdir/usr/local/man/man1" +ln -s ../../../share/man/man1/md5sum.textutils.1.gz \ + "$tmpdir/usr/local/man/man1/md5sum.1.gz" +cat >"$tmpdir/1.exp" <"$tmpdir/1.out" +expect_pass 'symlinks with matching names win' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +finish diff --git a/tests/man-db/manconv-coding-tags b/tests/man-db/manconv-coding-tags new file mode 100755 index 0000000..455caf0 --- /dev/null +++ b/tests/man-db/manconv-coding-tags @@ -0,0 +1,61 @@ +#! /bin/sh + +# Test manconv's support for Emacs-style coding: tags. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANCONV=manconv} + +init + +cat >"$tmpdir/1.exp" <<'EOF' +'\" -*- coding: UTF-8 +á +EOF +cat >"$tmpdir/1.inp" <<'EOF' +'\" -*- coding: ISO-8859-1 +EOF +<"$tmpdir/1.exp" tail -n +2 | iconv -f UTF-8 -t ISO-8859-1 >>"$tmpdir/1.inp" +run $MANCONV -f UTF-8 -t UTF-8 <"$tmpdir/1.inp" >"$tmpdir/1.out" +expect_pass 'simple coding tag' 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +cat >"$tmpdir/2.exp" <<'EOF' +'\" -*- mode: troff; coding: UTF-8 -*- +á +EOF +cat >"$tmpdir/2.inp" <<'EOF' +'\" -*- mode: troff; coding: ISO-8859-1 -*- +EOF +<"$tmpdir/2.exp" tail -n +2 | iconv -f UTF-8 -t ISO-8859-1 >>"$tmpdir/2.inp" +run $MANCONV -f UTF-8 -t UTF-8 <"$tmpdir/2.inp" >"$tmpdir/2.out" +expect_pass 'mode and coding tags' 'diff -u "$tmpdir/2.exp" "$tmpdir/2.out"' + +cat >"$tmpdir/3.exp" <<'EOF' +'\" -*- mode: troff; coding: UTF-8 -*- +á +EOF +cat >"$tmpdir/3.inp" <<'EOF' +'\" -*- mode: troff; coding: ISO-LATIN-1 -*- +EOF +<"$tmpdir/3.exp" tail -n +2 | iconv -f UTF-8 -t ISO-8859-1 >>"$tmpdir/3.inp" +run $MANCONV -f UTF-8 -t UTF-8 <"$tmpdir/3.inp" >"$tmpdir/3.out" +expect_pass 'iso-latin-1 coding alias' 'diff -u "$tmpdir/3.exp" "$tmpdir/3.out"' + +cat >"$tmpdir/4.inp" <<'EOF' +'\" -*- nroff -*- +EOF +run $MANCONV -f UTF-8 -t UTF-8 <"$tmpdir/4.inp" >"$tmpdir/4.out" +expect_pass 'preprocessor comment but no coding tag' \ + 'diff -u "$tmpdir/4.inp" "$tmpdir/4.out"' + +cat >"$tmpdir/5.exp" <<'EOF' +'\" -*- coding: utf-8 +á +EOF +cp "$tmpdir/5.exp" "$tmpdir/5.inp" +run $MANCONV -f UTF-8 -t UTF-8 <"$tmpdir/5.inp" >"$tmpdir/5.out" +expect_pass 'coding tag matches target encoding' \ + 'diff -u "$tmpdir/5.inp" "$tmpdir/5.out"' + +finish diff --git a/tests/man-db/manconv-guess-from-encoding b/tests/man-db/manconv-guess-from-encoding new file mode 100755 index 0000000..15b206b --- /dev/null +++ b/tests/man-db/manconv-guess-from-encoding @@ -0,0 +1,38 @@ +#! /bin/sh + +# Test manconv's support for guessing the input encoding if it is not +# explicitly specified. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANCONV=manconv} + +init + +write_page coding-tag 7 \ + "$tmpdir/usr/share/man/man7/coding-tag.7" \ + ISO-8859-1 '' '' 'coding-tag \- é' +iconv -f ISO-8859-1 -t UTF-8 \ + <"$tmpdir/usr/share/man/man7/coding-tag.7" \ + >"$tmpdir/coding-tag.7.exp" +run $MANCONV -t UTF-8 "$tmpdir/usr/share/man/man7/coding-tag.7" \ + >"$tmpdir/coding-tag.7.out" +expect_pass 'recode from encoding guessed from directory name' \ + 'diff -u "$tmpdir/coding-tag.7.exp" "$tmpdir/coding-tag.7.out"' + +write_page lang-dir 7 \ + "$tmpdir/usr/share/man/fr_FR.ISO-8859-1/man7/lang-dir.7.gz" \ + ISO-8859-1 gz '-*- coding: ISO-8859-1 -*-' 'lang-dir \- é' +cat >"$tmpdir/lang-dir.7.exp" <<'EOF' +'\" -*- coding: UTF-8 -*- +EOF +zcat "$tmpdir/usr/share/man/fr_FR.ISO-8859-1/man7/lang-dir.7.gz" | \ + tail -n +2 | iconv -f ISO-8859-1 -t UTF-8 >>"$tmpdir/lang-dir.7.exp" +run $MANCONV -t UTF-8 \ + "$tmpdir/usr/share/man/fr_FR.ISO-8859-1/man7/lang-dir.7.gz" \ + >"$tmpdir/lang-dir.7.out" +expect_pass 'recode from encoding guessed from directory name' \ + 'diff -u "$tmpdir/lang-dir.7.exp" "$tmpdir/lang-dir.7.out"' + +finish diff --git a/tests/man-db/manconv-incomplete-char-at-eof b/tests/man-db/manconv-incomplete-char-at-eof new file mode 100755 index 0000000..3557657 --- /dev/null +++ b/tests/man-db/manconv-incomplete-char-at-eof @@ -0,0 +1,15 @@ +#! /bin/sh + +# Test manconv's handling of incomplete characters at end of file. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANCONV=manconv} + +init + +printf '\314' >"$tmpdir/1.inp" # 0xCC +expect_pass 'incomplete character at EOF' '! run $MANCONV -f EUC-JP -t UTF-8//IGNORE <"$tmpdir/1.inp" >/dev/null' + +finish diff --git a/tests/man-db/manconv-odd-combinations b/tests/man-db/manconv-odd-combinations new file mode 100755 index 0000000..63817a4 --- /dev/null +++ b/tests/man-db/manconv-odd-combinations @@ -0,0 +1,78 @@ +#! /bin/sh + +# Test manconv's handling of various odd encoding combinations. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANCONV=manconv} + +init + +(for x in $(seq 160 255); do + printf "\\$(printf %03o "$x")" +done +echo) >"$tmpdir/1.inp" + +iconv -f ISO-8859-1 -t UTF-8 <"$tmpdir/1.inp" >"$tmpdir/1.exp" +run $MANCONV -f UTF-8:ISO-8859-1 -t UTF-8 <"$tmpdir/1.inp" >"$tmpdir/1.out" +expect_pass '-f UTF-8:ISO-8859-1 -t UTF-8 on ISO-8859-1 input' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +iconv -f ISO-8859-2 -t UTF-8 <"$tmpdir/1.inp" >"$tmpdir/1-latin2.exp" +run $MANCONV -f UTF-8:ISO-8859-2 -t UTF-8 \ + <"$tmpdir/1.inp" >"$tmpdir/1-latin2.out" +expect_pass '-f UTF-8:ISO-8859-2 -t UTF-8 on ISO-8859-2 input' \ + 'diff -u "$tmpdir/1-latin2.exp" "$tmpdir/1-latin2.out"' + +(for x in $(seq 1 1000); do + printf '‐' +done +echo 'Б' | iconv -f UTF-8 -t KOI8-R +echo '‐') >"$tmpdir/2.inp" +iconv -f KOI8-R -t UTF-8 <"$tmpdir/2.inp" >"$tmpdir/2.exp" +run $MANCONV -f UTF-8:KOI8-R -t UTF-8 <"$tmpdir/2.inp" >"$tmpdir/2.out" +expect_pass '-f UTF-8:KOI8-R -t UTF-8 on KOI8-R input with UTF-8 prefix' \ + 'diff -u "$tmpdir/2.exp" "$tmpdir/2.out"' + +(for x in $(seq 160 255); do + printf "\\$(printf %03o "$x")" +done +echo) | iconv -f ISO-8859-1 -t UTF-8 >"$tmpdir/3.inp" +run $MANCONV -f UTF-8:ISO-8859-1 -t UTF-8 <"$tmpdir/3.inp" >"$tmpdir/3.out" +expect_pass '-f UTF-8:ISO-8859-1 -t UTF-8 preserves UTF-8 input' \ + 'diff -u "$tmpdir/3.inp" "$tmpdir/3.out"' + +# U+00B7 MIDDLE DOT is not representable in ISO-8859-2, and so should be +# omitted. However, manconv should still recognise that the input was UTF-8 +# rather than falling back to ISO-8859-2. +cat >"$tmpdir/4.inp" <<'EOF' +š·ł +EOF +iconv -f UTF-8 -t ISO-8859-2 >"$tmpdir/4.exp" <"$tmpdir/4.out" +expect_pass 'recognises input encoding and omits invalid output character' \ + 'diff -u "$tmpdir/4.exp" "$tmpdir/4.out"' + +# 0xAE does not exist in ISO-8859-7, so manconv won't be able to recode this +# to UTF-8 without conversion errors. (In the original case where this was +# seen in the wild, the coding: tag should actually have read ISO-8859-13.) +iconv -f UTF-8 -t ISO-8859-13 >"$tmpdir/5.inp" <<'EOF' +'\" -*- coding: ISO-8859-7 +REGISTERED SIGN: ® +trailing data +EOF +cat >"$tmpdir/5.exp" <<'EOF' +'\" -*- coding: UTF-8 +EOF +<"$tmpdir/5.inp" tail -n +2 | iconv -f ISO-8859-7 -t UTF-8//IGNORE \ + >>"$tmpdir/5.exp" 2>/dev/null +run $MANCONV -f UTF-8:ISO-8859-1 -t UTF-8//IGNORE \ + <"$tmpdir/5.inp" >"$tmpdir/5.out" +expect_pass 'copes with invalid input characters' \ + 'diff -u "$tmpdir/5.exp" "$tmpdir/5.out"' + +finish diff --git a/tests/man-db/mandb-basic b/tests/man-db/mandb-basic new file mode 100755 index 0000000..0037bb4 --- /dev/null +++ b/tests/man-db/mandb-basic @@ -0,0 +1,24 @@ +#! /bin/sh + +# Basic mandb tests. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANDB=mandb} +: ${ACCESSDB=accessdb} + +init +fake_config /usr/share/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH +db_ext="$(db_ext)" + +write_page test 1 "$tmpdir/usr/share/man/man1/test.1.gz" UTF-8 gz t \ + 'test \- simple mandb test' +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" +echo 'test -> "- 1 1 MTIME A - - gz simple mandb test"' >"$tmpdir/1.exp" +accessdb_filter "$tmpdir/usr/share/man/index$db_ext" >"$tmpdir/1.out" +expect_pass 'simple mandb test' 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +finish diff --git a/tests/man-db/mandb-bogus-symlink b/tests/man-db/mandb-bogus-symlink new file mode 100755 index 0000000..b0ec9aa --- /dev/null +++ b/tests/man-db/mandb-bogus-symlink @@ -0,0 +1,25 @@ +#! /bin/sh + +# Test for double free or corruption crash with bogus filename and symlink of man page. +# https://bugzilla.redhat.com/show_bug.cgi?id=702904 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANDB=mandb} + +init +fake_config /usr/share/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH + +mkdir -p "$tmpdir/usr/share/man/man8" +mkdir -p "$tmpdir/usr/lib/aa-bbb" +write_page test1 8 "$tmpdir/usr/lib/aa-bbb/aa-test1.8.gz" UTF-8 gz t \ + 'test1 \- testing man page' +ln -s "../../../lib/aa-bbb/aa-test1.8.gz" "$tmpdir/usr/share/man/man8/aa-test1.8.gz" +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" +# $? is deliberately expanded here. +expect_pass 'double free' "test $? -eq 0" + +finish diff --git a/tests/man-db/mandb-cachedir-tag b/tests/man-db/mandb-cachedir-tag new file mode 100755 index 0000000..657c8e0 --- /dev/null +++ b/tests/man-db/mandb-cachedir-tag @@ -0,0 +1,28 @@ +#! /bin/sh + +# Don't create CACHEDIR.TAG in manpath + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANDB=mandb} + +init +fake_config /usr/share/man +mkdir -p "$tmpdir/usr/share/man" +mkdir -p "$tmpdir/usr/dir/man" +mkdir -p "$tmpdir/var/cache/man" +echo "MANDATORY_MANPATH $abstmpdir/usr/share/man" > "$tmpdir/manpath.config" +echo "MANDATORY_MANPATH $abstmpdir/usr/dir/man" >> "$tmpdir/manpath.config" +echo "MANDB_MAP $abstmpdir/usr/share/man $abstmpdir/var/cache/man" >> "$tmpdir/manpath.config" + +write_page test 1 "$tmpdir/usr/share/man/man1/test.1" UTF-8 '' '' \ + 'test \- simple mandb test' +write_page test2 1 "$tmpdir/usr/dir/man/man1/test2.1" UTF-8 '' '' \ + 'test2 \- simple mandb test' +run $MANDB -C "$tmpdir/manpath.config" -q "$tmpdir/usr/share/man:$tmpdir/usr/dir/man" +expect_pass "CACHEDIR.TAG exists" "[ -e $tmpdir/var/cache/man/CACHEDIR.TAG ]" +expect_pass "CACHEDIR.TAG doesn't exist 01" "[ ! -e $tmpdir/usr/share/man/CACHEDIR.TAG ]" +expect_pass "CACHEDIR.TAG doesn't exist 02" "[ ! -e $tmpdir/usr/dir/man/CACHEDIR.TAG ]" + +finish diff --git a/tests/man-db/mandb-empty-page b/tests/man-db/mandb-empty-page new file mode 100755 index 0000000..88e6ad0 --- /dev/null +++ b/tests/man-db/mandb-empty-page @@ -0,0 +1,30 @@ +#! /bin/sh + +# Test handling of empty files. +# https://bugs.debian.org/622104 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANDB=mandb} + +init +fake_config /usr/share/man /usr/X11R6/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH +db_ext="$(db_ext)" + +mkdir -p "$tmpdir/usr/share/man/man1" +touch "$tmpdir/usr/share/man/man1/empty.1" +gzip -9 "$tmpdir/usr/share/man/man1/empty.1" +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" +# $? is deliberately expanded here. +expect_pass 'empty page' "test $? -eq 0" + +./fspause +ln -s empty.1.gz "$tmpdir/usr/share/man/man1/empty2.1.gz" +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" +# $? is deliberately expanded here. +expect_pass 'symlink to empty page' "test $? -eq 0" + +finish diff --git a/tests/man-db/mandb-regular-file-symlink-changes b/tests/man-db/mandb-regular-file-symlink-changes new file mode 100755 index 0000000..79b6676 --- /dev/null +++ b/tests/man-db/mandb-regular-file-symlink-changes @@ -0,0 +1,67 @@ +#! /bin/sh + +# What happens when a manual page changes from a regular file to a symbolic +# link and back? +# https://bugs.debian.org/490582 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANDB=mandb} +: ${ACCESSDB=accessdb} + +init +fake_config /usr/share/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH +db_ext="$(db_ext)" + +write_page fs 5 "$tmpdir/usr/share/man/man5/fs.5.gz" \ + UTF-8 gz t 'fs \- fs(5)' +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" +cat >"$tmpdir/1.exp" < "- 5 5 MTIME A - - gz fs(5)" +EOF +accessdb_filter "$tmpdir/usr/share/man/index$db_ext" >"$tmpdir/1.out" +expect_pass 'fs(5) setup' 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +./fspause +write_page filesystems 5 "$tmpdir/usr/share/man/man5/filesystems.5.gz" \ + UTF-8 gz t 'filesystems \- filesystems(5)' +ln -sf filesystems.5.gz "$tmpdir/usr/share/man/man5/fs.5.gz" +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" +cat >"$tmpdir/2.exp" < "- 5 5 MTIME A - - gz filesystems(5)" +fs -> "- 5 5 MTIME B - - gz filesystems(5)" +EOF +accessdb_filter "$tmpdir/usr/share/man/index$db_ext" >"$tmpdir/2.out" +expect_pass 'mandb notices regular file -> symlink' \ + 'diff -u "$tmpdir/2.exp" "$tmpdir/2.out"' + +./fspause +ln -sf fs.5.gz "$tmpdir/usr/share/man/man5/fs2.5.gz" +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" +cat >"$tmpdir/3.exp" < "- 5 5 MTIME A - - gz filesystems(5)" +fs -> "- 5 5 MTIME B - - gz filesystems(5)" +fs2 -> "- 5 5 MTIME B - - gz filesystems(5)" +EOF +accessdb_filter "$tmpdir/usr/share/man/index$db_ext" >"$tmpdir/3.out" +expect_pass 'mandb notices two-level symlink' \ + 'diff -u "$tmpdir/3.exp" "$tmpdir/3.out"' + +./fspause +rm -f "$tmpdir/usr/share/man/man5/fs.5.gz" +write_page fs 5 "$tmpdir/usr/share/man/man5/fs.5.gz" \ + UTF-8 gz t 'fs \- new fs(5)' +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" +cat >"$tmpdir/4.exp" < "- 5 5 MTIME A - - gz filesystems(5)" +fs -> "- 5 5 MTIME A - - gz new fs(5)" +fs2 -> "- 5 5 MTIME B - - gz filesystems(5)" +EOF +accessdb_filter "$tmpdir/usr/share/man/index$db_ext" >"$tmpdir/4.out" +expect_pass 'mandb notices symlink -> regular file' \ + 'diff -u "$tmpdir/4.exp" "$tmpdir/4.out"' + +finish diff --git a/tests/man-db/mandb-symlink-beats-whatis-ref b/tests/man-db/mandb-symlink-beats-whatis-ref new file mode 100755 index 0000000..379bbe0 --- /dev/null +++ b/tests/man-db/mandb-symlink-beats-whatis-ref @@ -0,0 +1,60 @@ +#! /bin/sh + +# Test for: +# https://bugs.debian.org/204249 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANDB=mandb} +: ${ACCESSDB=accessdb} + +init +fake_config /usr/share/man /usr/X11R6/man +MANPATH="$tmpdir/usr/share/man:$tmpdir/usr/X11R6/man" +export MANPATH +db_ext="$(db_ext)" + +write_page xterm 1x "$tmpdir/usr/X11R6/man/man1/xterm.1x.gz" \ + UTF-8 gz '' 'xterm \- terminal emulator for X' +mkdir -p "$tmpdir/usr/share/man/man1" +ln -s ../../../X11R6/man/man1/xterm.1x.gz \ + "$tmpdir/usr/share/man/man1/x-terminal-emulator.1.gz" +run $MANDB -C "$tmpdir/manpath.config" -u -q \ + "$tmpdir/usr/share/man:$tmpdir/usr/X11R6/man" +cat >"$tmpdir/1-share.exp" < "- 1 1 MTIME B - - gz terminal emulator for X" +EOF +cat >"$tmpdir/1-X11R6.exp" < "- 1x 1 MTIME A - - gz terminal emulator for X" +EOF +accessdb_filter "$tmpdir/usr/share/man/index$db_ext" >"$tmpdir/1-share.out" +accessdb_filter "$tmpdir/usr/X11R6/man/index$db_ext" >"$tmpdir/1-X11R6.out" +expect_pass '/usr/share/man x-terminal-emulator -> xterm' \ + 'diff -u "$tmpdir/1-share.exp" "$tmpdir/1-share.out"' +expect_pass '/usr/X11R6/man x-terminal-emulator -> xterm' \ + 'diff -u "$tmpdir/1-X11R6.exp" "$tmpdir/1-X11R6.out"' + +./fspause +write_page uxterm 1x "$tmpdir/usr/X11R6/man/man1/uxterm.1x.gz" \ + UTF-8 gz '' \ + 'uxterm \- X terminal emulator for Unicode (UTF-8) environments' +ln -sf ../../../X11R6/man/man1/uxterm.1x.gz \ + "$tmpdir/usr/share/man/man1/x-terminal-emulator.1.gz" +run $MANDB -C "$tmpdir/manpath.config" -u -q \ + "$tmpdir/usr/share/man:$tmpdir/usr/X11R6/man" +cat >"$tmpdir/2-share.exp" < "- 1 1 MTIME B - - gz X terminal emulator for Unicode (UTF-8) environments" +EOF +cat >"$tmpdir/2-X11R6.exp" < "- 1x 1 MTIME A - - gz X terminal emulator for Unicode (UTF-8) environments" +xterm -> "- 1x 1 MTIME A - - gz terminal emulator for X" +EOF +accessdb_filter "$tmpdir/usr/share/man/index$db_ext" >"$tmpdir/2-share.out" +accessdb_filter "$tmpdir/usr/X11R6/man/index$db_ext" >"$tmpdir/2-X11R6.out" +expect_pass '/usr/share/man x-terminal-emulator -> uxterm' \ + 'diff -u "$tmpdir/2-share.exp" "$tmpdir/2-share.out"' +expect_pass '/usr/X11R6/man x-terminal-emulator -> uxterm' \ + 'diff -u "$tmpdir/2-X11R6.exp" "$tmpdir/2-X11R6.out"' + +finish diff --git a/tests/man-db/mandb-whatis-broken-link-changes b/tests/man-db/mandb-whatis-broken-link-changes new file mode 100755 index 0000000..23d2309 --- /dev/null +++ b/tests/man-db/mandb-whatis-broken-link-changes @@ -0,0 +1,55 @@ +#! /bin/sh + +# Ensure that we don't repeatedly rescan when a whatis entry turns into a +# broken link. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANDB=mandb} +: ${ACCESSDB=accessdb} + +init +fake_config /usr/share/man +MANPATH="$tmpdir/usr/share/man" +export MANPATH +db_ext="$(db_ext)" + +NL=' +' + +write_page test 1 "$tmpdir/usr/share/man/man1/test.1.gz" UTF-8 gz t \ + "test \- test page${NL}.br${NL}testlink \- link to test page" +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" +cat >"$tmpdir/1.exp" < "- 1 1 MTIME A - - gz test page" +testlink -> "- 1 1 MTIME C test - gz " +EOF +accessdb_filter "$tmpdir/usr/share/man/index$db_ext" >"$tmpdir/1.out" +expect_pass 'setup' 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +./fspause +echo '.so nonexistent.1' | gzip -9c >"$tmpdir/usr/share/man/man1/testlink.1.gz" +run $MANDB -C "$tmpdir/manpath.config" -u -q "$tmpdir/usr/share/man" +cat >"$tmpdir/2.exp" < "- 1 1 MTIME A - - gz test page" +testlink -> "- 1 1 MTIME C test - gz " +EOF +accessdb_filter "$tmpdir/usr/share/man/index$db_ext" >"$tmpdir/2.out" +expect_pass 'broken whatis' 'diff -u "$tmpdir/2.exp" "$tmpdir/2.out"' + +./fspause +LC_ALL=C run $MANDB -C "$tmpdir/manpath.config" -u \ + "$tmpdir/usr/share/man" >"$tmpdir/3.out" 2>/dev/null +cat >"$tmpdir/3.exp" <"$tmpdir/manpath.config" +} + +db_ext () { + case $DBTYPE in + gdbm) echo .db ;; + btree) echo .bt ;; + esac +} + +# Arguments: name section path encoding compression_extension preprocessor_line name_line +write_page () { + mkdir -p "${3%/*}" + >"$3.tmp1" + if [ "$6" ]; then + echo "'\\\" $6" >>"$3.tmp1" + fi + cat >>"$3.tmp1" <"$3.tmp2" + case $5 in + '') cat ;; + gz|z) gzip -9c ;; + Z) compress -c ;; + bz2) bzip2 -9c ;; + lzma) lzma -9c ;; + esac <"$3.tmp2" >"$3" + rm -f "$3.tmp1" "$3.tmp2" +} + +accessdb_filter () { + # e.g. 'test -> "- 1 1 1250702063 A - - gz simple mandb test"' + run $ACCESSDB "$1" | grep -v '^\$' | \ + sed 's/\(-> "[^ ][^ ]* [^ ][^ ]* [^ ][^ ]* \)[^ ][^ ]* [^ ][^ ]* /\1MTIME /' +} + +expect_pass () { + ret=0 + eval "$2" || ret=$? + if [ "$ret" = 0 ]; then + echo " PASS: $1" + else + failures="$(($failures + 1))" + echo " FAIL: $1" + fi +} + +skip () { + echo " SKIP: $1" + rm -rf "$abstmpdir" + exit 77 +} + +finish () { + case $failures in + 0) + rm -rf "$abstmpdir" + exit 0 + ;; + *) + if [ -z "$TEST_FAILURE_KEEP" ]; then + rm -rf "$abstmpdir" + fi + exit 1 + ;; + esac +} diff --git a/tests/man-db/whatis-path-to-executable b/tests/man-db/whatis-path-to-executable new file mode 100755 index 0000000..07b18a5 --- /dev/null +++ b/tests/man-db/whatis-path-to-executable @@ -0,0 +1,56 @@ +#! /bin/sh + +# Test that whatis behaves appropriately when given a path to an executable. + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MANDB=mandb} +: ${WHATIS=whatis} + +init +fake_config /usr/share/man /usr/local/man +cat >>"$tmpdir/manpath.config" <"$tmpdir/1.exp" <"$tmpdir/1.out" +expect_pass 'simple name returns all matches' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +cat >"$tmpdir/2.exp" <"$tmpdir/2.out" +expect_pass '/usr/bin/test only returns appropriate match' \ + 'diff -u "$tmpdir/2.exp" "$tmpdir/2.out"' + +cat >"$tmpdir/3.exp" <"$tmpdir/3.out" +expect_pass '/usr/local/bin/test only returns appropriate match' \ + 'diff -u "$tmpdir/3.exp" "$tmpdir/3.out"' + +finish diff --git a/tests/man-db/zsoelim-so-includes b/tests/man-db/zsoelim-so-includes new file mode 100755 index 0000000..311bf16 --- /dev/null +++ b/tests/man-db/zsoelim-so-includes @@ -0,0 +1,61 @@ +#! /bin/sh + +# Test for: +# https://bugs.debian.org/503472 + +: ${srcdir=.} +. "$srcdir/testlib.sh" + +: ${MAN=man} + +init +fake_config /usr/local/man /usr/share/man +MANPATH="$tmpdir/usr/local/man:$tmpdir/usr/share/man" +export MANPATH + +cat >"$tmpdir/fake-program" <>"$tmpdir/manpath.config" <>"$tmpdir/usr/share/man/man1/test.1" +write_page test2 7 "$tmpdir/usr/local/man/man7/test2.7" \ + UTF-8 '' '' 'test2 \- second-level local test page' +echo '.so test3.1' >>"$tmpdir/usr/local/man/man7/test2.7" +write_page test3 1 "$tmpdir/usr/local/man/man1/test3.1" \ + UTF-8 '' '' 'test3 \- third-level local test page' +write_page test3 1 "$tmpdir/usr/share/man/man1/test3.1" \ + UTF-8 '' '' 'test3 \- third-level test page' +cat >"$tmpdir/1.exp" <<'EOF' +.TH test 1 +.SH NAME +test \- top-level test page +.SH DESCRIPTION +test +.TH test2 7 +.SH NAME +test2 \- second-level local test page +.SH DESCRIPTION +test +.TH test3 1 +.SH NAME +test3 \- third-level test page +.SH DESCRIPTION +test +EOF +run $MAN -C "$tmpdir/manpath.config" test | \ + grep -v '^\.l[flt] ' >"$tmpdir/1.out" +expect_pass 'test(1) expanded correctly' \ + 'diff -u "$tmpdir/1.exp" "$tmpdir/1.out"' + +finish diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..5c2d8a3 --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,13 @@ +- hosts: localhost + roles: + - role: standard-test-beakerlib + tags: + - atomic + - classic + - container + tests: + - upstream-test-suite + required_packages: + - man-db + - gcc + - make diff --git a/tests/upstream-test-suite b/tests/upstream-test-suite new file mode 100755 index 0000000..d7f4f09 --- /dev/null +++ b/tests/upstream-test-suite @@ -0,0 +1,27 @@ +#!/bin/bash + +. /usr/share/beakerlib/beakerlib.sh + +TEST="/BaseOS/man-db/Sanity/upstream-test-suite" + +PACKAGES=${PACKAGES:-"man-db"} +REQUIRES=${REQUIRES:-"gcc make"} + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm --all + rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory" + rlRun "cp -r man-db/* $TmpDir/." 0 "Copying test suite" + rlRun "pushd $TmpDir" + rlPhaseEnd + + rlPhaseStartTest + rlRun "make test" 0 "Running tests" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "popd" + rlRun "rm -r $TmpDir" 0 "Removing tmp directory" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd