[tor-commits] [tor/master] Refactor format_*_number_sigsafe to have a common implementation
nickm at torproject.org
nickm at torproject.org
Mon Nov 18 16:04:37 UTC 2013
commit c2dfae78d3a881af7cfe2fb4a79da7e3598788fc
Author: Nick Mathewson <nickm at torproject.org>
Date: Fri Oct 18 10:37:23 2013 -0700
Refactor format_*_number_sigsafe to have a common implementation
---
src/common/util.c | 113 +++++++++++++++++++++++------------------------------
src/common/util.h | 2 +-
2 files changed, 49 insertions(+), 66 deletions(-)
diff --git a/src/common/util.c b/src/common/util.c
index bbb6044..cb23e7e 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -3396,6 +3396,51 @@ tor_join_win_cmdline(const char *argv[])
return joined_argv;
}
+/* As format_{hex,dex}_number_sigsafe, but takes a <b>radix</b> argument
+ * in range 2..16 inclusive. */
+static int
+format_number_sigsafe(unsigned long x, char *buf, int buf_len,
+ unsigned int radix)
+{
+ unsigned long tmp;
+ int len;
+ char *cp;
+
+ /* NOT tor_assert. This needs to be safe to run from within a signal handler,
+ * and from within the 'tor_assert() has failed' code. */
+ if (radix < 2 || radix > 16)
+ return 0;
+
+ /* Count how many digits we need. */
+ tmp = x;
+ len = 1;
+ while (tmp >= radix) {
+ tmp /= radix;
+ ++len;
+ }
+
+ /* Not long enough */
+ if (!buf || len >= buf_len)
+ return 0;
+
+ cp = buf + len;
+ *cp = '\0';
+ do {
+ unsigned digit = x % radix;
+ tor_assert(cp > buf);
+ --cp;
+ *cp = "0123456789ABCDEF"[digit];
+ x /= radix;
+ } while (x);
+
+ /* NOT tor_assert; see above. */
+ if (cp != buf) {
+ abort();
+ }
+
+ return len;
+}
+
/**
* Helper function to output hex numbers from within a signal handler.
*
@@ -3418,78 +3463,16 @@ tor_join_win_cmdline(const char *argv[])
* arbitrary C functions.
*/
int
-format_hex_number_sigsafe(unsigned int x, char *buf, int buf_len)
+format_hex_number_sigsafe(unsigned long x, char *buf, int buf_len)
{
- int len;
- unsigned int tmp;
- char *cur;
-
- /* Sanity check */
- if (!buf || buf_len <= 1)
- return 0;
-
- /* How many chars do we need for x? */
- if (x > 0) {
- len = 0;
- tmp = x;
- while (tmp > 0) {
- tmp >>= 4;
- ++len;
- }
- } else {
- len = 1;
- }
-
- /* Bail if we would go past the end of the buffer */
- if (len+1 > buf_len)
- return 0;
-
- /* Point to last one */
- cur = buf + len - 1;
-
- /* Convert x to hex */
- do {
- *cur-- = "0123456789ABCDEF"[x & 0xf];
- x >>= 4;
- } while (x != 0 && cur >= buf);
-
- buf[len] = '\0';
-
- /* Return len */
- return len;
+ return format_number_sigsafe(x, buf, buf_len, 16);
}
/** 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;
+ return format_number_sigsafe(x, buf, buf_len, 10);
}
#ifndef _WIN32
diff --git a/src/common/util.h b/src/common/util.h
index 1c92c4f..37effa2 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -519,7 +519,7 @@ int32_t tor_weak_random_range(tor_weak_rng_t *rng, int32_t top);
* <b>n</b> */
#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 long x, char *buf, int max_len);
int format_dec_number_sigsafe(unsigned long x, char *buf, int max_len);
#ifdef UTIL_PRIVATE
More information about the tor-commits
mailing list