summaryrefslogtreecommitdiff
path: root/src/ls.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2004-09-26 07:06:07 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2004-09-26 07:06:07 +0000
commit1842a21b23674152ab94ca5c660a8a071123facb (patch)
treea8b95ac62bcd25805431c31693a7f141a99130d6 /src/ls.c
parentd3781e4cb267c540674ecddb9deea6080a679d5f (diff)
downloadcoreutils-1842a21b23674152ab94ca5c660a8a071123facb.tar.xz
(gobble_file, print_long_format): Don't assume that
human-readable output has a byte count equal to its column width; this isn't always true in locales where the radix character is not '.' or ','. (format_user_or_group): Revamp code to match the above fix; this avoids the (very faint) possibility of integer overflow.
Diffstat (limited to 'src/ls.c')
-rw-r--r--src/ls.c59
1 files changed, 34 insertions, 25 deletions
diff --git a/src/ls.c b/src/ls.c
index f3d5e891a..886cfb7aa 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -2545,8 +2545,9 @@ gobble_file (const char *name, enum filetype type, bool explicit_arg,
blocks = ST_NBLOCKS (f->stat);
{
char buf[LONGEST_HUMAN_READABLE + 1];
- int len = strlen (human_readable (blocks, buf, human_output_opts,
- ST_NBLOCKSIZE, output_block_size));
+ int len = mbswidth (human_readable (blocks, buf, human_output_opts,
+ ST_NBLOCKSIZE, output_block_size),
+ 0);
if (block_size_width < len)
block_size_width = len;
}
@@ -2596,8 +2597,9 @@ gobble_file (const char *name, enum filetype type, bool explicit_arg,
{
char buf[LONGEST_HUMAN_READABLE + 1];
uintmax_t size = unsigned_file_size (f->stat.st_size);
- int len = strlen (human_readable (size, buf, human_output_opts,
- 1, file_output_block_size));
+ int len = mbswidth (human_readable (size, buf, human_output_opts,
+ 1, file_output_block_size),
+ 0);
if (file_size_width < len)
file_size_width = len;
}
@@ -3051,17 +3053,15 @@ format_user_or_group (char const *name, unsigned long int id, int width)
if (name)
{
- /* The output column count may differ from the byte count.
- Adjust for this, but don't output garbage if integer overflow
- occurs during adjustment. */
- len = strlen (name);
- width -= mbswidth (name, 0);
- width += len;
- if (width < 0)
- width = 0;
- printf ("%-*s ", width, name);
- if (len < width)
- len = width;
+ size_t namelen = strlen (name);
+ int width_gap = width - mbswidth (name, 0);
+ int pad = MAX (0, width_gap);
+ fputs (name, stdout);
+ len = strlen (name) + pad;
+
+ do
+ putchar (' ');
+ while (pad--);
}
else
{
@@ -3184,10 +3184,15 @@ print_long_format (const struct fileinfo *f)
if (print_block_size)
{
char hbuf[LONGEST_HUMAN_READABLE + 1];
- sprintf (p, "%*s ", block_size_width,
- human_readable (ST_NBLOCKS (f->stat), hbuf, human_output_opts,
- ST_NBLOCKSIZE, output_block_size));
- p += block_size_width + 1;
+ char const *blocks =
+ human_readable (ST_NBLOCKS (f->stat), hbuf, human_output_opts,
+ ST_NBLOCKSIZE, output_block_size);
+ int pad;
+ for (pad = block_size_width - mbswidth (blocks, 0); 0 < pad; pad--)
+ *p++ = ' ';
+ while ((*p++ = *blocks++))
+ continue;
+ p[-1] = ' ';
}
/* The last byte of the mode string is the POSIX
@@ -3229,18 +3234,22 @@ print_long_format (const struct fileinfo *f)
umaxtostr (major (f->stat.st_rdev), majorbuf),
minor_device_number_width,
umaxtostr (minor (f->stat.st_rdev), minorbuf));
+ p += file_size_width + 1;
}
else
{
char hbuf[LONGEST_HUMAN_READABLE + 1];
- uintmax_t size = unsigned_file_size (f->stat.st_size);
- sprintf (p, "%*s ", file_size_width,
- human_readable (size, hbuf, human_output_opts,
- 1, file_output_block_size));
+ char const *size =
+ human_readable (unsigned_file_size (f->stat.st_size),
+ hbuf, human_output_opts, 1, file_output_block_size);
+ int pad;
+ for (pad = file_size_width - mbswidth (size, 0); 0 < pad; pad--)
+ *p++ = ' ';
+ while ((*p++ = *size++))
+ continue;
+ p[-1] = ' ';
}
- p += file_size_width + 1;
-
if ((when_local = localtime (&when)))
{
time_t six_months_ago;