mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 04:22:34 +03:00
Ticket #3666: Improper use of IEC and SI prefixes for size in size_trunc().
(size_trunc_len): return statically allocated buffer. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
37fcb210f2
commit
fdd9ab4098
32
lib/util.c
32
lib/util.c
@ -405,18 +405,24 @@ size_trunc_sep (uintmax_t size, gboolean use_si)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Print file SIZE to BUFFER, but don't exceed LEN characters,
|
||||
* not including trailing 0. BUFFER should be at least LEN+1 long.
|
||||
* This function is called for every file on panels, so avoid
|
||||
* floating point by any means.
|
||||
* Represent some numeric value as string of required length.
|
||||
*
|
||||
* Units: size units (filesystem sizes are 1K blocks)
|
||||
* 0=bytes, 1=Kbytes, 2=Mbytes, etc.
|
||||
* @param len number of characters to represent @size
|
||||
* @param size value to represent
|
||||
* @param units @size units: 0=bytes, 1=Kbytes, 2=Mbytes, etc.
|
||||
* @param use_si use SI or IEC units (10- or 2-based respectively)
|
||||
*
|
||||
* @return static buffer
|
||||
*/
|
||||
|
||||
void
|
||||
size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gboolean use_si)
|
||||
const char *
|
||||
size_trunc_len (unsigned int len, uintmax_t size, int units, gboolean use_si)
|
||||
{
|
||||
/* This function is called for every file on panels, so avoid floating point by any means. */
|
||||
|
||||
/* Enough space to represent uintmax_t value with units */
|
||||
static char buffer[BUF_TINY];
|
||||
|
||||
/* Avoid taking power for every file. */
|
||||
/* *INDENT-OFF* */
|
||||
static const uintmax_t power10[] = {
|
||||
@ -452,6 +458,7 @@ size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gbool
|
||||
#endif
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static const char *const suffix[] = { "", "K", "M", "G", "T", "P", "E", "Z", "Y", NULL };
|
||||
static const char *const suffix_lc[] = { "", "k", "m", "g", "t", "p", "e", "z", "y", NULL };
|
||||
|
||||
@ -493,19 +500,20 @@ size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gbool
|
||||
if (j == units)
|
||||
{
|
||||
/* Empty files will print "0" even with minimal width. */
|
||||
g_snprintf (buffer, len + 1, "%s", "0");
|
||||
g_snprintf (buffer, sizeof (buffer), "%s", "0");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use "~K" or just "K" if len is 1. Use "B" for bytes. */
|
||||
g_snprintf (buffer, len + 1, (len > 1) ? "~%s" : "%s", (j > 1) ? sfx[j - 1] : "B");
|
||||
g_snprintf (buffer, sizeof (buffer), (len > 1) ? "~%s" : "%s",
|
||||
(j > 1) ? sfx[j - 1] : "B");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (size < power10[len - (j > 0 ? 1 : 0)])
|
||||
{
|
||||
g_snprintf (buffer, len + 1, "%" PRIuMAX "%s", size, sfx[j]);
|
||||
g_snprintf (buffer, sizeof (buffer), "%" PRIuMAX "%s", size, sfx[j]);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -515,6 +523,8 @@ size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gbool
|
||||
else
|
||||
size = (size + 512) >> 10;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -150,11 +150,11 @@ const char *size_trunc (uintmax_t size, gboolean use_si);
|
||||
* NOTE: uses the same static buffer as size_trunc. */
|
||||
const char *size_trunc_sep (uintmax_t size, gboolean use_si);
|
||||
|
||||
/* Print file SIZE to BUFFER, but don't exceed LEN characters,
|
||||
* not including trailing 0. BUFFER should be at least LEN+1 long.
|
||||
*
|
||||
/* Return a static string representing size, appending "K" or "M" for
|
||||
* big sizes. but don't exceed LEN characters,
|
||||
* Units: size units (0=bytes, 1=Kbytes, 2=Mbytes, etc.) */
|
||||
void size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gboolean use_si);
|
||||
const char *size_trunc_len (unsigned int len, uintmax_t size, int units, gboolean use_si);
|
||||
|
||||
const char *string_perm (mode_t mode_bits);
|
||||
|
||||
const char *extension (const char *);
|
||||
|
@ -407,7 +407,7 @@ chown_cmd (void)
|
||||
struct stat sf_stat;
|
||||
const char *fname;
|
||||
int result;
|
||||
char buffer[BUF_TINY];
|
||||
const char *buffer;
|
||||
uid_t new_user = (uid_t) (-1);
|
||||
gid_t new_group = (gid_t) (-1);
|
||||
|
||||
@ -438,7 +438,7 @@ chown_cmd (void)
|
||||
chown_label (0, str_trunc (fname, GW - 4));
|
||||
chown_label (1, str_trunc (get_owner (sf_stat.st_uid), GW - 4));
|
||||
chown_label (2, str_trunc (get_group (sf_stat.st_gid), GW - 4));
|
||||
size_trunc_len (buffer, GW - 4, sf_stat.st_size, 0, panels_options.kilobyte_si);
|
||||
buffer = size_trunc_len (GW - 4, sf_stat.st_size, 0, panels_options.kilobyte_si);
|
||||
chown_label (3, buffer);
|
||||
chown_label (4, string_perm (sf_stat.st_mode));
|
||||
|
||||
|
@ -491,7 +491,7 @@ overwrite_query_dialog (file_op_context_t * ctx, enum OperationMode mode)
|
||||
|
||||
vfs_path_t *p;
|
||||
char *s1;
|
||||
char s2[BUF_SMALL];
|
||||
const char *s2;
|
||||
int w, bw1, bw2;
|
||||
unsigned short i;
|
||||
|
||||
@ -524,7 +524,7 @@ overwrite_query_dialog (file_op_context_t * ctx, enum OperationMode mode)
|
||||
vfs_path_free (p);
|
||||
g_free (s1);
|
||||
/* new file size */
|
||||
size_trunc_len (s2, sizeof (s2), ui->src_stat->st_size, 0, panels_options.kilobyte_si);
|
||||
s2 = size_trunc_len (BUF_SMALL - 1, ui->src_stat->st_size, 0, panels_options.kilobyte_si);
|
||||
NEW_LABEL (2, s2);
|
||||
/* new file modification date & time */
|
||||
s1 = (char *) file_date (ui->src_stat->st_mtime);
|
||||
@ -539,7 +539,7 @@ overwrite_query_dialog (file_op_context_t * ctx, enum OperationMode mode)
|
||||
vfs_path_free (p);
|
||||
g_free (s1);
|
||||
/* existing file size */
|
||||
size_trunc_len (s2, sizeof (s2), ui->dst_stat->st_size, 0, panels_options.kilobyte_si);
|
||||
s2 = size_trunc_len (BUF_SMALL - 1, ui->dst_stat->st_size, 0, panels_options.kilobyte_si);
|
||||
NEW_LABEL (6, s2);
|
||||
/* existing file modification date & time */
|
||||
s1 = (char *) file_date (ui->dst_stat->st_mtime);
|
||||
@ -1030,8 +1030,6 @@ file_progress_show_total (file_op_total_context_t * tctx, file_op_context_t * ct
|
||||
uintmax_t copied_bytes, gboolean show_summary)
|
||||
{
|
||||
char buffer[BUF_TINY];
|
||||
char buffer2[BUF_TINY];
|
||||
char buffer3[BUF_TINY];
|
||||
file_op_context_ui_t *ui;
|
||||
|
||||
if (ctx == NULL || ctx->ui == NULL)
|
||||
@ -1057,7 +1055,7 @@ file_progress_show_total (file_op_total_context_t * tctx, file_op_context_t * ct
|
||||
if (ui->time_label != NULL)
|
||||
{
|
||||
struct timeval tv_current;
|
||||
char buffer4[BUF_TINY];
|
||||
char buffer2[BUF_TINY], buffer3[BUF_TINY];
|
||||
|
||||
gettimeofday (&tv_current, NULL);
|
||||
file_frmt_time (buffer2, tv_current.tv_sec - tctx->transfer_start.tv_sec);
|
||||
@ -1069,6 +1067,8 @@ file_progress_show_total (file_op_total_context_t * tctx, file_op_context_t * ct
|
||||
g_snprintf (buffer, sizeof (buffer), _("Time: %s %s"), buffer2, buffer3);
|
||||
else
|
||||
{
|
||||
char buffer4[BUF_TINY];
|
||||
|
||||
file_bps_prepare_for_show (buffer4, (long) tctx->bps);
|
||||
g_snprintf (buffer, sizeof (buffer), _("Time: %s %s (%s)"), buffer2, buffer3,
|
||||
buffer4);
|
||||
@ -1080,8 +1080,8 @@ file_progress_show_total (file_op_total_context_t * tctx, file_op_context_t * ct
|
||||
g_snprintf (buffer, sizeof (buffer), _("Time: %s"), buffer2);
|
||||
else
|
||||
{
|
||||
file_bps_prepare_for_show (buffer4, (long) tctx->bps);
|
||||
g_snprintf (buffer, sizeof (buffer), _("Time: %s (%s)"), buffer2, buffer4);
|
||||
file_bps_prepare_for_show (buffer3, (long) tctx->bps);
|
||||
g_snprintf (buffer, sizeof (buffer), _("Time: %s (%s)"), buffer2, buffer3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1090,14 +1090,19 @@ file_progress_show_total (file_op_total_context_t * tctx, file_op_context_t * ct
|
||||
|
||||
if (ui->total_bytes_label != NULL)
|
||||
{
|
||||
size_trunc_len (buffer2, 5, tctx->copied_bytes, 0, panels_options.kilobyte_si);
|
||||
const char *buffer2, *buffer3;
|
||||
|
||||
buffer2 = size_trunc_len (5, tctx->copied_bytes, 0, panels_options.kilobyte_si);
|
||||
if (!ctx->progress_totals_computed)
|
||||
g_snprintf (buffer, sizeof (buffer), _(" Total: %s "), buffer2);
|
||||
else
|
||||
{
|
||||
size_trunc_len (buffer3, 5, ctx->progress_bytes, 0, panels_options.kilobyte_si);
|
||||
g_snprintf (buffer, sizeof (buffer), _(" Total: %s/%s "), buffer2, buffer3);
|
||||
char *b2;
|
||||
|
||||
b2 = g_strdup (buffer2);
|
||||
buffer3 = size_trunc_len (5, ctx->progress_bytes, 0, panels_options.kilobyte_si);
|
||||
g_snprintf (buffer, sizeof (buffer), _(" Total: %s/%s "), b2, buffer3);
|
||||
g_free (b2);
|
||||
}
|
||||
|
||||
hline_set_text (ui->total_bytes_label, buffer);
|
||||
|
@ -176,13 +176,16 @@ info_show_info (WInfo * info)
|
||||
tty_print_string (_("No space information"));
|
||||
else
|
||||
{
|
||||
char buffer1[6], buffer2[6];
|
||||
char *buffer1;
|
||||
const char *buffer2;
|
||||
|
||||
size_trunc_len (buffer1, 5, myfs_stats.avail, 1, panels_options.kilobyte_si);
|
||||
size_trunc_len (buffer2, 5, myfs_stats.total, 1, panels_options.kilobyte_si);
|
||||
buffer1 =
|
||||
g_strdup (size_trunc_len (5, myfs_stats.avail, 1, panels_options.kilobyte_si));
|
||||
buffer2 = size_trunc_len (5, myfs_stats.total, 1, panels_options.kilobyte_si);
|
||||
tty_printf (_("Free space: %s/%s (%d%%)"), buffer1, buffer2,
|
||||
myfs_stats.total == 0 ? 0 :
|
||||
(int) (100 * (long double) myfs_stats.avail / myfs_stats.total));
|
||||
g_free (buffer1);
|
||||
}
|
||||
MC_FALLTHROUGH;
|
||||
case 14:
|
||||
@ -236,8 +239,9 @@ info_show_info (WInfo * info)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
char buffer[10];
|
||||
size_trunc_len (buffer, 9, st.st_size, 0, panels_options.kilobyte_si);
|
||||
const char *buffer;
|
||||
|
||||
buffer = size_trunc_len (9, st.st_size, 0, panels_options.kilobyte_si);
|
||||
tty_printf (_("Size: %s"), buffer);
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
|
||||
tty_printf (ngettext (" (%lu block)", " (%lu blocks)",
|
||||
|
@ -512,12 +512,13 @@ string_file_size (file_entry_t * fe, int len)
|
||||
|
||||
#ifdef HAVE_STRUCT_STAT_ST_RDEV
|
||||
if (S_ISBLK (fe->st.st_mode) || S_ISCHR (fe->st.st_mode))
|
||||
{
|
||||
format_device_number (buffer, len + 1, fe->st.st_rdev);
|
||||
else
|
||||
return buffer;
|
||||
}
|
||||
#endif
|
||||
size_trunc_len (buffer, (unsigned int) len, fe->st.st_size, 0, panels_options.kilobyte_si);
|
||||
|
||||
return buffer;
|
||||
return size_trunc_len ((unsigned int) len, fe->st.st_size, 0, panels_options.kilobyte_si);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1154,15 +1155,17 @@ show_free_space (const WPanel * panel)
|
||||
if (myfs_stats.avail != 0 || myfs_stats.total != 0)
|
||||
{
|
||||
const Widget *w = CONST_WIDGET (panel);
|
||||
char buffer1[6], buffer2[6], tmp[BUF_SMALL];
|
||||
char *buffer1;
|
||||
const char *buffer2;
|
||||
char tmp[BUF_SMALL];
|
||||
|
||||
size_trunc_len (buffer1, sizeof (buffer1) - 1, myfs_stats.avail, 1,
|
||||
panels_options.kilobyte_si);
|
||||
size_trunc_len (buffer2, sizeof (buffer2) - 1, myfs_stats.total, 1,
|
||||
panels_options.kilobyte_si);
|
||||
buffer1 = g_strdup (size_trunc_len (5, myfs_stats.avail, 1, panels_options.kilobyte_si));
|
||||
buffer2 = size_trunc_len (5, myfs_stats.total, 1, panels_options.kilobyte_si);
|
||||
g_snprintf (tmp, sizeof (tmp), " %s/%s (%d%%) ", buffer1, buffer2,
|
||||
myfs_stats.total == 0 ? 0 :
|
||||
(int) (100 * (long double) myfs_stats.avail / myfs_stats.total));
|
||||
g_free (buffer1);
|
||||
/* FIX LEGACY: use str_term_width1() instead of strlen() here */
|
||||
widget_move (w, w->lines - 1, w->cols - 2 - (int) strlen (tmp));
|
||||
tty_setcolor (NORMAL_COLOR);
|
||||
tty_print_string (tmp);
|
||||
|
@ -169,12 +169,13 @@ mcview_display_status (WView * view)
|
||||
tty_printf ("0x%08" PRIxMAX, (uintmax_t) view->hex_cursor);
|
||||
else
|
||||
{
|
||||
char buffer[BUF_TRUNC_LEN + 1];
|
||||
const char *buffer;
|
||||
|
||||
size_trunc_len (buffer, BUF_TRUNC_LEN, mcview_get_filesize (view), 0,
|
||||
panels_options.kilobyte_si);
|
||||
tty_printf ("%9" PRIuMAX "/%s%s %s", (uintmax_t) view->dpy_end,
|
||||
buffer, mcview_may_still_grow (view) ? "+" : " ",
|
||||
buffer =
|
||||
size_trunc_len (BUF_TRUNC_LEN, mcview_get_filesize (view), 0,
|
||||
panels_options.kilobyte_si);
|
||||
tty_printf ("%9" PRIuMAX "/%s%s %s", (uintmax_t) view->dpy_end, buffer,
|
||||
mcview_may_still_grow (view) ? "+" : " ",
|
||||
#ifdef HAVE_CHARSET
|
||||
mc_global.source_codepage >= 0 ?
|
||||
get_codepage_id (mc_global.source_codepage) :
|
||||
|
Loading…
Reference in New Issue
Block a user