commit c2dfae78d3a881af7cfe2fb4a79da7e3598788fc Author: Nick Mathewson nickm@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
tor-commits@lists.torproject.org