diff --git a/src/apps/testapps/testPolygonToCells.c b/src/apps/testapps/testPolygonToCells.c index 74abff9b7..0ed6ab97d 100644 --- a/src/apps/testapps/testPolygonToCells.c +++ b/src/apps/testapps/testPolygonToCells.c @@ -75,6 +75,15 @@ static LatLng lineVerts[] = {{0, 0}, {1, 0}}; static GeoLoop lineGeoLoop = {.numVerts = 2, .verts = lineVerts}; static GeoPolygon lineGeoPolygon; +static LatLng polarBandVerts[] = { + {85 * M_PI / 180, 0}, + {85 * M_PI / 180, 179 * M_PI / 180}, + {89.9 * M_PI / 180, 179 * M_PI / 180}, + {89.9 * M_PI / 180, 0}, +}; +static GeoLoop polarBandGeoLoop = {.numVerts = 4, .verts = polarBandVerts}; +static GeoPolygon polarBandGeoPolygon; + /** * Return true if the cell crosses the meridian. */ @@ -179,6 +188,9 @@ SUITE(polygonToCells) { invalidHoleGeoPolygon.numHoles = 1; invalidHoleGeoPolygon.holes = &invalidHoleGeoLoop; + polarBandGeoPolygon.geoloop = polarBandGeoLoop; + polarBandGeoPolygon.numHoles = 0; + // -------------------------------------------- // maxPolygonToCellsSize // -------------------------------------------- @@ -273,6 +285,20 @@ SUITE(polygonToCells) { free(hexagons); } + TEST(polygonToCells_polarBand) { + // Exercise a misestimation in bboxHexEstimate + int64_t numHexagons; + t_assertSuccess(H3_EXPORT(maxPolygonToCellsSize)(&polarBandGeoPolygon, + 9, 0, &numHexagons)); + H3Index *hexagons = calloc(numHexagons, sizeof(H3Index)); + + t_assert(H3_EXPORT(polygonToCells)(&polarBandGeoPolygon, 9, 0, + hexagons) == E_FAILED, + "polar band mis-estimates the number of cells"); + + free(hexagons); + } + TEST(polygonToCellsExact) { LatLng somewhere = {1, 2}; H3Index origin; diff --git a/src/apps/testapps/testPolygonToCellsExperimental.c b/src/apps/testapps/testPolygonToCellsExperimental.c index 371629d4e..6d7d31075 100644 --- a/src/apps/testapps/testPolygonToCellsExperimental.c +++ b/src/apps/testapps/testPolygonToCellsExperimental.c @@ -71,6 +71,15 @@ static LatLng lineVerts[] = {{0.6595072188743, -2.1371053983433}, static GeoLoop lineGeoLoop = {.numVerts = 2, .verts = lineVerts}; static GeoPolygon lineGeoPolygon; +static LatLng polarBandVerts[] = { + {85 * M_PI / 180, 0}, + {85 * M_PI / 180, 179 * M_PI / 180}, + {89.9 * M_PI / 180, 179 * M_PI / 180}, + {89.9 * M_PI / 180, 0}, +}; +static GeoLoop polarBandGeoLoop = {.numVerts = 4, .verts = polarBandVerts}; +static GeoPolygon polarBandGeoPolygon; + static GeoPolygon nullHoleGeoPolygon; static GeoPolygon pointHoleGeoPolygon; static GeoPolygon lineHoleGeoPolygon; @@ -191,6 +200,9 @@ SUITE(polygonToCells) { lineGeoPolygon.geoloop = lineGeoLoop; lineGeoPolygon.numHoles = 0; + polarBandGeoPolygon.geoloop = polarBandGeoLoop; + polarBandGeoPolygon.numHoles = 0; + TEST(polygonToCells_ZeroSize) { t_assert(H3_EXPORT(polygonToCellsExperimental)(&sfGeoPolygon, 9, CONTAINMENT_CENTER, 0, @@ -377,6 +389,24 @@ SUITE(polygonToCells) { free(hexagons); } + TEST(polygonToCells_polarBand) { + // Exercise a misestimation in bboxHexEstimate + int64_t numHexagons; + t_assertSuccess(H3_EXPORT(maxPolygonToCellsSizeExperimental)( + &polarBandGeoPolygon, 9, CONTAINMENT_CENTER, &numHexagons)); + H3Index *hexagons = calloc(numHexagons, sizeof(H3Index)); + + t_assertSuccess(H3_EXPORT(polygonToCellsExperimental)( + &polarBandGeoPolygon, 9, CONTAINMENT_CENTER, numHexagons, + hexagons)); + int64_t actualNumIndexes = countNonNullIndexes(hexagons, numHexagons); + + t_assert(actualNumIndexes == 4171389, + "got expected polygonToCells size"); + + free(hexagons); + } + TEST(polygonToCellsContainsPolygon) { int64_t numHexagons; t_assertSuccess(H3_EXPORT(maxPolygonToCellsSizeExperimental)( diff --git a/src/h3lib/lib/algos.c b/src/h3lib/lib/algos.c index cec4de741..22ae6df61 100644 --- a/src/h3lib/lib/algos.c +++ b/src/h3lib/lib/algos.c @@ -1109,7 +1109,6 @@ H3Error H3_EXPORT(polygonToCells)(const GeoPolygon *geoPolygon, int res, // If this branch is reached, we have exceeded the maximum // number of hexagons possible and need to clean up the // allocated memory. - // TODO: Reachable via fuzzer if (loopCount > numHexagons) { H3_MEMORY(free)(search); H3_MEMORY(free)(found);