[tor-commits] [tor/master] Avoid divide by zero and NaNs in scale_array_elements_to_u64
nickm at torproject.org
nickm at torproject.org
Thu Sep 11 04:15:43 UTC 2014
commit 59f9a5c78695213442599e8f2e8a535e8a9cc666
Author: Nick Mathewson <nickm at torproject.org>
Date: Wed Sep 10 23:59:21 2014 -0400
Avoid divide by zero and NaNs in scale_array_elements_to_u64
Patch from teor; part of 13104
---
src/or/routerlist.c | 5 +++--
src/test/test_dir.c | 27 +++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 32cbe19..0df411b 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1802,7 +1802,7 @@ scale_array_elements_to_u64(u64_dbl_t *entries, int n_entries,
uint64_t *total_out)
{
double total = 0.0;
- double scale_factor;
+ double scale_factor = 0.0;
int i;
/* big, but far away from overflowing an int64_t */
#define SCALE_TO_U64_MAX (INT64_MAX / 4)
@@ -1810,7 +1810,8 @@ scale_array_elements_to_u64(u64_dbl_t *entries, int n_entries,
for (i = 0; i < n_entries; ++i)
total += entries[i].dbl;
- scale_factor = SCALE_TO_U64_MAX / total;
+ if (total > 0.0)
+ scale_factor = SCALE_TO_U64_MAX / total;
for (i = 0; i < n_entries; ++i)
entries[i].u64 = tor_llround(entries[i].dbl * scale_factor);
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index c03b63b..1b56bcd 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -1749,10 +1749,37 @@ test_dir_scale_bw(void *testdata)
tt_assert(total <= (U64_LITERAL(1)<<62));
for (i=0; i<8; ++i) {
+ /* vals[2].u64 is the scaled value of 1.0 */
double ratio = ((double)vals[i].u64) / vals[2].u64;
tt_double_op(fabs(ratio - v[i]), <, .00001);
}
+ /* test handling of no entries */
+ total = 1;
+ scale_array_elements_to_u64(vals, 0, &total);
+ tt_assert(total == 0);
+
+ /* make sure we don't read the array when we have no entries
+ * may require compiler flags to catch NULL dereferences */
+ total = 1;
+ scale_array_elements_to_u64(NULL, 0, &total);
+ tt_assert(total == 0);
+
+ scale_array_elements_to_u64(NULL, 0, NULL);
+
+ /* test handling of zero totals */
+ total = 1;
+ vals[0].dbl = 0.0;
+ scale_array_elements_to_u64(vals, 1, &total);
+ tt_assert(total == 0);
+ tt_assert(vals[0].u64 == 0);
+
+ vals[0].dbl = 0.0;
+ vals[1].dbl = 0.0;
+ scale_array_elements_to_u64(vals, 2, NULL);
+ tt_assert(vals[0].u64 == 0);
+ tt_assert(vals[1].u64 == 0);
+
done:
;
}
More information about the tor-commits
mailing list