]> git.pld-linux.org Git - packages/findutils.git/blob - findutils-4.6.0-exec-args.patch
- enhanced info and pl.po-update patches
[packages/findutils.git] / findutils-4.6.0-exec-args.patch
1 From 443166adaf1c8b91e16a716f3b13f47493b895cc Mon Sep 17 00:00:00 2001
2 From: Bernhard Voelker <mail@bernhard-voelker.de>
3 Date: Tue, 31 May 2016 10:38:52 +0200
4 Subject: [PATCH] Fix bug #48030: find: -exec + does not pass all arguments in
5  certain cases
6
7 When the -exec arguments buffer (usually 128k) is full and the given
8 command has been executed with all that arguments, find(1) missed to
9 execute the command yet another time if only 1 another file would have
10 to be processed.
11 Both find(1), i.e., nowadays FTS-version, and oldfind are affected.
12 This bug was present since the implementation of '-exec +' in 2005,
13 see commit FINDUTILS_4_2_11-1-25-gf0a6ac6.
14
15 * lib/buildcmd.c (bc_push_arg): Move the assignment to set 'state->todo'
16 to 1 down after the immediate execution which resets that flag.
17 * find/testsuite/sv-48030-exec-plus-bug.sh: Add a test.
18 * find/testsuite/Makefile.am (test_shell_progs): Reference the test.
19 * NEWS (Bug Fixes): Mention the fix.
20
21 Reported by Joe Philip Ninan <indiajoe@gmail.com> in
22 https://savannah.gnu.org/bugs/?48030
23
24 Upstream-commit: 8cdc9767e305c9566f537af9d1acf71d1bc6ee8e
25 Signed-off-by: Kamil Dudka <kdudka@redhat.com>
26 ---
27  find/testsuite/Makefile.am               |   3 +-
28  find/testsuite/sv-48030-exec-plus-bug.sh | 143 +++++++++++++++++++++++++++++++
29  lib/buildcmd.c                           |  10 +--
30  3 files changed, 150 insertions(+), 6 deletions(-)
31  create mode 100644 find/testsuite/sv-48030-exec-plus-bug.sh
32
33 diff --git a/find/testsuite/Makefile.am b/find/testsuite/Makefile.am
34 index c1369c3..ab5dbe8 100644
35 --- a/find/testsuite/Makefile.am
36 +++ b/find/testsuite/Makefile.am
37 @@ -258,7 +258,8 @@ test_escapechars.sh \
38  test_escape_c.sh \
39  test_inode.sh \
40  sv-34079.sh \
41 -sv-34976-execdir-fd-leak.sh
42 +sv-34976-execdir-fd-leak.sh \
43 +sv-48030-exec-plus-bug.sh
44  
45  EXTRA_DIST = $(EXTRA_DIST_EXP) $(EXTRA_DIST_XO) $(EXTRA_DIST_GOLDEN) \
46         $(test_shell_progs) binary_locations.sh checklists.py
47 diff --git a/find/testsuite/sv-48030-exec-plus-bug.sh b/find/testsuite/sv-48030-exec-plus-bug.sh
48 new file mode 100644
49 index 0000000..4dbf149
50 --- /dev/null
51 +++ b/find/testsuite/sv-48030-exec-plus-bug.sh
52 @@ -0,0 +1,143 @@
53 +#! /bin/sh
54 +# Copyright (C) 2016 Free Software Foundation, Inc.
55 +#
56 +# This program is free software: you can redistribute it and/or modify
57 +# it under the terms of the GNU General Public License as published by
58 +# the Free Software Foundation, either version 3 of the License, or
59 +# (at your option) any later version.
60 +#
61 +# This program is distributed in the hope that it will be useful,
62 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
63 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
64 +# GNU General Public License for more details.
65 +#
66 +# You should have received a copy of the GNU General Public License
67 +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
68 +#
69 +
70 +# This test verifies that find invokes the given command for the
71 +# multiple-argument sytax '-exec CMD {} +'.  Between FINDUTILS-4.2.12
72 +# and v4.6.0, find(1) would have failed to execute CMD another time
73 +# if there was only one last single file argument.
74 +
75 +testname="$(basename $0)"
76 +
77 +. "${srcdir}"/binary_locations.sh
78 +
79 +die() {
80 +  echo "$@" >&2
81 +  exit 1
82 +}
83 +
84 +# This is used to simplify checking of the return value
85 +# which is useful when ensuring a command fails as desired.
86 +# I.e., just doing `command ... &&fail=1` will not catch
87 +# a segfault in command for example.  With this helper you
88 +# instead check an explicit exit code like
89 +#   returns_ 1 command ... || fail
90 +returns_ () {
91 +  # Disable tracing so it doesn't interfere with stderr of the wrapped command
92 +  { set +x; } 2>/dev/null
93 +
94 +  local exp_exit="$1"
95 +  shift
96 +  "$@"
97 +  test $? -eq $exp_exit && ret_=0 || ret_=1
98 +
99 +  set -x
100 +  { return $ret_; } 2>/dev/null
101 +}
102 +
103 +# Define the nicest compare available (borrowed from gnulib).
104 +if diff_out_=`exec 2>/dev/null; diff -u "$0" "$0" < /dev/null` \
105 +   && diff -u Makefile "$0" 2>/dev/null | grep '^[+]#!' >/dev/null; then
106 +  # diff accepts the -u option and does not (like AIX 7 'diff') produce an
107 +  # extra space on column 1 of every content line.
108 +  if test -z "$diff_out_"; then
109 +    compare () { diff -u "$@"; }
110 +  else
111 +    compare ()
112 +    {
113 +      if diff -u "$@" > diff.out; then
114 +        # No differences were found, but Solaris 'diff' produces output
115 +        # "No differences encountered". Hide this output.
116 +        rm -f diff.out
117 +        true
118 +      else
119 +        cat diff.out
120 +        rm -f diff.out
121 +        false
122 +      fi
123 +    }
124 +  fi
125 +elif diff_out_=`exec 2>/dev/null; diff -c "$0" "$0" < /dev/null`; then
126 +  if test -z "$diff_out_"; then
127 +    compare () { diff -c "$@"; }
128 +  else
129 +    compare ()
130 +    {
131 +      if diff -c "$@" > diff.out; then
132 +        # No differences were found, but AIX and HP-UX 'diff' produce output
133 +        # "No differences encountered" or "There are no differences between the
134 +        # files.". Hide this output.
135 +        rm -f diff.out
136 +        true
137 +      else
138 +        cat diff.out
139 +        rm -f diff.out
140 +        false
141 +      fi
142 +    }
143 +  fi
144 +elif cmp -s /dev/null /dev/null 2>/dev/null; then
145 +  compare () { cmp -s "$@"; }
146 +else
147 +  compare () { cmp "$@"; }
148 +fi
149 +
150 +DIR='RashuBug'
151 +# Name of the CMD to execute: the file name must be 6 characters long
152 +# (to trigger the bug in combination with the test files).
153 +CMD='tstcmd'
154 +
155 +# Create test files.
156 +make_test_data() {
157 +  # Create the CMD script and check that it works.
158 +  mkdir "$DIR" 'bin' \
159 +    && echo 'printf "%s\n" "$@"' > "bin/$CMD" \
160 +    && chmod +x "bin/$CMD" \
161 +    && PATH="$PWD/bin:$PATH" \
162 +    && [ $( "${ftsfind}" bin -maxdepth 0 -exec "$CMD" '{}' + ) = 'bin' ] \
163 +    || return 1
164 +
165 +  # Create expected output file - also used for creating the test data.
166 +  { seq -f "${DIR}/abcdefghijklmnopqrstuv%04g" 901 &&
167 +    seq -f "${DIR}/abcdefghijklmnopqrstu%04g" 902 3719
168 +  } > exp2 \
169 +    && LC_ALL=C sort exp2 > exp \
170 +    && rm exp2 \
171 +    || return 1
172 +
173 +  # Create test files, and check if test data has been created correctly.
174 +  xargs touch < exp \
175 +    && [ -f "${DIR}/abcdefghijklmnopqrstu3719" ] \
176 +    && [ 3719 = $( "${ftsfind}" "$DIR" -type f | wc -l ) ] \
177 +    || return 1
178 +}
179 +
180 +set -x
181 +tmpdir="$(mktemp -d)" \
182 +  && cd "$tmpdir" \
183 +  && make_test_data "${tmpdir}" \
184 +  || die "FAIL: failed to set up the test in ${tmpdir}"
185 +
186 +fail=0
187 +for exe in "${ftsfind}" "${oldfind}"; do
188 +  "$exe" "$DIR" -type f -exec "$CMD" '{}' + > out || fail=1
189 +  LC_ALL=C sort out > out2 || fail=1
190 +  compare exp out2 || fail=1
191 +done
192 +
193 +cd ..
194 +rm -rf "${tmpdir}" || exit 1
195 +exit $fail
196 diff --git a/lib/buildcmd.c b/lib/buildcmd.c
197 index a58f67e..27e9ce5 100644
198 --- a/lib/buildcmd.c
199 +++ b/lib/buildcmd.c
200 @@ -356,11 +356,6 @@ bc_push_arg (struct buildcmd_control *ctl,
201  
202    assert (arg != NULL);
203  
204 -  if (!initial_args)
205 -    {
206 -      state->todo = 1;
207 -    }
208 -
209    if (!terminate)
210      {
211        if (state->cmd_argv_chars + len + pfxlen > ctl->arg_max)
212 @@ -380,6 +375,11 @@ bc_push_arg (struct buildcmd_control *ctl,
213              bc_do_exec (ctl, state);
214      }
215  
216 +  if (!initial_args)
217 +    {
218 +      state->todo = 1;
219 +    }
220 +
221    if (state->cmd_argc >= state->cmd_argv_alloc)
222      {
223        /* XXX: we could use extendbuf() here. */
224 -- 
225 2.5.5
226
This page took 0.29687 seconds and 3 git commands to generate.