When using instance [COUNT], the instance check is wrong. instance-- == 0 should be --instance == 0.
Add a testcase run-ar-N.sh that uses -N COUNT with extract and delete operations checking the right instance was extracted and deleted. https://sourceware.org/bugzilla/show_bug.cgi?id=28725 Reported-by: panxiaohe <panxh_...@163.com> Signed-off-by: Mark Wielaard <m...@klomp.org> --- src/ChangeLog | 6 +++++ src/ar.c | 4 +-- tests/ChangeLog | 6 +++++ tests/Makefile.am | 2 ++ tests/run-ar-N.sh | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 2 deletions(-) create mode 100755 tests/run-ar-N.sh diff --git a/src/ChangeLog b/src/ChangeLog index 88db4051..9348c562 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2022-08-28 Mark Wielaard <m...@klomp.org> + + * ar.c (do_oper_extract): Predecrement instance before compare + to zero. + (do_oper_delete): Likewise. + 2022-08-10 Andreas Schwab <sch...@suse.de> * readelf.c (print_attributes): Also handle SHT_RISCV_ATTRIBUTES. diff --git a/src/ar.c b/src/ar.c index 9e8df120..04456c18 100644 --- a/src/ar.c +++ b/src/ar.c @@ -518,7 +518,7 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, ENTRY entry; entry.key = arhdr->ar_name; ENTRY *res = hsearch (entry, FIND); - if (res != NULL && (instance < 0 || instance-- == 0) + if (res != NULL && (instance < 0 || --instance == 0) && !found[(char **) res->data - argv]) found[(char **) res->data - argv] = do_extract = true; } @@ -952,7 +952,7 @@ do_oper_delete (const char *arfname, char **argv, int argc, ENTRY entry; entry.key = arhdr->ar_name; ENTRY *res = hsearch (entry, FIND); - if (res != NULL && (instance < 0 || instance-- == 0) + if (res != NULL && (instance < 0 || --instance == 0) && !found[(char **) res->data - argv]) found[(char **) res->data - argv] = do_delete = true; } diff --git a/tests/ChangeLog b/tests/ChangeLog index d2952cc9..48bb28d1 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2022-08-26 Mark Wielaard <m...@klomp.org> + + * run-ar-N.sh: New test. + * Makefile.am (TESTS): Add run-ar-N.sh. + (EXTRA_DIST): Likewise. + 2022-08-04 Sergei Trofimovich <sly...@gmail.com> * low_high_pc.c (handle_die): Drop redundant 'lx' suffix. diff --git a/tests/Makefile.am b/tests/Makefile.am index 87988fb9..85514898 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -100,6 +100,7 @@ test-nlist$(EXEEXT): test-nlist.c $(test_nlist_CFLAGS) $(GCOV_FLAGS) -o $@ $< $(test_nlist_LDADD) TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ + run-ar-N.sh \ update1 update2 update3 update4 \ run-show-die-info.sh run-get-files.sh run-get-lines.sh \ run-next-files.sh run-next-lines.sh \ @@ -254,6 +255,7 @@ endif endif EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ + run-ar-N.sh \ run-show-die-info.sh run-get-files.sh run-get-lines.sh \ run-next-files.sh run-next-lines.sh testfile-only-debug-line.bz2 \ run-get-pubnames.sh run-get-aranges.sh \ diff --git a/tests/run-ar-N.sh b/tests/run-ar-N.sh new file mode 100755 index 00000000..de8f62b3 --- /dev/null +++ b/tests/run-ar-N.sh @@ -0,0 +1,65 @@ +#! /usr/bin/env bash +# Copyright (C) 2022 Mark J. Wielaard <m...@klomp.org> +# This file is part of elfutils. +# +# This file 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. +# +# elfutils 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/>. + +. $srcdir/test-subr.sh + +tempfiles testfile test.ar + +echo create test.ar with 3 testfile +echo 1 > testfile +testrun ${abs_top_builddir}/src/ar -vr test.ar testfile +echo 2 > testfile +testrun ${abs_top_builddir}/src/ar -vq test.ar testfile +testrun ${abs_top_builddir}/src/ar -t test.ar +echo 3 > testfile +testrun ${abs_top_builddir}/src/ar -vq test.ar testfile +testrun_compare ${abs_top_builddir}/src/ar -t test.ar << EOF +testfile +testfile +testfile +EOF + +echo list content of testfile 1 2 3 +testrun ${abs_top_builddir}/src/ar -vx -N 1 test.ar testfile +diff -u testfile - << EOF +1 +EOF +testrun ${abs_top_builddir}/src/ar -vx -N 2 test.ar testfile +diff -u testfile - << EOF +2 +EOF +testrun ${abs_top_builddir}/src/ar -vx -N 3 test.ar testfile +diff -u testfile - << EOF +3 +EOF + +echo delete testfile 2 +testrun ${abs_top_builddir}/src/ar -vd -N 2 test.ar testfile +testrun_compare ${abs_top_builddir}/src/ar -t test.ar << EOF +testfile +testfile +EOF +testrun ${abs_top_builddir}/src/ar -vx -N 1 test.ar testfile +diff -u testfile - << EOF +1 +EOF +testrun ${abs_top_builddir}/src/ar -vx -N 2 test.ar testfile +diff -u testfile - << EOF +3 +EOF + +exit 0 -- 2.30.2