summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAssaf Gordon <assafgordon@gmail.com>2014-07-15 12:25:03 -0400
committerPádraig Brady <P@draigBrady.com>2014-07-16 22:35:17 +0100
commit061882d73b4f11f7b7f7151754e617234edc6f7a (patch)
treed527f75dcf25f2ded0233eb0f7728b958c91a30c
parent37b36018d3f5f276622a9888e32623f9410a80e0 (diff)
downloadcoreutils-061882d73b4f11f7b7f7151754e617234edc6f7a.tar.gz
numfmt: fix isblank() usage for some unibyte locales
* src/numfmt.c (simple_strtod_int): Replace isdigit() with c_isdigit() to avoid locale concerns and -Wchar-subscripts warnings on cygwin. Remove the now redundant locale guard. (simple_strtod_human): Cast characters to unsigned so that the promoted int value passed to isblank() is positive, allowing it to work correctly for all characters in unibyte locales. Previously character 0xA0, i.e. non-breaking space, would be misclassified for example. (process_suffixed_number): Likewise. (skip_fields): Likewise. Both issues were triggered by the -Wchar-subscripts warning on GCC 4.8.3 on cygwin, due to the is*() implementations used there, but the issue is present on all platforms defaulting to signed chars. * NEWS: Mention the bug fix. Reported by Eric Blake
-rw-r--r--NEWS4
-rw-r--r--src/numfmt.c15
2 files changed, 10 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index f691ab3cb..7f40fad83 100644
--- a/NEWS
+++ b/NEWS
@@ -86,6 +86,10 @@ GNU coreutils NEWS -*- outline -*-
ln -sr '' F no longer segfaults. Now works as expected.
[bug introduced with the --relative feature in coreutils-8.16]
+ numfmt now handles blanks correctly in all unibyte locales. Previously
+ in locales where character 0xA0 is a blank, numfmt would mishandle it.
+ [bug introduced when numfmt was added in coreutils-8.21]
+
ptx --format long option parsing no longer falls through into the --help case.
[bug introduced in TEXTUTILS-1_22i]
diff --git a/src/numfmt.c b/src/numfmt.c
index 6091bb6bd..206866ac9 100644
--- a/src/numfmt.c
+++ b/src/numfmt.c
@@ -23,6 +23,7 @@
#include "mbsalign.h"
#include "argmatch.h"
+#include "c-ctype.h"
#include "error.h"
#include "quote.h"
#include "system.h"
@@ -454,14 +455,10 @@ simple_strtod_int (const char *input_str,
*negative = false;
*endptr = (char *) input_str;
- while (*endptr && isdigit (**endptr))
+ while (*endptr && c_isdigit (**endptr))
{
int digit = (**endptr) - '0';
- /* can this happen in some strange locale? */
- if (digit < 0 || digit > 9)
- return SSE_INVALID_NUMBER;
-
if (digits > MAX_UNSCALED_DIGITS)
e = SSE_OK_PRECISION_LOSS;
@@ -600,7 +597,7 @@ simple_strtod_human (const char *input_str,
/* process suffix. */
/* Skip any blanks between the number and suffix. */
- while (isblank (**endptr))
+ while (isblank (to_uchar (**endptr)))
(*endptr)++;
if (!valid_suffix (**endptr))
@@ -1174,7 +1171,7 @@ process_suffixed_number (char *text, long double *result, size_t *precision)
/* Skip white space - always. */
char *p = text;
- while (*p && isblank (*p))
+ while (*p && isblank (to_uchar (*p)))
++p;
const unsigned int skip_count = text - p;
@@ -1229,9 +1226,9 @@ skip_fields (char *buf, int fields)
else
while (*ptr && fields--)
{
- while (*ptr && isblank (*ptr))
+ while (*ptr && isblank (to_uchar (*ptr)))
++ptr;
- while (*ptr && !isblank (*ptr))
+ while (*ptr && !isblank (to_uchar (*ptr)))
++ptr;
}
return ptr;