diff --git a/src/iso19111/metadata.cpp b/src/iso19111/metadata.cpp index d648f83e04..1b4f499add 100644 --- a/src/iso19111/metadata.cpp +++ b/src/iso19111/metadata.cpp @@ -421,6 +421,13 @@ GeographicBoundingBox::Private::intersection(const Private &otherExtent) const { return nullptr; } + // Bail out on longitudes not in [-180,180]. We could probably make + // some sense of them, but this check at least avoid potential infinite + // recursion. + if (oW > 180 || oE < -180) { + return nullptr; + } + // Return larger of two parts of the multipolygon auto inter1 = intersection(Private(oW, oS, 180.0, oN)); auto inter2 = intersection(Private(-180.0, oS, oE, oN)); diff --git a/test/unit/test_metadata.cpp b/test/unit/test_metadata.cpp index d17c341733..64ddfab677 100644 --- a/test/unit/test_metadata.cpp +++ b/test/unit/test_metadata.cpp @@ -284,13 +284,15 @@ TEST(metadata, extent_edge_cases) { optional(), std::vector(), std::vector(), std::vector()); - auto A = Extent::createFromBBOX(-180, -90, 180, 90); - auto B = Extent::createFromBBOX(180, -90, 180, 90); - EXPECT_FALSE(A->intersects(B)); - EXPECT_FALSE(B->intersects(A)); - EXPECT_FALSE(A->contains(B)); - EXPECT_TRUE(A->intersection(B) == nullptr); - EXPECT_TRUE(B->intersection(A) == nullptr); + { + auto A = Extent::createFromBBOX(-180, -90, 180, 90); + auto B = Extent::createFromBBOX(180, -90, 180, 90); + EXPECT_FALSE(A->intersects(B)); + EXPECT_FALSE(B->intersects(A)); + EXPECT_FALSE(A->contains(B)); + EXPECT_TRUE(A->intersection(B) == nullptr); + EXPECT_TRUE(B->intersection(A) == nullptr); + } EXPECT_THROW(Extent::createFromBBOX( std::numeric_limits::quiet_NaN(), -90, 180, 90), @@ -304,6 +306,20 @@ TEST(metadata, extent_edge_cases) { EXPECT_THROW(Extent::createFromBBOX( -180, -90, 180, std::numeric_limits::quiet_NaN()), InvalidValueTypeException); + + // Scenario of https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=57328 + { + auto A = Extent::createFromBBOX(0, 1, 2, 3); + auto B = Extent::createFromBBOX(200, -80, -100, 80); + EXPECT_TRUE(A->intersection(B) == nullptr); + EXPECT_TRUE(B->intersection(A) == nullptr); + } + { + auto A = Extent::createFromBBOX(0, 1, 2, 3); + auto B = Extent::createFromBBOX(100, -80, -200, 80); + EXPECT_TRUE(A->intersection(B) == nullptr); + EXPECT_TRUE(B->intersection(A) == nullptr); + } } // ---------------------------------------------------------------------------