80 lines
2.6 KiB
Diff
80 lines
2.6 KiB
Diff
From 2f56f5a42033dc6db15d8963e54566f01fa0d61d Mon Sep 17 00:00:00 2001
|
|
From: Paul Eggert <eggert@cs.ucla.edu>
|
|
Date: Sun, 1 May 2022 22:46:21 -0700
|
|
Subject: [PATCH] sort: fix sort -g infloop again
|
|
|
|
Problem reported by Giulio Genovese (Bug#55212).
|
|
* src/sort.c (nan_compare): To compare NaNs, simply printf+strcmp.
|
|
This avoids the problem of padding bits and unspecified behavior.
|
|
Args are now long double instead of char *; caller changed.
|
|
|
|
Reference:https://github.com/coreutils/coreutils/commit/2f56f5a42033dc6db15d8963e54566f01fa0d61d
|
|
Conflict: NEWS Context adaptation
|
|
|
|
---
|
|
NEWS | 6 ++++++
|
|
src/sort.c | 21 ++++++---------------
|
|
2 files changed, 12 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/NEWS b/NEWS
|
|
index 3e44c0c..fc8ff16 100644
|
|
--- a/NEWS
|
|
+++ b/NEWS
|
|
@@ -4,6 +4,12 @@ GNU coreutils NEWS -*- outline -*-
|
|
|
|
** Bug fixes
|
|
|
|
+ 'sort -g' no longer infloops when given multiple NaNs on platforms
|
|
+ like x86-64 where 'long double' has padding bits in memory.
|
|
+ Although the fix alters sort -g's NaN ordering, that ordering has
|
|
+ long been documented to be platform-dependent.
|
|
+ [bug introduced 1999-05-02 and only partly fixed in coreutils-8.14]
|
|
+
|
|
cp now copies /dev/fd/N correctly on platforms like Solaris where
|
|
it is a character-special file whose minor device number is N.
|
|
[bug introduced in fileutils-4.1.6]
|
|
diff --git a/src/sort.c b/src/sort.c
|
|
index 8e1533e..5b4342f 100644
|
|
--- a/src/sort.c
|
|
+++ b/src/sort.c
|
|
@@ -2360,22 +2360,13 @@ numcompare_mb (const char *a, const char *b)
|
|
}
|
|
#endif /* HAV_EMBRTOWC */
|
|
|
|
-/* Work around a problem whereby the long double value returned by glibc's
|
|
- strtold ("NaN", ...) contains uninitialized bits: clear all bytes of
|
|
- A and B before calling strtold. FIXME: remove this function if
|
|
- gnulib guarantees that strtold's result is always well defined. */
|
|
static int
|
|
-nan_compare (char const *sa, char const *sb)
|
|
+nan_compare (long double a, long double b)
|
|
{
|
|
- long double a;
|
|
- memset (&a, 0, sizeof a);
|
|
- a = strtold (sa, NULL);
|
|
-
|
|
- long double b;
|
|
- memset (&b, 0, sizeof b);
|
|
- b = strtold (sb, NULL);
|
|
-
|
|
- return memcmp (&a, &b, sizeof a);
|
|
+ char buf[2][sizeof "-nan()" + CHAR_BIT * sizeof a];
|
|
+ snprintf (buf[0], sizeof buf[0], "%Lf", a);
|
|
+ snprintf (buf[1], sizeof buf[1], "%Lf", b);
|
|
+ return strcmp (buf[0], buf[1]);
|
|
}
|
|
|
|
static int
|
|
@@ -2403,7 +2394,7 @@ general_numcompare (char const *sa, char const *sb)
|
|
: a == b ? 0
|
|
: b == b ? -1
|
|
: a == a ? 1
|
|
- : nan_compare (sa, sb));
|
|
+ : nan_compare (a, b));
|
|
}
|
|
|
|
/* Return an integer in 1..12 of the month name MONTH.
|
|
--
|
|
2.27.0
|
|
|