mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 12:32:40 +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,
|
* Represent some numeric value as string of required length.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* Units: size units (filesystem sizes are 1K blocks)
|
* @param len number of characters to represent @size
|
||||||
* 0=bytes, 1=Kbytes, 2=Mbytes, etc.
|
* @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
|
const char *
|
||||||
size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gboolean use_si)
|
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. */
|
/* Avoid taking power for every file. */
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
static const uintmax_t power10[] = {
|
static const uintmax_t power10[] = {
|
||||||
@ -452,6 +458,7 @@ size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gbool
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
static const char *const suffix[] = { "", "K", "M", "G", "T", "P", "E", "Z", "Y", NULL };
|
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 };
|
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)
|
if (j == units)
|
||||||
{
|
{
|
||||||
/* Empty files will print "0" even with minimal width. */
|
/* Empty files will print "0" even with minimal width. */
|
||||||
g_snprintf (buffer, len + 1, "%s", "0");
|
g_snprintf (buffer, sizeof (buffer), "%s", "0");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Use "~K" or just "K" if len is 1. Use "B" for bytes. */
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size < power10[len - (j > 0 ? 1 : 0)])
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,6 +523,8 @@ size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gbool
|
|||||||
else
|
else
|
||||||
size = (size + 512) >> 10;
|
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. */
|
* NOTE: uses the same static buffer as size_trunc. */
|
||||||
const char *size_trunc_sep (uintmax_t size, gboolean use_si);
|
const char *size_trunc_sep (uintmax_t size, gboolean use_si);
|
||||||
|
|
||||||
/* Print file SIZE to BUFFER, but don't exceed LEN characters,
|
/* Return a static string representing size, appending "K" or "M" for
|
||||||
* not including trailing 0. BUFFER should be at least LEN+1 long.
|
* big sizes. but don't exceed LEN characters,
|
||||||
*
|
|
||||||
* Units: size units (0=bytes, 1=Kbytes, 2=Mbytes, etc.) */
|
* 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 *string_perm (mode_t mode_bits);
|
||||||
|
|
||||||
const char *extension (const char *);
|
const char *extension (const char *);
|
||||||
|
@ -407,7 +407,7 @@ chown_cmd (void)
|
|||||||
struct stat sf_stat;
|
struct stat sf_stat;
|
||||||
const char *fname;
|
const char *fname;
|
||||||
int result;
|
int result;
|
||||||
char buffer[BUF_TINY];
|
const char *buffer;
|
||||||
uid_t new_user = (uid_t) (-1);
|
uid_t new_user = (uid_t) (-1);
|
||||||
gid_t new_group = (gid_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 (0, str_trunc (fname, GW - 4));
|
||||||
chown_label (1, str_trunc (get_owner (sf_stat.st_uid), 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));
|
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 (3, buffer);
|
||||||
chown_label (4, string_perm (sf_stat.st_mode));
|
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;
|
vfs_path_t *p;
|
||||||
char *s1;
|
char *s1;
|
||||||
char s2[BUF_SMALL];
|
const char *s2;
|
||||||
int w, bw1, bw2;
|
int w, bw1, bw2;
|
||||||
unsigned short i;
|
unsigned short i;
|
||||||
|
|
||||||
@ -524,7 +524,7 @@ overwrite_query_dialog (file_op_context_t * ctx, enum OperationMode mode)
|
|||||||
vfs_path_free (p);
|
vfs_path_free (p);
|
||||||
g_free (s1);
|
g_free (s1);
|
||||||
/* new file size */
|
/* 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_LABEL (2, s2);
|
||||||
/* new file modification date & time */
|
/* new file modification date & time */
|
||||||
s1 = (char *) file_date (ui->src_stat->st_mtime);
|
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);
|
vfs_path_free (p);
|
||||||
g_free (s1);
|
g_free (s1);
|
||||||
/* existing file size */
|
/* 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);
|
NEW_LABEL (6, s2);
|
||||||
/* existing file modification date & time */
|
/* existing file modification date & time */
|
||||||
s1 = (char *) file_date (ui->dst_stat->st_mtime);
|
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)
|
uintmax_t copied_bytes, gboolean show_summary)
|
||||||
{
|
{
|
||||||
char buffer[BUF_TINY];
|
char buffer[BUF_TINY];
|
||||||
char buffer2[BUF_TINY];
|
|
||||||
char buffer3[BUF_TINY];
|
|
||||||
file_op_context_ui_t *ui;
|
file_op_context_ui_t *ui;
|
||||||
|
|
||||||
if (ctx == NULL || ctx->ui == NULL)
|
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)
|
if (ui->time_label != NULL)
|
||||||
{
|
{
|
||||||
struct timeval tv_current;
|
struct timeval tv_current;
|
||||||
char buffer4[BUF_TINY];
|
char buffer2[BUF_TINY], buffer3[BUF_TINY];
|
||||||
|
|
||||||
gettimeofday (&tv_current, NULL);
|
gettimeofday (&tv_current, NULL);
|
||||||
file_frmt_time (buffer2, tv_current.tv_sec - tctx->transfer_start.tv_sec);
|
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);
|
g_snprintf (buffer, sizeof (buffer), _("Time: %s %s"), buffer2, buffer3);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char buffer4[BUF_TINY];
|
||||||
|
|
||||||
file_bps_prepare_for_show (buffer4, (long) tctx->bps);
|
file_bps_prepare_for_show (buffer4, (long) tctx->bps);
|
||||||
g_snprintf (buffer, sizeof (buffer), _("Time: %s %s (%s)"), buffer2, buffer3,
|
g_snprintf (buffer, sizeof (buffer), _("Time: %s %s (%s)"), buffer2, buffer3,
|
||||||
buffer4);
|
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);
|
g_snprintf (buffer, sizeof (buffer), _("Time: %s"), buffer2);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
file_bps_prepare_for_show (buffer4, (long) tctx->bps);
|
file_bps_prepare_for_show (buffer3, (long) tctx->bps);
|
||||||
g_snprintf (buffer, sizeof (buffer), _("Time: %s (%s)"), buffer2, buffer4);
|
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)
|
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)
|
if (!ctx->progress_totals_computed)
|
||||||
g_snprintf (buffer, sizeof (buffer), _(" Total: %s "), buffer2);
|
g_snprintf (buffer, sizeof (buffer), _(" Total: %s "), buffer2);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_trunc_len (buffer3, 5, ctx->progress_bytes, 0, panels_options.kilobyte_si);
|
char *b2;
|
||||||
g_snprintf (buffer, sizeof (buffer), _(" Total: %s/%s "), buffer2, buffer3);
|
|
||||||
|
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);
|
hline_set_text (ui->total_bytes_label, buffer);
|
||||||
|
@ -176,13 +176,16 @@ info_show_info (WInfo * info)
|
|||||||
tty_print_string (_("No space information"));
|
tty_print_string (_("No space information"));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char buffer1[6], buffer2[6];
|
char *buffer1;
|
||||||
|
const char *buffer2;
|
||||||
|
|
||||||
size_trunc_len (buffer1, 5, myfs_stats.avail, 1, panels_options.kilobyte_si);
|
buffer1 =
|
||||||
size_trunc_len (buffer2, 5, myfs_stats.total, 1, panels_options.kilobyte_si);
|
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,
|
tty_printf (_("Free space: %s/%s (%d%%)"), buffer1, buffer2,
|
||||||
myfs_stats.total == 0 ? 0 :
|
myfs_stats.total == 0 ? 0 :
|
||||||
(int) (100 * (long double) myfs_stats.avail / myfs_stats.total));
|
(int) (100 * (long double) myfs_stats.avail / myfs_stats.total));
|
||||||
|
g_free (buffer1);
|
||||||
}
|
}
|
||||||
MC_FALLTHROUGH;
|
MC_FALLTHROUGH;
|
||||||
case 14:
|
case 14:
|
||||||
@ -236,8 +239,9 @@ info_show_info (WInfo * info)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
char buffer[10];
|
const char *buffer;
|
||||||
size_trunc_len (buffer, 9, st.st_size, 0, panels_options.kilobyte_si);
|
|
||||||
|
buffer = size_trunc_len (9, st.st_size, 0, panels_options.kilobyte_si);
|
||||||
tty_printf (_("Size: %s"), buffer);
|
tty_printf (_("Size: %s"), buffer);
|
||||||
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
|
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
|
||||||
tty_printf (ngettext (" (%lu block)", " (%lu 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
|
#ifdef HAVE_STRUCT_STAT_ST_RDEV
|
||||||
if (S_ISBLK (fe->st.st_mode) || S_ISCHR (fe->st.st_mode))
|
if (S_ISBLK (fe->st.st_mode) || S_ISCHR (fe->st.st_mode))
|
||||||
|
{
|
||||||
format_device_number (buffer, len + 1, fe->st.st_rdev);
|
format_device_number (buffer, len + 1, fe->st.st_rdev);
|
||||||
else
|
return buffer;
|
||||||
|
}
|
||||||
#endif
|
#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)
|
if (myfs_stats.avail != 0 || myfs_stats.total != 0)
|
||||||
{
|
{
|
||||||
const Widget *w = CONST_WIDGET (panel);
|
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,
|
buffer1 = g_strdup (size_trunc_len (5, myfs_stats.avail, 1, panels_options.kilobyte_si));
|
||||||
panels_options.kilobyte_si);
|
buffer2 = size_trunc_len (5, myfs_stats.total, 1, panels_options.kilobyte_si);
|
||||||
size_trunc_len (buffer2, sizeof (buffer2) - 1, myfs_stats.total, 1,
|
|
||||||
panels_options.kilobyte_si);
|
|
||||||
g_snprintf (tmp, sizeof (tmp), " %s/%s (%d%%) ", buffer1, buffer2,
|
g_snprintf (tmp, sizeof (tmp), " %s/%s (%d%%) ", buffer1, buffer2,
|
||||||
myfs_stats.total == 0 ? 0 :
|
myfs_stats.total == 0 ? 0 :
|
||||||
(int) (100 * (long double) myfs_stats.avail / myfs_stats.total));
|
(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));
|
widget_move (w, w->lines - 1, w->cols - 2 - (int) strlen (tmp));
|
||||||
tty_setcolor (NORMAL_COLOR);
|
tty_setcolor (NORMAL_COLOR);
|
||||||
tty_print_string (tmp);
|
tty_print_string (tmp);
|
||||||
|
@ -169,12 +169,13 @@ mcview_display_status (WView * view)
|
|||||||
tty_printf ("0x%08" PRIxMAX, (uintmax_t) view->hex_cursor);
|
tty_printf ("0x%08" PRIxMAX, (uintmax_t) view->hex_cursor);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char buffer[BUF_TRUNC_LEN + 1];
|
const char *buffer;
|
||||||
|
|
||||||
size_trunc_len (buffer, BUF_TRUNC_LEN, mcview_get_filesize (view), 0,
|
buffer =
|
||||||
panels_options.kilobyte_si);
|
size_trunc_len (BUF_TRUNC_LEN, mcview_get_filesize (view), 0,
|
||||||
tty_printf ("%9" PRIuMAX "/%s%s %s", (uintmax_t) view->dpy_end,
|
panels_options.kilobyte_si);
|
||||||
buffer, mcview_may_still_grow (view) ? "+" : " ",
|
tty_printf ("%9" PRIuMAX "/%s%s %s", (uintmax_t) view->dpy_end, buffer,
|
||||||
|
mcview_may_still_grow (view) ? "+" : " ",
|
||||||
#ifdef HAVE_CHARSET
|
#ifdef HAVE_CHARSET
|
||||||
mc_global.source_codepage >= 0 ?
|
mc_global.source_codepage >= 0 ?
|
||||||
get_codepage_id (mc_global.source_codepage) :
|
get_codepage_id (mc_global.source_codepage) :
|
||||||
|
Loading…
Reference in New Issue
Block a user