Skip to content

Commit

Permalink
Add test for cellsToLinkedMultipolygon leak (#673)
Browse files Browse the repository at this point in the history
* Add test for cellsToLinkedMultipolygon leak

* fix test
  • Loading branch information
isaacbrodsky authored Sep 6, 2022
1 parent 6931d36 commit befff57
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 42 deletions.
11 changes: 11 additions & 0 deletions src/apps/testapps/testCellsToLinkedMultiPolygon.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,4 +297,15 @@ SUITE(cellsToLinkedMultiPolygon) {

H3_EXPORT(destroyLinkedMultiPolygon)(&polygon);
}

TEST(specificLeak) {
// Test for a case where a leak can occur, detected by fuzzer.
// The leak detection part will be enforced here by valgrind.
LinkedGeoPolygon polygon;
H3Index set[] = {0xd60006d60000f100, 0x3c3c403c1300d668};
int numHexes = ARRAY_SIZE(set);
t_assert(H3_EXPORT(cellsToLinkedMultiPolygon)(set, numHexes,
&polygon) == E_FAILED,
"invalid cells fail");
}
}
36 changes: 9 additions & 27 deletions src/apps/testapps/testPolygon.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,7 @@ SUITE(polygon) {
LinkedGeoPolygon polygon = {0};
addLinkedLoop(&polygon, outer);

int result = normalizeMultiPolygon(&polygon);

t_assert(result == NORMALIZATION_SUCCESS, "No error code returned");
t_assertSuccess(normalizeMultiPolygon(&polygon));

t_assert(countLinkedPolygons(&polygon) == 1, "Polygon count correct");
t_assert(countLinkedLoops(&polygon) == 1, "Loop count correct");
Expand All @@ -383,9 +381,7 @@ SUITE(polygon) {
addLinkedLoop(&polygon, outer1);
addLinkedLoop(&polygon, outer2);

int result = normalizeMultiPolygon(&polygon);

t_assert(result == NORMALIZATION_SUCCESS, "No error code returned");
t_assertSuccess(normalizeMultiPolygon(&polygon));

t_assert(countLinkedPolygons(&polygon) == 2, "Polygon count correct");
t_assert(countLinkedLoops(&polygon) == 1,
Expand Down Expand Up @@ -413,9 +409,7 @@ SUITE(polygon) {
addLinkedLoop(&polygon, inner);
addLinkedLoop(&polygon, outer);

int result = normalizeMultiPolygon(&polygon);

t_assert(result == NORMALIZATION_SUCCESS, "No error code returned");
t_assertSuccess(normalizeMultiPolygon(&polygon));

t_assert(countLinkedPolygons(&polygon) == 1, "Polygon count correct");
t_assert(countLinkedLoops(&polygon) == 2,
Expand Down Expand Up @@ -450,9 +444,7 @@ SUITE(polygon) {
addLinkedLoop(&polygon, outer);
addLinkedLoop(&polygon, inner1);

int result = normalizeMultiPolygon(&polygon);

t_assert(result == NORMALIZATION_SUCCESS, "No error code returned");
t_assertSuccess(normalizeMultiPolygon(&polygon));

t_assert(countLinkedPolygons(&polygon) == 1,
"Polygon count correct for 2 holes");
Expand Down Expand Up @@ -490,9 +482,7 @@ SUITE(polygon) {
addLinkedLoop(&polygon, outer);
addLinkedLoop(&polygon, outer2);

int result = normalizeMultiPolygon(&polygon);

t_assert(result == NORMALIZATION_SUCCESS, "No error code returned");
t_assertSuccess(normalizeMultiPolygon(&polygon));

t_assert(countLinkedPolygons(&polygon) == 2, "Polygon count correct");
t_assert(countLinkedLoops(&polygon) == 2,
Expand Down Expand Up @@ -538,9 +528,7 @@ SUITE(polygon) {
addLinkedLoop(&polygon, innerBig);
addLinkedLoop(&polygon, outer);

int result = normalizeMultiPolygon(&polygon);

t_assert(result == NORMALIZATION_SUCCESS, "No error code returned");
t_assertSuccess(normalizeMultiPolygon(&polygon));

t_assert(countLinkedPolygons(&polygon) == 2, "Polygon count correct");
t_assert(countLinkedLoops(&polygon) == 2,
Expand Down Expand Up @@ -572,9 +560,7 @@ SUITE(polygon) {
addLinkedLoop(&polygon, outer1);
addLinkedLoop(&polygon, outer2);

int result = normalizeMultiPolygon(&polygon);

t_assert(result == NORMALIZATION_ERR_UNASSIGNED_HOLES,
t_assert(normalizeMultiPolygon(&polygon) == E_FAILED,
"Expected error code returned");

t_assert(countLinkedPolygons(&polygon) == 1, "Polygon count correct");
Expand Down Expand Up @@ -603,9 +589,7 @@ SUITE(polygon) {
addLinkedLoop(next, outer2);

// Should be a no-op
int result = normalizeMultiPolygon(&polygon);

t_assert(result == NORMALIZATION_ERR_MULTIPLE_POLYGONS,
t_assert(normalizeMultiPolygon(&polygon) == E_FAILED,
"Expected error code returned");

t_assert(countLinkedPolygons(&polygon) == 2, "Polygon count correct");
Expand Down Expand Up @@ -636,9 +620,7 @@ SUITE(polygon) {
addLinkedLoop(&polygon, inner);
addLinkedLoop(&polygon, outer);

int result = normalizeMultiPolygon(&polygon);

t_assert(result == NORMALIZATION_ERR_UNASSIGNED_HOLES,
t_assert(normalizeMultiPolygon(&polygon) == E_FAILED,
"Expected error code returned");

H3_EXPORT(destroyLinkedMultiPolygon)(&polygon);
Expand Down
7 changes: 1 addition & 6 deletions src/h3lib/include/linkedGeo.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@
#include "h3api.h"
#include "latLng.h"

// Error codes for normalizeMultiPolygon
#define NORMALIZATION_SUCCESS 0
#define NORMALIZATION_ERR_MULTIPLE_POLYGONS 1
#define NORMALIZATION_ERR_UNASSIGNED_HOLES 2

// Macros for use with polygonAlgos.h
/** Macro: Init iteration vars for LinkedGeoLoop */
#define INIT_ITERATION_LINKED_LOOP \
Expand All @@ -52,7 +47,7 @@
/** Macro: Whether a LinkedGeoLoop is empty */
#define IS_EMPTY_LINKED_LOOP(loop) loop->first == NULL

int normalizeMultiPolygon(LinkedGeoPolygon *root);
H3Error normalizeMultiPolygon(LinkedGeoPolygon *root);
LinkedGeoPolygon *addNewLinkedPolygon(LinkedGeoPolygon *polygon);
LinkedGeoLoop *addNewLinkedLoop(LinkedGeoPolygon *polygon);
LinkedGeoLoop *addLinkedLoop(LinkedGeoPolygon *polygon, LinkedGeoLoop *loop);
Expand Down
9 changes: 5 additions & 4 deletions src/h3lib/lib/algos.c
Original file line number Diff line number Diff line change
Expand Up @@ -1149,9 +1149,10 @@ H3Error H3_EXPORT(cellsToLinkedMultiPolygon)(const H3Index *h3Set,
return err;
}
_vertexGraphToLinkedGeo(&graph, out);
if (normalizeMultiPolygon(out)) {
return E_FAILED;
}
destroyVertexGraph(&graph);
return E_SUCCESS;
H3Error normalizeResult = normalizeMultiPolygon(out);
if (normalizeResult) {
H3_EXPORT(destroyLinkedMultiPolygon)(out);
}
return normalizeResult;
}
10 changes: 5 additions & 5 deletions src/h3lib/lib/linkedGeo.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,20 +290,20 @@ static const LinkedGeoPolygon *findPolygonForHole(
* @param root Root polygon including all loops
* @return 0 on success, or an error code > 0 for invalid input
*/
int normalizeMultiPolygon(LinkedGeoPolygon *root) {
H3Error normalizeMultiPolygon(LinkedGeoPolygon *root) {
// We assume that the input is a single polygon with loops;
// if it has multiple polygons, don't touch it
if (root->next) {
return NORMALIZATION_ERR_MULTIPLE_POLYGONS;
return E_FAILED;
}

// Count loops, exiting early if there's only one
int loopCount = countLinkedLoops(root);
if (loopCount <= 1) {
return NORMALIZATION_SUCCESS;
return E_SUCCESS;
}

int resultCode = NORMALIZATION_SUCCESS;
H3Error resultCode = E_SUCCESS;
LinkedGeoPolygon *polygon = NULL;
LinkedGeoLoop *next;
int innerCount = 0;
Expand Down Expand Up @@ -355,7 +355,7 @@ int normalizeMultiPolygon(LinkedGeoPolygon *root) {
// a way to destroy it with destroyLinkedMultiPolygon.
destroyLinkedGeoLoop(innerLoops[i]);
H3_MEMORY(free)(innerLoops[i]);
resultCode = NORMALIZATION_ERR_UNASSIGNED_HOLES;
resultCode = E_FAILED;
}
}

Expand Down

0 comments on commit befff57

Please sign in to comment.