Ticket #13104: 03-scale-array-arith-undef.patch

File 03-scale-array-arith-undef.patch, 2.0 KB (added by teor, 5 years ago)

Avoid divide by zero and NaNs in scale_array_elements_to_u64

  • src/or/routerlist.c

    diff --git a/src/or/routerlist.c b/src/or/routerlist.c
    index 14451c0..8ed9f03 100644
    a b scale_array_elements_to_u64(u64_dbl_t *entries, int n_entries, 
    18061806                            uint64_t *total_out)
    18071807{
    18081808  double total = 0.0;
    1809   double scale_factor;
     1809  double scale_factor = 0.0;
    18101810  int i;
    18111811  /* big, but far away from overflowing an int64_t */
    18121812#define SCALE_TO_U64_MAX ((int64_t) (INT64_MAX / 4))
    scale_array_elements_to_u64(u64_dbl_t *entries, int n_entries, 
    18141814  for (i = 0; i < n_entries; ++i)
    18151815    total += entries[i].dbl;
    18161816
    1817   scale_factor = SCALE_TO_U64_MAX / total;
     1817  if (total > 0.0)
     1818    scale_factor = SCALE_TO_U64_MAX / total;
    18181819
    18191820  for (i = 0; i < n_entries; ++i)
    18201821    entries[i].u64 = tor_llround(entries[i].dbl * scale_factor);
  • src/test/test_dir.c

    diff --git a/src/test/test_dir.c b/src/test/test_dir.c
    index 71b474d..035f241 100644
    a b test_dir_scale_bw(void *testdata) 
    17331733  tt_assert(total <= (U64_LITERAL(1)<<62));
    17341734
    17351735  for (i=0; i<8; ++i) {
     1736    /* vals[2].u64 is the scaled value of 1.0 */
    17361737    double ratio = ((double)vals[i].u64) / vals[2].u64;
    17371738    tt_double_op(fabs(ratio - v[i]), <, .00001);
    17381739  }
    17391740
     1741  /* test handling of no entries */
     1742  total = 1;
     1743  scale_array_elements_to_u64(vals, 0, &total);
     1744  tt_assert(total == 0);
     1745
     1746  /* make sure we don't read the array when we have no entries
     1747   * may require compiler flags to catch NULL dereferences */
     1748  total = 1;
     1749  scale_array_elements_to_u64(NULL, 0, &total);
     1750  tt_assert(total == 0);
     1751
     1752  scale_array_elements_to_u64(NULL, 0, NULL);
     1753
     1754  /* test handling of zero totals */
     1755  total = 1;
     1756  vals[0].dbl = 0.0;
     1757  scale_array_elements_to_u64(vals, 1, &total);
     1758  tt_assert(total == 0);
     1759  tt_assert(vals[0].u64 == 0);
     1760
     1761  vals[0].dbl = 0.0;
     1762  vals[1].dbl = 0.0;
     1763  scale_array_elements_to_u64(vals, 2, NULL);
     1764  tt_assert(vals[0].u64 == 0);
     1765  tt_assert(vals[1].u64 == 0);
     1766
    17401767 done:
    17411768  ;
    17421769}