Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[core] Fix int overflow issue in GridIndex #15245

Merged
merged 2 commits into from
Jul 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions src/mbgl/util/grid_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ namespace mbgl {


template <class T>
GridIndex<T>::GridIndex(const float width_, const float height_, const int16_t cellSize_) :
GridIndex<T>::GridIndex(const float width_, const float height_, const uint32_t cellSize_) :
width(width_),
height(height_),
xCellCount(std::ceil(width_ / cellSize_)),
yCellCount(std::ceil(height_ / cellSize_)),
xScale(xCellCount / width_),
yScale(yCellCount / height_)
xCellCount(std::ceil(width / cellSize_)),
yCellCount(std::ceil(height / cellSize_)),
xScale(xCellCount / width),
yScale(yCellCount / height)
{
assert(width > 0.0f);
assert(height > 0.0f);
boxCells.resize(xCellCount * yCellCount);
circleCells.resize(xCellCount * yCellCount);
}
Expand All @@ -30,7 +32,7 @@ void GridIndex<T>::insert(T&& t, const BBox& bbox) {
auto cx2 = convertToXCellCoord(bbox.max.x);
auto cy2 = convertToYCellCoord(bbox.max.y);

int16_t x, y, cellIndex;
std::size_t x, y, cellIndex;
for (x = cx1; x <= cx2; ++x) {
for (y = cy1; y <= cy2; ++y) {
cellIndex = xCellCount * y + x;
Expand All @@ -50,7 +52,7 @@ void GridIndex<T>::insert(T&& t, const BCircle& bcircle) {
auto cx2 = convertToXCellCoord(bcircle.center.x + bcircle.radius);
auto cy2 = convertToYCellCoord(bcircle.center.y + bcircle.radius);

int16_t x, y, cellIndex;
std::size_t x, y, cellIndex;
for (x = cx1; x <= cx2; ++x) {
for (y = cy1; y <= cy2; ++y) {
cellIndex = xCellCount * y + x;
Expand Down Expand Up @@ -151,7 +153,7 @@ void GridIndex<T>::query(const BBox& queryBBox, std::function<bool (const T&, co
auto cx2 = convertToXCellCoord(queryBBox.max.x);
auto cy2 = convertToYCellCoord(queryBBox.max.y);

int16_t x, y, cellIndex;
std::size_t x, y, cellIndex;
for (x = cx1; x <= cx2; ++x) {
for (y = cy1; y <= cy2; ++y) {
cellIndex = xCellCount * y + x;
Expand Down Expand Up @@ -214,7 +216,7 @@ void GridIndex<T>::query(const BCircle& queryBCircle, std::function<bool (const
auto cx2 = convertToXCellCoord(queryBCircle.center.x + queryBCircle.radius);
auto cy2 = convertToYCellCoord(queryBCircle.center.y + queryBCircle.radius);

int16_t x, y, cellIndex;
std::size_t x, y, cellIndex;
for (x = cx1; x <= cx2; ++x) {
for (y = cy1; y <= cy2; ++y) {
cellIndex = xCellCount * y + x;
Expand Down Expand Up @@ -252,12 +254,12 @@ void GridIndex<T>::query(const BCircle& queryBCircle, std::function<bool (const
}

template <class T>
int16_t GridIndex<T>::convertToXCellCoord(const float x) const {
std::size_t GridIndex<T>::convertToXCellCoord(const float x) const {
return util::max(0.0, util::min(xCellCount - 1.0, std::floor(x * xScale)));
}

template <class T>
int16_t GridIndex<T>::convertToYCellCoord(const float y) const {
std::size_t GridIndex<T>::convertToYCellCoord(const float y) const {
return util::max(0.0, util::min(yCellCount - 1.0, std::floor(y * yScale)));
}

Expand Down
10 changes: 5 additions & 5 deletions src/mbgl/util/grid_index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ template <class T>
class GridIndex {
public:

GridIndex(const float width_, const float height_, const int16_t cellSize_);
GridIndex(const float width_, const float height_, const uint32_t cellSize_);

using BBox = mapbox::geometry::box<float>;
using BCircle = geometry::circle<float>;
Expand All @@ -81,8 +81,8 @@ class GridIndex {
void query(const BBox&, std::function<bool (const T&, const BBox&)>) const;
void query(const BCircle&, std::function<bool (const T&, const BBox&)>) const;

int16_t convertToXCellCoord(const float x) const;
int16_t convertToYCellCoord(const float y) const;
std::size_t convertToXCellCoord(const float x) const;
std::size_t convertToYCellCoord(const float y) const;

bool boxesCollide(const BBox&, const BBox&) const;
bool circlesCollide(const BCircle&, const BCircle&) const;
Expand All @@ -91,8 +91,8 @@ class GridIndex {
const float width;
const float height;

const int16_t xCellCount;
const int16_t yCellCount;
const std::size_t xCellCount;
const std::size_t yCellCount;
const double xScale;
const double yScale;

Expand Down
5 changes: 5 additions & 0 deletions test/util/grid_index.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,8 @@ TEST(GridIndex, CircleBox) {
EXPECT_EQ(grid.query({{0, 80}, {20, 100}}), (std::vector<int16_t>{2}));
}

TEST(GridIndex, IndexesFeaturesOverflow) {
GridIndex<int16_t> grid(5000, 5000, 25);
grid.insert(0, {{4500, 4500}, {4900, 4900}});
EXPECT_EQ(grid.query({{4000, 4000}, {5000, 5000}}), (std::vector<int16_t>{0}));
}