summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Voelker <mail@bernhard-voelker.de>2017-10-22 20:50:50 +0200
committerBernhard Voelker <mail@bernhard-voelker.de>2017-10-22 20:50:50 +0200
commitef1581ea51cc200962f07c613c49f96d283b6d6a (patch)
tree23ac2b8a15ab5242980fd7b69bef5f887e46e38d
parent77e4a7f17fa387c336b44f05c5f0056cfc47ad22 (diff)
downloadfindutils-ef1581ea51.tar.gz
find: avoid segfault with -D without argument
On some platforms, 'find -D' without any further argument crashed. * find/util.c (process_leading_options): Output an error diagnostic when the -D option is the last argument. Previously, 'find -D' without any further arguments crashed on some platforms where the following strtok_r does not expect a NULL pointer argument in the first call. * NEWS (Bug Fixes): Mention the fix. * find/testsuite/sv-52220.sh: Add a test. * find/testsuite/Makefile.am (test_shell_progs): Reference the test. Fixes https://savannah.gnu.org/bugs/?52220
-rw-r--r--NEWS3
-rw-r--r--find/testsuite/Makefile.am3
-rwxr-xr-xfind/testsuite/sv-52220.sh61
-rw-r--r--find/util.c5
4 files changed, 71 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 29aef53..7ad898c 100644
--- a/NEWS
+++ b/NEWS
@@ -52,6 +52,9 @@ Some minor documentation improvements are listed in "Bug Fixes" below.
** Bug Fixes
+#52220: 'find -D' without any further argument no longer crashes.
+ Bug present since the implementation of -D in FINDUTILS_4_3_1-1.
+
#51304: doc: use correct IEC unit prefixes in the documentation of 'find -size'.
find(1) uses binary-based units for the suffixes 'k', 'M', and 'G' of
the argument of the '-size' option: 1024, 1024*1024 and 1024^3.
diff --git a/find/testsuite/Makefile.am b/find/testsuite/Makefile.am
index 0fcd842..39e939f 100644
--- a/find/testsuite/Makefile.am
+++ b/find/testsuite/Makefile.am
@@ -261,7 +261,8 @@ test_type-list.sh \
sv-34079.sh \
sv-34976-execdir-fd-leak.sh \
sv-48030-exec-plus-bug.sh \
-sv-48180-refuse-noop.sh
+sv-48180-refuse-noop.sh \
+sv-52220.sh
EXTRA_DIST = $(EXTRA_DIST_EXP) $(EXTRA_DIST_XO) $(EXTRA_DIST_GOLDEN) \
$(test_shell_progs) binary_locations.sh checklists.py
diff --git a/find/testsuite/sv-52220.sh b/find/testsuite/sv-52220.sh
new file mode 100755
index 0000000..75d1691
--- /dev/null
+++ b/find/testsuite/sv-52220.sh
@@ -0,0 +1,61 @@
+#! /bin/sh
+# Copyright (C) 2017 Free Software Foundation, Inc.
+#
+# This program 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.
+#
+# This program 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/>.
+#
+#
+# Verify that 'find -D' without further argument outputs an error diagnostic.
+# Between FINDUTILS_4_3_1-1 and 4.6, find crashed on some platforms.
+
+testname="$(basename $0)"
+
+. "${srcdir}"/binary_locations.sh
+
+die() {
+ echo "$@" >&2
+ exit 1
+}
+
+# This is used to simplify checking of the return value
+# which is useful when ensuring a command fails as desired.
+# I.e., just doing `command ... &&fail=1` will not catch
+# a segfault in command for example. With this helper you
+# instead check an explicit exit code like
+# returns_ 1 command ... || fail
+returns_ () {
+ # Disable tracing so it doesn't interfere with stderr of the wrapped command
+ { set +x; } 2>/dev/null
+
+ local exp_exit="$1"
+ shift
+ "$@"
+ test $? -eq $exp_exit && ret_=0 || ret_=1
+
+ set -x
+ { return $ret_; } 2>/dev/null
+}
+
+set -x
+
+fail=0
+# Exercise both find executables.
+for exe in "${ftsfind}" "${oldfind}"; do
+ e="$(basename "$exe")"
+ err="${e}${opt}.err"
+ returns_ 1 "$exe" -D >/dev/null 2> "$err" || fail=1
+ grep -F "find: Missing argument after the -D option." "$err" \
+ || { cat "$err"; fail=1; }
+done
+
+exit $fail
diff --git a/find/util.c b/find/util.c
index 2d97a8c..187b284 100644
--- a/find/util.c
+++ b/find/util.c
@@ -970,6 +970,11 @@ process_leading_options (int argc, char *argv[])
}
else if (0 == strcmp ("-D", argv[i]))
{
+ if (argc <= i+1)
+ {
+ error (0, 0, _("Missing argument after the -D option."));
+ usage (EXIT_FAILURE);
+ }
process_debug_options (argv[i+1]);
++i; /* skip the argument too. */
}