diff options
author | Tor Egge <Tor.Egge@online.no> | 2023-01-03 22:19:20 +0100 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2023-01-03 22:19:20 +0100 |
commit | ff711e87548ab5da97d11219c9b27c40aa9e650c (patch) | |
tree | 0cd06132aef200c29b596e25063fdb4f24d543f8 /vespalib | |
parent | 76cd523c8377c24029c3eac337be5e6a72176d07 (diff) |
Avoid integer overflows for geo fencing.
Diffstat (limited to 'vespalib')
-rw-r--r-- | vespalib/src/vespa/vespalib/geo/zcurve.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/vespalib/src/vespa/vespalib/geo/zcurve.cpp b/vespalib/src/vespa/vespalib/geo/zcurve.cpp index 3bd68857154..c207f966704 100644 --- a/vespalib/src/vespa/vespalib/geo/zcurve.cpp +++ b/vespalib/src/vespa/vespalib/geo/zcurve.cpp @@ -3,6 +3,8 @@ #include <vespa/vespalib/geo/zcurve.h> #include <vespa/vespalib/util/priority_queue.h> #include <vespa/vespalib/util/fiddle.h> +#include <algorithm> +#include <limits> namespace vespalib::geo { @@ -30,7 +32,7 @@ public: int64_t total_estimate() const { return _total_estimate; } void put(Area area) { - _total_estimate += area.estimate(); + _total_estimate += std::min(area.estimate(), std::numeric_limits<int64_t>::max() - _total_estimate); _queue.push(std::move(area)); } @@ -130,8 +132,15 @@ ZCurve::RangeVector ZCurve::find_ranges(int min_x, int min_y, int max_x, int max_y) { - int64_t total_size = ((static_cast<int64_t>(max_x) - min_x + 1) * (static_cast<int64_t>(max_y) - min_y + 1)); - int64_t estimate_target = (total_size * 4); + uint64_t x_size = (static_cast<int64_t>(max_x) - min_x + 1); + uint64_t y_size = (static_cast<int64_t>(max_y) - min_y + 1); + uint64_t total_size = (x_size > std::numeric_limits<uint32_t>::max() && + y_size > std::numeric_limits<uint32_t>::max()) ? + std::numeric_limits<uint64_t>::max() : + (x_size * y_size); + int64_t estimate_target = (total_size > std::numeric_limits<int64_t>::max() / 4) ? + std::numeric_limits<int64_t>::max() : + (total_size * 4); ZAreaSplitter splitter(min_x, min_y, max_x, max_y); while (splitter.total_estimate() > estimate_target && splitter.num_ranges() < 42) { splitter.split_worst(); |