[tor-commits] [tor/master] Add a signal-safe decimal formatting function

nickm at torproject.org nickm at torproject.org
Mon Nov 18 16:04:36 UTC 2013


commit 5343ee1a06ebb959fc77753898015186b94a5daa
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Jul 19 13:03:23 2013 -0400

    Add a signal-safe decimal formatting function
---
 src/common/util.c    |   33 ++++++++++++++++++++++++++++++++
 src/common/util.h    |    1 +
 src/test/test_util.c |   51 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+)

diff --git a/src/common/util.c b/src/common/util.c
index 0e8d34e..25ea133 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -3441,6 +3441,39 @@ format_hex_number_sigsafe(unsigned int x, char *buf, int buf_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
 /** 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
diff --git a/src/common/util.h b/src/common/util.h
index 0a8e4a2..f6d8287 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -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)))
 
 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
 /* Prototypes for private functions only used by util.c (and unit tests) */
diff --git a/src/test/test_util.c b/src/test/test_util.c
index f7513c0..b331a80 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -2671,6 +2671,56 @@ test_util_format_hex_number(void *ptr)
 }
 
 /**
+ * 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
  */
 static void
@@ -3362,6 +3412,7 @@ struct testcase_t util_tests[] = {
   UTIL_TEST(spawn_background_fail, 0),
   UTIL_TEST(spawn_background_partial_read, 0),
   UTIL_TEST(format_hex_number, 0),
+  UTIL_TEST(format_dec_number, 0),
   UTIL_TEST(join_win_cmdline, 0),
   UTIL_TEST(split_lines, 0),
   UTIL_TEST(n_bits_set, 0),





More information about the tor-commits mailing list