mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
ls: fix alignment with locale formatted --size
Fix allocated size alignment in locales with multi-byte grouping chars.
Tested with: LC_ALL=sv_SE.utf8 ls --size --block-size=\'k
* src/ls.c (print_file_name_and_frills): Don't rely on
printf("%*s", width, string) to pad multi-byte strings appropriately.
Instead work out the padding required and use:
printf("%*s%s", padding, "", string) to pad multi-byte appropriately.
* tests/ls/block-size.sh: Add a test case.
* NEWS: Mention the bug fix.
Fixes https://bugs.gnu.org/79347
This commit is contained in:
4
NEWS
4
NEWS
@@ -35,6 +35,10 @@ GNU coreutils NEWS -*- outline -*-
|
||||
a confusing error about changing permissions.
|
||||
[This bug was present in "the beginning".]
|
||||
|
||||
"ls --size --block-size=\'k" could misalign output in locales
|
||||
with multi-byte thousands grouping characters.
|
||||
[This bug was present in "the beginning".]
|
||||
|
||||
'od --strings' with '-N' now works correctly. Previously od might
|
||||
write a NUL byte after a heap buffer, or output invalid addresses.
|
||||
[These bugs were present in "the beginning".]
|
||||
|
||||
16
src/ls.c
16
src/ls.c
@@ -4869,10 +4869,18 @@ print_file_name_and_frills (const struct fileinfo *f, size_t start_col)
|
||||
format_inode (buf, f));
|
||||
|
||||
if (print_block_size)
|
||||
printf ("%*s ", format == with_commas ? 0 : block_size_width,
|
||||
! f->stat_ok ? "?"
|
||||
: human_readable (STP_NBLOCKS (&f->stat), buf, human_output_opts,
|
||||
ST_NBLOCKSIZE, output_block_size));
|
||||
{
|
||||
char const *blocks =
|
||||
(! f->stat_ok
|
||||
? "?"
|
||||
: human_readable (STP_NBLOCKS (&f->stat), buf, human_output_opts,
|
||||
ST_NBLOCKSIZE, output_block_size));
|
||||
int blocks_width = mbswidth (blocks, MBSWIDTH_FLAGS);
|
||||
int pad = 0;
|
||||
if (0 <= blocks_width && block_size_width && format != with_commas)
|
||||
pad = block_size_width - blocks_width;
|
||||
printf ("%*s%s ", pad, "", blocks);
|
||||
}
|
||||
|
||||
if (print_scontext)
|
||||
printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext);
|
||||
|
||||
@@ -26,9 +26,9 @@ mkdir sub
|
||||
cd sub
|
||||
|
||||
for size in 1024 4096 262144; do
|
||||
echo foo | dd conv=sync bs=$size >file$size || fail=1
|
||||
echo foo | dd conv=sync bs=$size >file$size || framework_failure_
|
||||
done
|
||||
touch -d '2001-01-01 00:00' file* || fail=1
|
||||
touch -d '2001-01-01 00:00' file* || framework_failure_
|
||||
|
||||
size_etc='s/[^ ]* *[^ ]* *//'
|
||||
|
||||
@@ -183,4 +183,21 @@ EOF
|
||||
|
||||
compare exp out || fail=1
|
||||
|
||||
# Ensure --size alignment with multi-byte grouping chars
|
||||
# which wasn't the case before coreutils v9.8
|
||||
cd sub
|
||||
for sizem in 1 10; do
|
||||
echo foo |
|
||||
dd conv=sync bs=$((sizem*1024*1024)) >file${sizem}M || framework_failure_
|
||||
done
|
||||
|
||||
# If any of these unavailable, the C fallback should also be aligned
|
||||
for loc in sv_SE.UTF-8 $LOCALE_FR_UTF8; do
|
||||
test $(LC_ALL=$loc ls -s1 --block-size=\'k |
|
||||
tail -n+2 | cut -dK -f1 |
|
||||
while IFS= read size; do
|
||||
printf '%s\n' "$size" | LC_ALL=$loc wc -L
|
||||
done | uniq | wc -l) = 1 || fail=1
|
||||
done
|
||||
|
||||
Exit $fail
|
||||
|
||||
Reference in New Issue
Block a user