From unknown Wed Jun 18 00:15:11 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#37859 <37859@debbugs.gnu.org> To: bug#37859 <37859@debbugs.gnu.org> Subject: Status: [PATCH] shuf: fix bug with =?UTF-8?Q?=E2=80=98-r?= -n =?UTF-8?Q?0=E2=80=99?= Reply-To: bug#37859 <37859@debbugs.gnu.org> Date: Wed, 18 Jun 2025 07:15:11 +0000 retitle 37859 [PATCH] shuf: fix bug with =E2=80=98-r -n 0=E2=80=99 reassign 37859 coreutils submitter 37859 Paul Eggert severity 37859 normal tag 37859 patch thanks From debbugs-submit-bounces@debbugs.gnu.org Mon Oct 21 16:21:25 2019 Received: (at submit) by debbugs.gnu.org; 21 Oct 2019 20:21:25 +0000 Received: from localhost ([127.0.0.1]:57899 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMeBA-0006PO-N8 for submit@debbugs.gnu.org; Mon, 21 Oct 2019 16:21:25 -0400 Received: from lists.gnu.org ([209.51.188.17]:36779) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMeB8-0006PF-7f for submit@debbugs.gnu.org; Mon, 21 Oct 2019 16:21:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38686) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iMeB6-00041C-Jd for bug-coreutils@gnu.org; Mon, 21 Oct 2019 16:21:22 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_50,RCVD_IN_DNSWL_MED, URIBL_BLOCKED autolearn=disabled version=3.3.2 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iMeB4-0005Bl-TK for bug-coreutils@gnu.org; Mon, 21 Oct 2019 16:21:20 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:57346) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iMeB4-0005B1-Kn for bug-coreutils@gnu.org; Mon, 21 Oct 2019 16:21:18 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 5B7AB1606BB for ; Mon, 21 Oct 2019 13:21:16 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id pREih1jR0rV3; Mon, 21 Oct 2019 13:21:15 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 19D551606B3; Mon, 21 Oct 2019 13:21:15 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id oh1L4S6QPUJa; Mon, 21 Oct 2019 13:21:15 -0700 (PDT) Received: from Penguin.CS.UCLA.EDU (Penguin.CS.UCLA.EDU [131.179.64.200]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id E8E8B160671; Mon, 21 Oct 2019 13:21:14 -0700 (PDT) From: Paul Eggert To: bug-coreutils@gnu.org Subject: [PATCH] =?UTF-8?q?shuf:=20fix=20bug=20with=20=E2=80=98-r=20-n=200?= =?UTF-8?q?=E2=80=99?= Date: Mon, 21 Oct 2019 13:21:08 -0700 Message-Id: <20191021202109.8176-1-eggert@cs.ucla.edu> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 131.179.128.68 X-Spam-Score: -1.3 (-) X-Debbugs-Envelope-To: submit Cc: Paul Eggert X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) =E2=80=98shuf -r -n 0 file=E2=80=99 would mistakenly read from standard i= nput. Problem reported by my student Jingnong Qu while reimplementing a shuf subset in Python as an exercise in UCLA Computer Science 35L: https://web.cs.ucla.edu/classes/fall19/cs35L/assign/assign3.html * NEWS: Mention the fix. Also, ASCIIfy a previous item. * src/shuf.c (main): Fix bug. * tests/misc/shuf.sh: Add a test case for the bug. --- NEWS | 5 ++++- src/shuf.c | 53 +++++++++++++++++++++++++--------------------- tests/misc/shuf.sh | 4 ++++ 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/NEWS b/NEWS index fe38e80d4..476c02aed 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,9 @@ GNU coreutils NEWS -= *- outline -*- (like Solaris 10 and Solaris 11). [bug introduced in coreutils-8.31] =20 + 'shuf -r -n 0 file' no longer mistakenly reads from standard input. + [bug introduced with the --repeat feature in coreutils-8.22] + split no longer reports a "output file suffixes exhausted" error when the specified number of files is evenly divisible by 10, 16, 26, for --numeric, --hex, or default alphabetic suffixes respectively. @@ -210,7 +213,7 @@ GNU coreutils NEWS = -*- outline -*- 'mv -n A B' no longer suffers from a race condition that can overwrite a simultaneously-created B. This bug fix requires platform support for the renameat2 or renameatx_np syscalls, found - in recent Linux and macOS kernels. As a side effect, =E2=80=98mv -n A= A=E2=80=99 + in recent Linux and macOS kernels. As a side effect, 'mv -n A A' now silently does nothing if A exists. [bug introduced with coreutils-7.1] =20 diff --git a/src/shuf.c b/src/shuf.c index 968d3641c..6a1aa0158 100644 --- a/src/shuf.c +++ b/src/shuf.c @@ -493,7 +493,12 @@ main (int argc, char **argv) } =20 /* Prepare input. */ - if (echo) + if (head_lines =3D=3D 0) + { + n_lines =3D 0; + line =3D NULL; + } + else if (echo) { input_from_argv (operand, n_operands, eolbyte); n_lines =3D n_operands; @@ -507,54 +512,54 @@ main (int argc, char **argv) else { /* If an input file is specified, re-open it as stdin. */ - if (n_operands =3D=3D 1) - if (! (STREQ (operand[0], "-") || ! head_lines - || freopen (operand[0], "r", stdin))) - die (EXIT_FAILURE, errno, "%s", quotef (operand[0])); + if (n_operands =3D=3D 1 + && ! (STREQ (operand[0], "-") + || freopen (operand[0], "r", stdin))) + die (EXIT_FAILURE, errno, "%s", quotef (operand[0])); =20 fadvise (stdin, FADVISE_SEQUENTIAL); =20 - if (! repeat && head_lines !=3D SIZE_MAX - && (! head_lines || input_size () > RESERVOIR_MIN_INPUT)) + if (repeat || head_lines =3D=3D SIZE_MAX + || input_size () <=3D RESERVOIR_MIN_INPUT) { - use_reservoir_sampling =3D true; - n_lines =3D SIZE_MAX; /* unknown number of input lines, for = now. */ + n_lines =3D read_input (stdin, eolbyte, &input_lines); + line =3D input_lines; } else { - n_lines =3D read_input (stdin, eolbyte, &input_lines); - line =3D input_lines; + use_reservoir_sampling =3D true; + n_lines =3D SIZE_MAX; /* unknown number of input lines, for = now. */ } } =20 - if (! repeat) - head_lines =3D MIN (head_lines, n_lines); + /* The adjusted head line count; can be less than HEAD_LINES if the + input is small and if not repeating. */ + size_t ahead_lines =3D repeat || head_lines < n_lines ? head_lines : n= _lines; =20 randint_source =3D randint_all_new (random_source, (use_reservoir_sampling || repeat ? SIZE_MAX - : randperm_bound (head_lines, n_lin= es))); + : randperm_bound (ahead_lines, n_li= nes))); if (! randint_source) die (EXIT_FAILURE, errno, "%s", quotef (random_source)); =20 if (use_reservoir_sampling) { /* Instead of reading the entire file into 'line', - use reservoir-sampling to store just "head_lines" random lines.= */ - n_lines =3D read_input_reservoir_sampling (stdin, eolbyte, head_li= nes, + use reservoir-sampling to store just AHEAD_LINES random lines. = */ + n_lines =3D read_input_reservoir_sampling (stdin, eolbyte, ahead_l= ines, randint_source, &reservoi= r); - head_lines =3D n_lines; + ahead_lines =3D n_lines; } =20 /* Close stdin now, rather than earlier, so that randint_all_new doesn't have to worry about opening something other than stdin. */ - if (! (echo || input_range) - && (fclose (stdin) !=3D 0)) + if (! (head_lines =3D=3D 0 || echo || input_range || fclose (stdin) =3D= =3D 0)) die (EXIT_FAILURE, errno, _("read error")); =20 if (!repeat) - permutation =3D randperm_new (randint_source, head_lines, n_lines); + permutation =3D randperm_new (randint_source, ahead_lines, n_lines); =20 if (outfile && ! freopen (outfile, "w", stdout)) die (EXIT_FAILURE, errno, "%s", quotef (outfile)); @@ -569,10 +574,10 @@ main (int argc, char **argv) if (n_lines =3D=3D 0) die (EXIT_FAILURE, 0, _("no lines to repeat")); if (input_range) - i =3D write_random_numbers (randint_source, head_lines, + i =3D write_random_numbers (randint_source, ahead_lines, lo_input, hi_input, eolbyte); else - i =3D write_random_lines (randint_source, head_lines, line, = n_lines); + i =3D write_random_lines (randint_source, ahead_lines, line,= n_lines); } } else @@ -580,10 +585,10 @@ main (int argc, char **argv) if (use_reservoir_sampling) i =3D write_permuted_output_reservoir (n_lines, reservoir, permu= tation); else if (input_range) - i =3D write_permuted_numbers (head_lines, lo_input, + i =3D write_permuted_numbers (ahead_lines, lo_input, permutation, eolbyte); else - i =3D write_permuted_lines (head_lines, line, permutation); + i =3D write_permuted_lines (ahead_lines, line, permutation); } =20 if (i !=3D 0) diff --git a/tests/misc/shuf.sh b/tests/misc/shuf.sh index bbc54a9d2..c866f5de5 100755 --- a/tests/misc/shuf.sh +++ b/tests/misc/shuf.sh @@ -39,6 +39,10 @@ compare in out > /dev/null && { fail=3D1; echo "not ra= ndom?" 1>&2; } sort -n out > out1 compare in out1 || { fail=3D1; echo "not a permutation" 1>&2; } =20 +# Exercize shuf's -r -n 0 options, with no standard input. +shuf -r -n 0 in <&- >out || fail=3D1 +compare /dev/null out || fail=3D1 + # Exercise shuf's -e option. t=3D$(shuf -e a b c d e | sort | fmt) test "$t" =3D 'a b c d e' || { fail=3D1; echo "not a permutation" 1>&2; = } --=20 2.21.0 From debbugs-submit-bounces@debbugs.gnu.org Mon Oct 21 16:28:34 2019 Received: (at control) by debbugs.gnu.org; 21 Oct 2019 20:28:34 +0000 Received: from localhost ([127.0.0.1]:57904 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMeI5-0006a1-PH for submit@debbugs.gnu.org; Mon, 21 Oct 2019 16:28:33 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:37512) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMeI3-0006Zo-FD for control@debbugs.gnu.org; Mon, 21 Oct 2019 16:28:32 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id B1BA11605EA for ; Mon, 21 Oct 2019 13:28:25 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 6_Si66cz0PWk for ; Mon, 21 Oct 2019 13:28:25 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 0E9D0160633 for ; Mon, 21 Oct 2019 13:28:25 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 0DckLo0gYOfk for ; Mon, 21 Oct 2019 13:28:24 -0700 (PDT) Received: from Penguin.CS.UCLA.EDU (Penguin.CS.UCLA.EDU [131.179.64.200]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id E2D4B1605EA for ; Mon, 21 Oct 2019 13:28:24 -0700 (PDT) To: GNU bug control From: Paul Eggert Subject: 37859 is fixed Organization: UCLA Computer Science Department Message-ID: Date: Mon, 21 Oct 2019 13:28:20 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.1.1 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) close 37859 From unknown Wed Jun 18 00:15:11 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Tue, 19 Nov 2019 12:24:08 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator