summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2023-01-03 22:19:20 +0100
committerTor Egge <Tor.Egge@online.no>2023-01-03 22:19:20 +0100
commitff711e87548ab5da97d11219c9b27c40aa9e650c (patch)
tree0cd06132aef200c29b596e25063fdb4f24d543f8 /vespalib
parent76cd523c8377c24029c3eac337be5e6a72176d07 (diff)
Avoid integer overflows for geo fencing.
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/vespa/vespalib/geo/zcurve.cpp15
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();