BLI: Prevent Overflow in Grouped Number Output #105263
|
@ -3706,8 +3706,8 @@ void BKE_ptcache_update_info(PTCacheID *pid)
|
|||
}
|
||||
else {
|
||||
PTCacheMem *pm = cache->mem_cache.first;
|
||||
char formatted_tot[16];
|
||||
char formatted_mem[15];
|
||||
char formatted_tot[BLI_STR_FORMAT_INT32_GROUPED_SIZE];
|
||||
char formatted_mem[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE];
|
||||
long long int bytes = 0.0f;
|
||||
int i;
|
||||
|
||||
|
|
|
@ -310,7 +310,7 @@ class HashTableStats {
|
|||
std::cout << " Removed Slots: " << removed_amount_ << " (" << removed_load_factor_ * 100.0f
|
||||
<< " %)\n";
|
||||
|
||||
char memory_size_str[15];
|
||||
char memory_size_str[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE];
|
||||
BLI_str_format_byte_unit(memory_size_str, size_in_bytes_, true);
|
||||
std::cout << " Size: ~" << memory_size_str << "\n";
|
||||
std::cout << " Size per Slot: " << size_per_element_ << " bytes\n";
|
||||
|
|
|
@ -17,6 +17,22 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Buffer size of maximum `uint64` plus commas and terminator. */
|
||||
#define BLI_STR_FORMAT_UINT64_GROUPED_SIZE 27
|
||||
|
||||
/* Buffer size of maximum `int32` with commas and terminator. */
|
||||
#define BLI_STR_FORMAT_INT32_GROUPED_SIZE 16
|
||||
|
||||
/* Buffer size of maximum `int64` formatted as byte size (with GiB for example). */
|
||||
#define BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE 15
|
||||
|
||||
/* Buffer size of maximum `int32` formatted as compact decimal size ("15.6M" for example). */
|
||||
#define BLI_STR_FORMAT_INT32_DECIMAL_UNIT_SIZE 7
|
||||
|
||||
/* Buffer size of maximum `int32` formatted as very short decimal size ("15B" for example). */
|
||||
#define BLI_STR_FORMAT_INT32_INTEGER_UNIT_SIZE 5
|
||||
Harley marked this conversation as resolved
|
||||
|
||||
/**
|
||||
* Duplicates the first \a len bytes of cstring \a str
|
||||
* into a newly mallocN'd string and returns it. \a str
|
||||
|
@ -276,7 +292,8 @@ const char *BLI_str_escape_find_quote(const char *str) ATTR_NONNULL();
|
|||
* \param num: Number to format
|
||||
* \return The length of \a dst
|
||||
*/
|
||||
size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL();
|
||||
size_t BLI_str_format_int_grouped(char dst[BLI_STR_FORMAT_INT32_GROUPED_SIZE], int num)
|
||||
ATTR_NONNULL();
|
||||
/**
|
||||
* Format uint64_t with decimal grouping.
|
||||
* 1000 -> 1,000
|
||||
|
@ -285,7 +302,8 @@ size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL();
|
|||
* \param num: Number to format
|
||||
* \return The length of \a dst
|
||||
*/
|
||||
size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num) ATTR_NONNULL();
|
||||
size_t BLI_str_format_uint64_grouped(char dst[BLI_STR_FORMAT_UINT64_GROUPED_SIZE], uint64_t num)
|
||||
ATTR_NONNULL();
|
||||
/**
|
||||
* Format a size in bytes using binary units.
|
||||
* 1000 -> 1 KB
|
||||
|
@ -296,7 +314,9 @@ size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num) ATTR_NONNULL();
|
|||
* \param bytes: Number to format.
|
||||
* \param base_10: Calculate using base 10 (GB, MB, ...) or 2 (GiB, MiB, ...).
|
||||
*/
|
||||
void BLI_str_format_byte_unit(char dst[15], long long int bytes, bool base_10) ATTR_NONNULL();
|
||||
void BLI_str_format_byte_unit(char dst[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE],
|
||||
long long int bytes,
|
||||
bool base_10) ATTR_NONNULL();
|
||||
/**
|
||||
* Format a count to up to 6 places (plus '\0' terminator) string using long number
|
||||
* names abbreviations. Used to produce a compact representation of large numbers.
|
||||
|
@ -315,7 +335,8 @@ void BLI_str_format_byte_unit(char dst[15], long long int bytes, bool base_10) A
|
|||
*
|
||||
* Length of 7 is the maximum of the resulting string, for example, `-15.5K\0`.
|
||||
*/
|
||||
void BLI_str_format_decimal_unit(char dst[7], int number_to_format) ATTR_NONNULL();
|
||||
void BLI_str_format_decimal_unit(char dst[BLI_STR_FORMAT_INT32_DECIMAL_UNIT_SIZE],
|
||||
int number_to_format) ATTR_NONNULL();
|
||||
/**
|
||||
* Format a count to up to 3 places (plus minus sign, plus '\0' terminator) string using long
|
||||
* number names abbreviations. Used to produce a compact representation of large numbers as
|
||||
|
@ -337,7 +358,8 @@ void BLI_str_format_decimal_unit(char dst[7], int number_to_format) ATTR_NONNULL
|
|||
*
|
||||
* Length of 5 is the maximum of the resulting string, for example, `-15K\0`.
|
||||
*/
|
||||
void BLI_str_format_integer_unit(char dst[5], int number_to_format) ATTR_NONNULL();
|
||||
void BLI_str_format_integer_unit(char dst[BLI_STR_FORMAT_INT32_INTEGER_UNIT_SIZE],
|
||||
int number_to_format) ATTR_NONNULL();
|
||||
/**
|
||||
* Compare two strings without regard to case.
|
||||
*
|
||||
|
|
|
@ -974,7 +974,7 @@ class Vector {
|
|||
std::cout << " Capacity: " << (capacity_end_ - begin_) << "\n";
|
||||
std::cout << " Inline Capacity: " << InlineBufferCapacity << "\n";
|
||||
|
||||
char memory_size_str[15];
|
||||
char memory_size_str[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE];
|
||||
BLI_str_format_byte_unit(memory_size_str, sizeof(*this), true);
|
||||
std::cout << " Size on Stack: " << memory_size_str << "\n";
|
||||
}
|
||||
|
|
|
@ -1098,7 +1098,7 @@ int BLI_string_find_split_words(
|
|||
/** \name String Formatting (Numeric)
|
||||
* \{ */
|
||||
|
||||
static size_t BLI_str_format_int_grouped_ex(char src[16], char dst[16], int num_len)
|
||||
static size_t BLI_str_format_int_grouped_ex(char *src, char *dst, int num_len)
|
||||
{
|
||||
char *p_src = src;
|
||||
char *p_dst = dst;
|
||||
|
@ -1122,25 +1122,25 @@ static size_t BLI_str_format_int_grouped_ex(char src[16], char dst[16], int num_
|
|||
return (size_t)(p_dst - dst);
|
||||
}
|
||||
|
||||
size_t BLI_str_format_int_grouped(char dst[16], int num)
|
||||
size_t BLI_str_format_int_grouped(char dst[BLI_STR_FORMAT_INT32_GROUPED_SIZE], int num)
|
||||
{
|
||||
char src[16];
|
||||
char src[BLI_STR_FORMAT_INT32_GROUPED_SIZE];
|
||||
const int num_len = BLI_snprintf(src, sizeof(src), "%d", num);
|
||||
|
||||
return BLI_str_format_int_grouped_ex(src, dst, num_len);
|
||||
}
|
||||
|
||||
size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num)
|
||||
size_t BLI_str_format_uint64_grouped(char dst[BLI_STR_FORMAT_UINT64_GROUPED_SIZE], uint64_t num)
|
||||
{
|
||||
/* NOTE: Buffer to hold maximum `uint64`, which is 1.8e+19. but
|
||||
* we also need space for commas and null-terminator. */
|
||||
char src[27];
|
||||
char src[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
const int num_len = BLI_snprintf(src, sizeof(src), "%" PRIu64 "", num);
|
||||
|
||||
return BLI_str_format_int_grouped_ex(src, dst, num_len);
|
||||
}
|
||||
|
||||
void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base_10)
|
||||
void BLI_str_format_byte_unit(char dst[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE],
|
||||
long long int bytes,
|
||||
const bool base_10)
|
||||
{
|
||||
double bytes_converted = bytes;
|
||||
int order = 0;
|
||||
|
@ -1159,14 +1159,15 @@ void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base
|
|||
decimals = MAX2(order - 1, 0);
|
||||
|
||||
/* Format value first, stripping away floating zeroes. */
|
||||
const size_t dst_len = 15;
|
||||
const size_t dst_len = BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE;
|
||||
size_t len = BLI_snprintf_rlen(dst, dst_len, "%.*f", decimals, bytes_converted);
|
||||
len -= (size_t)BLI_str_rstrip_float_zero(dst, '\0');
|
||||
dst[len++] = ' ';
|
||||
BLI_strncpy(dst + len, base_10 ? units_base_10[order] : units_base_2[order], dst_len - len);
|
||||
}
|
||||
|
||||
void BLI_str_format_decimal_unit(char dst[7], int number_to_format)
|
||||
void BLI_str_format_decimal_unit(char dst[BLI_STR_FORMAT_INT32_DECIMAL_UNIT_SIZE],
|
||||
int number_to_format)
|
||||
{
|
||||
float number_to_format_converted = number_to_format;
|
||||
int order = 0;
|
||||
|
@ -1179,7 +1180,7 @@ void BLI_str_format_decimal_unit(char dst[7], int number_to_format)
|
|||
order++;
|
||||
}
|
||||
|
||||
const size_t dst_len = 7;
|
||||
const size_t dst_len = BLI_STR_FORMAT_INT32_DECIMAL_UNIT_SIZE;
|
||||
int decimals = 0;
|
||||
if ((order > 0) && fabsf(number_to_format_converted) < 100.0f) {
|
||||
decimals = 1;
|
||||
|
@ -1187,7 +1188,8 @@ void BLI_str_format_decimal_unit(char dst[7], int number_to_format)
|
|||
BLI_snprintf(dst, dst_len, "%.*f%s", decimals, number_to_format_converted, units[order]);
|
||||
}
|
||||
|
||||
void BLI_str_format_integer_unit(char dst[5], const int number_to_format)
|
||||
void BLI_str_format_integer_unit(char dst[BLI_STR_FORMAT_INT32_INTEGER_UNIT_SIZE],
|
||||
const int number_to_format)
|
||||
{
|
||||
float number_to_format_converted = number_to_format;
|
||||
int order = 0;
|
||||
|
@ -1207,7 +1209,7 @@ void BLI_str_format_integer_unit(char dst[5], const int number_to_format)
|
|||
order++;
|
||||
}
|
||||
|
||||
const size_t dst_len = 5;
|
||||
const size_t dst_len = BLI_STR_FORMAT_INT32_INTEGER_UNIT_SIZE;
|
||||
BLI_snprintf(dst,
|
||||
dst_len,
|
||||
"%s%s%d%s",
|
||||
|
|
|
@ -324,7 +324,7 @@ TEST(string, StrPartitionExUtf8)
|
|||
/* BLI_str_format_int_grouped */
|
||||
TEST(string, StrFormatIntGrouped)
|
||||
{
|
||||
char number_str[16];
|
||||
char number_str[BLI_STR_FORMAT_INT32_GROUPED_SIZE];
|
||||
int number;
|
||||
|
||||
BLI_str_format_int_grouped(number_str, number = 0);
|
||||
|
@ -355,10 +355,32 @@ TEST(string, StrFormatIntGrouped)
|
|||
EXPECT_STREQ("-999", number_str);
|
||||
}
|
||||
|
||||
/* BLI_str_format_uint64_grouped */
|
||||
TEST(string, StrFormatUint64Grouped)
|
||||
{
|
||||
char number_str[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
uint64_t number;
|
||||
|
||||
BLI_str_format_uint64_grouped(number_str, number = 0);
|
||||
EXPECT_STREQ("0", number_str);
|
||||
|
||||
BLI_str_format_uint64_grouped(number_str, number = 1);
|
||||
EXPECT_STREQ("1", number_str);
|
||||
|
||||
BLI_str_format_uint64_grouped(number_str, number = 999);
|
||||
EXPECT_STREQ("999", number_str);
|
||||
|
||||
BLI_str_format_uint64_grouped(number_str, number = 1000);
|
||||
EXPECT_STREQ("1,000", number_str);
|
||||
|
||||
BLI_str_format_uint64_grouped(number_str, number = 18446744073709551615);
|
||||
EXPECT_STREQ("18,446,744,073,709,551,615", number_str);
|
||||
}
|
||||
|
||||
/* BLI_str_format_byte_unit */
|
||||
TEST(string, StrFormatByteUnits)
|
||||
{
|
||||
char size_str[15];
|
||||
char size_str[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE];
|
||||
long long int size;
|
||||
|
||||
/* Base 10 */
|
||||
|
@ -423,7 +445,7 @@ TEST(string, StrFormatByteUnits)
|
|||
/* BLI_str_format_decimal_unit */
|
||||
TEST(string, StrFormatDecimalUnits)
|
||||
{
|
||||
char size_str[7];
|
||||
char size_str[BLI_STR_FORMAT_INT32_DECIMAL_UNIT_SIZE];
|
||||
int size;
|
||||
|
||||
BLI_str_format_decimal_unit(size_str, size = 0);
|
||||
|
@ -518,7 +540,7 @@ TEST(string, StrFormatDecimalUnits)
|
|||
/* BLI_str_format_integer_unit */
|
||||
TEST(string, StrFormatIntegerUnits)
|
||||
{
|
||||
char size_str[7];
|
||||
char size_str[BLI_STR_FORMAT_INT32_INTEGER_UNIT_SIZE];
|
||||
int size;
|
||||
|
||||
BLI_str_format_integer_unit(size_str, size = 0);
|
||||
|
|
|
@ -256,7 +256,7 @@ void EEVEE_lightcache_info_update(SceneEEVEE *eevee)
|
|||
return;
|
||||
}
|
||||
|
||||
char formatted_mem[15];
|
||||
char formatted_mem[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE];
|
||||
BLI_str_format_byte_unit(formatted_mem, eevee_lightcache_memsize_get(lcache), false);
|
||||
|
||||
int irr_samples = eevee_lightcache_irradiance_sample_count(lcache);
|
||||
|
|
|
@ -61,8 +61,6 @@
|
|||
|
||||
ENUM_OPERATORS(eUserpref_StatusBar_Flag, STATUSBAR_SHOW_VERSION)
|
||||
|
||||
#define MAX_INFO_NUM_LEN 16
|
||||
|
||||
struct SceneStats {
|
||||
uint64_t totvert, totvertsel, totvertsculpt;
|
||||
uint64_t totedge, totedgesel;
|
||||
|
@ -76,15 +74,19 @@ struct SceneStats {
|
|||
|
||||
struct SceneStatsFmt {
|
||||
/* Totals */
|
||||
char totvert[MAX_INFO_NUM_LEN], totvertsel[MAX_INFO_NUM_LEN], totvertsculpt[MAX_INFO_NUM_LEN];
|
||||
char totface[MAX_INFO_NUM_LEN], totfacesel[MAX_INFO_NUM_LEN];
|
||||
char totedge[MAX_INFO_NUM_LEN], totedgesel[MAX_INFO_NUM_LEN], totfacesculpt[MAX_INFO_NUM_LEN];
|
||||
char totbone[MAX_INFO_NUM_LEN], totbonesel[MAX_INFO_NUM_LEN];
|
||||
char totobj[MAX_INFO_NUM_LEN], totobjsel[MAX_INFO_NUM_LEN];
|
||||
char totlamp[MAX_INFO_NUM_LEN], totlampsel[MAX_INFO_NUM_LEN];
|
||||
char tottri[MAX_INFO_NUM_LEN];
|
||||
char totgplayer[MAX_INFO_NUM_LEN], totgpframe[MAX_INFO_NUM_LEN];
|
||||
char totgpstroke[MAX_INFO_NUM_LEN], totgppoint[MAX_INFO_NUM_LEN];
|
||||
char totvert[BLI_STR_FORMAT_UINT64_GROUPED_SIZE], totvertsel[BLI_STR_FORMAT_UINT64_GROUPED_SIZE],
|
||||
totvertsculpt[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
char totface[BLI_STR_FORMAT_UINT64_GROUPED_SIZE], totfacesel[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
char totedge[BLI_STR_FORMAT_UINT64_GROUPED_SIZE], totedgesel[BLI_STR_FORMAT_UINT64_GROUPED_SIZE],
|
||||
totfacesculpt[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
char totbone[BLI_STR_FORMAT_UINT64_GROUPED_SIZE], totbonesel[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
char totobj[BLI_STR_FORMAT_UINT64_GROUPED_SIZE], totobjsel[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
char totlamp[BLI_STR_FORMAT_UINT64_GROUPED_SIZE], totlampsel[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
char tottri[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
char totgplayer[BLI_STR_FORMAT_UINT64_GROUPED_SIZE],
|
||||
totgpframe[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
char totgpstroke[BLI_STR_FORMAT_UINT64_GROUPED_SIZE],
|
||||
totgppoint[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
|
||||
};
|
||||
|
||||
static bool stats_mesheval(const Mesh *me_eval, bool is_selected, SceneStats *stats)
|
||||
|
@ -599,7 +601,7 @@ static const char *info_statusbar_string(Main *bmain,
|
|||
ViewLayer *view_layer,
|
||||
char statusbar_flag)
|
||||
{
|
||||
char formatted_mem[15];
|
||||
char formatted_mem[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE];
|
||||
size_t ofs = 0;
|
||||
static char info[256];
|
||||
int len = sizeof(info);
|
||||
|
|
|
@ -913,7 +913,7 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn
|
|||
}
|
||||
|
||||
auto to_string = [](int value) {
|
||||
char str[16];
|
||||
char str[BLI_STR_FORMAT_INT32_GROUPED_SIZE];
|
||||
BLI_str_format_int_grouped(str, value);
|
||||
return std::string(str);
|
||||
};
|
||||
|
|
|
@ -1747,7 +1747,7 @@ static void outliner_draw_userbuts(uiBlock *block,
|
|||
uiBut *bt;
|
||||
ID *id = tselem->id;
|
||||
const char *tip = nullptr;
|
||||
char buf[16] = "";
|
||||
char buf[BLI_STR_FORMAT_INT32_GROUPED_SIZE] = "";
|
||||
int but_flag = UI_BUT_DRAG_LOCK;
|
||||
|
||||
if (ID_IS_LINKED(id)) {
|
||||
|
|
|
@ -571,11 +571,11 @@ static void spreadsheet_footer_region_draw(const bContext *C, ARegion *region)
|
|||
std::stringstream ss;
|
||||
ss << "Rows: ";
|
||||
if (runtime->visible_rows != runtime->tot_rows) {
|
||||
char visible_rows_str[16];
|
||||
char visible_rows_str[BLI_STR_FORMAT_INT32_GROUPED_SIZE];
|
||||
BLI_str_format_int_grouped(visible_rows_str, runtime->visible_rows);
|
||||
ss << visible_rows_str << " / ";
|
||||
}
|
||||
char tot_rows_str[16];
|
||||
char tot_rows_str[BLI_STR_FORMAT_INT32_GROUPED_SIZE];
|
||||
BLI_str_format_int_grouped(tot_rows_str, runtime->tot_rows);
|
||||
ss << tot_rows_str << " | Columns: " << runtime->tot_columns;
|
||||
std::string stats_str = ss.str();
|
||||
|
|
|
@ -143,7 +143,7 @@ void GeometryDataSetTreeViewItem::build_row(uiLayout &row)
|
|||
if (const std::optional<int> count = this->count()) {
|
||||
/* Using the tree row button instead of a separate right aligned button gives padding
|
||||
* to the right side of the number, which it didn't have with the button. */
|
||||
char element_count[7];
|
||||
char element_count[BLI_STR_FORMAT_INT32_DECIMAL_UNIT_SIZE];
|
||||
BLI_str_format_decimal_unit(element_count, *count);
|
||||
UI_but_hint_drawstr_set((uiBut *)this->view_item_button(), element_count);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Should be BLI_STR_FORMAT_INT32_INTEGER_UNIT_SIZE