mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 13:43:47 +01:00
Add a signal-safe decimal formatting function
This commit is contained in:
parent
8f0755fa85
commit
5343ee1a06
@ -3441,6 +3441,39 @@ format_hex_number_sigsafe(unsigned int x, char *buf, int buf_len)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** As format_hex_number_sigsafe, but format the number in base 10. */
|
||||||
|
int
|
||||||
|
format_dec_number_sigsafe(unsigned long x, char *buf, int buf_len)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
unsigned long tmp;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
tmp = x;
|
||||||
|
len = 1;
|
||||||
|
while (tmp > 9) {
|
||||||
|
tmp /= 10;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len >= buf_len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cp = buf + len;
|
||||||
|
*cp = '\0';
|
||||||
|
do {
|
||||||
|
unsigned digit = x % 10;
|
||||||
|
tor_assert(cp > buf);
|
||||||
|
--cp;
|
||||||
|
*cp = '0' + digit;
|
||||||
|
x /= 10;
|
||||||
|
} while (x);
|
||||||
|
|
||||||
|
tor_assert(cp == buf);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/** Format <b>child_state</b> and <b>saved_errno</b> as a hex string placed in
|
/** Format <b>child_state</b> and <b>saved_errno</b> as a hex string placed in
|
||||||
* <b>hex_errno</b>. Called between fork and _exit, so must be signal-handler
|
* <b>hex_errno</b>. Called between fork and _exit, so must be signal-handler
|
||||||
|
@ -520,6 +520,7 @@ int32_t tor_weak_random_range(tor_weak_rng_t *rng, int32_t top);
|
|||||||
#define tor_weak_random_one_in_n(rng, n) (0==tor_weak_random_range((rng),(n)))
|
#define tor_weak_random_one_in_n(rng, n) (0==tor_weak_random_range((rng),(n)))
|
||||||
|
|
||||||
int format_hex_number_sigsafe(unsigned int x, char *buf, int max_len);
|
int format_hex_number_sigsafe(unsigned int x, char *buf, int max_len);
|
||||||
|
int format_dec_number_sigsafe(unsigned long x, char *buf, int max_len);
|
||||||
|
|
||||||
#ifdef UTIL_PRIVATE
|
#ifdef UTIL_PRIVATE
|
||||||
/* Prototypes for private functions only used by util.c (and unit tests) */
|
/* Prototypes for private functions only used by util.c (and unit tests) */
|
||||||
|
@ -2670,6 +2670,56 @@ test_util_format_hex_number(void *ptr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for format_hex_number_sigsafe()
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_util_format_dec_number(void *ptr)
|
||||||
|
{
|
||||||
|
int i, len;
|
||||||
|
char buf[33];
|
||||||
|
const struct {
|
||||||
|
const char *str;
|
||||||
|
unsigned int x;
|
||||||
|
} test_data[] = {
|
||||||
|
{"0", 0},
|
||||||
|
{"1", 1},
|
||||||
|
{"1234", 1234},
|
||||||
|
{"12345678", 12345678},
|
||||||
|
{"99999999", 99999999},
|
||||||
|
{"100000000", 100000000},
|
||||||
|
{"4294967295", 4294967295u},
|
||||||
|
#if UINT_MAX > 0xffffffff
|
||||||
|
{"18446744073709551615", 18446744073709551615u },
|
||||||
|
#endif
|
||||||
|
{NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
(void)ptr;
|
||||||
|
|
||||||
|
for (i = 0; test_data[i].str != NULL; ++i) {
|
||||||
|
len = format_dec_number_sigsafe(test_data[i].x, buf, sizeof(buf));
|
||||||
|
test_neq(len, 0);
|
||||||
|
test_eq(len, strlen(buf));
|
||||||
|
test_streq(buf, test_data[i].str);
|
||||||
|
|
||||||
|
len = format_dec_number_sigsafe(test_data[i].x, buf,
|
||||||
|
(int)(strlen(test_data[i].str) + 1));
|
||||||
|
test_eq(len, strlen(buf));
|
||||||
|
test_streq(buf, test_data[i].str);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_eq(4, format_dec_number_sigsafe(7331, buf, 5));
|
||||||
|
test_streq(buf, "7331");
|
||||||
|
test_eq(0, format_dec_number_sigsafe(7331, buf, 4));
|
||||||
|
test_eq(1, format_dec_number_sigsafe(0, buf, 2));
|
||||||
|
test_eq(0, format_dec_number_sigsafe(0, buf, 1));
|
||||||
|
|
||||||
|
done:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that we can properly format a Windows command line
|
* Test that we can properly format a Windows command line
|
||||||
*/
|
*/
|
||||||
@ -3362,6 +3412,7 @@ struct testcase_t util_tests[] = {
|
|||||||
UTIL_TEST(spawn_background_fail, 0),
|
UTIL_TEST(spawn_background_fail, 0),
|
||||||
UTIL_TEST(spawn_background_partial_read, 0),
|
UTIL_TEST(spawn_background_partial_read, 0),
|
||||||
UTIL_TEST(format_hex_number, 0),
|
UTIL_TEST(format_hex_number, 0),
|
||||||
|
UTIL_TEST(format_dec_number, 0),
|
||||||
UTIL_TEST(join_win_cmdline, 0),
|
UTIL_TEST(join_win_cmdline, 0),
|
||||||
UTIL_TEST(split_lines, 0),
|
UTIL_TEST(split_lines, 0),
|
||||||
UTIL_TEST(n_bits_set, 0),
|
UTIL_TEST(n_bits_set, 0),
|
||||||
|
Loading…
Reference in New Issue
Block a user