cut, expand, fold, join, numfmt, unexpand, uniq, on non-GLIBC platforms
treated the \u0085 (next line) character as a blank character.

src/system.h (c32isvertspace): Include 0x0085 so c32issep() excludes it.
Also split out to ...
(c32isnewline): ... a new function, in case we need to
consider unicode newlines in isolation in future.
* tests/unexpand/mb.sh: Add a test case to both ensure
processing of \u0085 characters does not overflow a buffer,
and that those characters are not treated as separators.
* NEWS: Mention the fix.

Link: https://github.com/coreutils/coreutils/pull/361
---
 NEWS                 |  4 ++++
 src/system.h         | 13 ++++++++++---
 tests/unexpand/mb.sh |  9 +++++++++
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 85ba2cec2..7af271ceb 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,10 @@ GNU coreutils NEWS                                    -*- 
outline -*-
 
 ** Bug fixes
 
+  cut, expand, fold, join, numfmt, unexpand, and uniq, no longer consider
+  the \u0085 (next line) character as a separator on non-GLIBC platforms.
+  [bug introduced in coreutils-9.11]
+
   'realpath' without -s, or 'readlink' with -e,-f,-m no longer
   loop infinitely when resolving a symbolic link which
   resolves to a path beginning with the symbolic link itself.
diff --git a/src/system.h b/src/system.h
index 66d0ab1b8..926426204 100644
--- a/src/system.h
+++ b/src/system.h
@@ -167,12 +167,19 @@ c32isnbspace (char32_t wc)
 
 ATTRIBUTE_PURE
 static inline int
-c32isvertspace (char32_t wc)
+c32isnewline (char32_t wc)
 {
-  return    wc == 0x000A || wc == 0x000B || wc == 0x000C || wc == 0x000D
-         || wc == 0x2028 || wc == 0x2029;
+  return wc == 0x000A || wc == 0x0085 || wc == 0x2028 || wc == 0x2029;
 }
 
+ATTRIBUTE_PURE
+static inline int
+c32isvertspace (char32_t wc)
+{
+  /* 000D is backwards as opposed to vertical,
+     but that's fine for this grouping.  */
+  return c32isnewline (wc) || wc == 0x000B || wc == 0x000C || wc == 0x000D;
+}
 
 /* c32isblank() is too variable on non GLIBC platforms.
    E.g., does not include \u3000 ideographic space on musl.
diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh
index 84ba0354e..a1155f193 100755
--- a/tests/unexpand/mb.sh
+++ b/tests/unexpand/mb.sh
@@ -178,4 +178,13 @@ ideo_space=$(env printf '\u3000')
   unexpand -t1 >out 2>err; ret=$?
 test "$ret" = 0 || { cat err; fail=1; }
 
+# Ensure U+0085 is not treated as a separator,
+# and also no buffer overflows (where wcwidth() is -1) as per:
+# https://github.com/coreutils/coreutils/pull/361
+next_line=$(env printf '\u0085')
+yes "$next_line" | head -n 40000 | { tr -d '\n'; echo; } >next_lines ||
+  framework_failure_
+unexpand -t1 <next_lines >out || fail=1
+compare out next_lines || fail=1
+
 Exit $fail
-- 
2.55.0


Reply via email to