Subject: bug#77622: coreutils-9.6.53-14af8 on Solaris 11 OpenIndiana

From: Bruno Haible <[email-masked]>
Date: Tue, 08 Apr 2025 02:38:19 +0200

On Solaris OpenIndiana, there is one test failure:
FAIL: tests/misc/numfmt

Specifically, the tests lcl-fmt-2, lcl-fmt-3 fail. See the attached log file.

I can easily reproduce it:
  $ LC_ALL=fr_FR.UTF-8 src/numfmt --format "--%'10f--" 50000
  --50�000--
whereas
  $ LC_ALL=en_US.UTF-8 src/numfmt --format "--%'10f--" 50000
  --    50,000--

What happens is that numfmt prepares a format string "%'.*Lf%s" and
passes it to snprintf(), in the fr_FR.UTF-8 locale. Solaris 11 OpenIndiana
and Solaris 11 OmniOS have a bug here: when the thousands-separator is
a multibyte character, snprintf() takes only the first byte of it.

This is not a problem on other platforms: A test program (attached)
shows that:
  - on Solaris 11.4, the thousands-separator is U+0020 = SPACE, a single-byte
    character.
  - on glibc, it is U+202F NARROW NO-BREAK SPACE, and snprintf stores
    it entirely in the result string.
  - on Solaris 11 OpenIndiana / OmniOS, it is U+00A0 NO-BREAK SPACE =
    "\xc2\xa0", and snprintf() takes only the first byte.

Later, the padding pass runs mbswidth() on the returned string, and
due to this invalid byte sequence mbswidth() returns -1, and no padding
characters are added.

The fix belongs in Solaris 11 or Gnulib; the numfmt source code should
not need any changes. I'll deal with that; this should not delay the
coreutils release.

Bruno