Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix segfault in SimplePointInAreaLocator caused by casting MultiPolyg… #334

Closed
wants to merge 1 commit into from

Conversation

sumeerbhola
Copy link
Contributor

@sumeerbhola sumeerbhola commented Sep 2, 2020

…on to Polygon

References https://trac.osgeo.org/geos/ticket/1047
References cockroachdb/cockroach#53254


This change is Reviewable

}
auto poly = dynamic_cast<const Polygon*>(geom->getGeometryN(0));
if (poly) {
return locatePointInPolygon(p, dynamic_cast<const Polygon*>(geom->getGeometryN(0)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe use poly as the second argument?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -111,5 +120,15 @@ void object::test<5>
"MULTIPOINT ((1 1), (0 0))");
}

// 6 - TestPointLocator Point inside GeometryCollection containing MultiPolygon, using SimplePointInAreaLocator.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe worth adding a clarification it is a single Polygon inside a MULTIPOLYGON

@dr-jts
Copy link
Contributor

dr-jts commented Sep 2, 2020

In JTS at least, spatial predicates do not support GEOMETRYCOLLECTIONs as inputs. So this is a case of erroneous input. But should not be allowed to cause a segfault, for sure.

@dr-jts
Copy link
Contributor

dr-jts commented Sep 2, 2020

The idea of generalizing SimplePointInAreaLocator to handle any kind of collection isn't a bad one. But the fact that this allows intersects to handle a geometry like

GEOMETRYCOLLECTION (MULTIPOLYGON (((9223372036854776000 -9223372036854776000, 9223372036854776000 9223372036854776000, -9223372036854776000 9223372036854776000, -9223372036854776000 9223372036854776000, 9223372036854776000 -9223372036854776000))))

(as per the original ticket GEOS-1047) is just a lucky accident. You should review your upstream code and ensure it meets the contract for GEOS spatial predicates.

@otan
Copy link
Contributor

otan commented Sep 2, 2020

You should review your upstream code and ensure it meets the contract for GEOS spatial predicates.

This is for a database (i.e. CockroachDB), where the users can specify the kinds of shapes coming in. We're just the messenger. This affects PostGIS as well (https://trac.osgeo.org/geos/ticket/1042).

We don't control the shapes; this was one we happened to bump into whilst randomized testing a variety of different unions that led to this shape. By chance, it also affects intersects.

However, the seg fault as it stands is definitely not a good situation for us as it is not easily recoverable.

@dr-jts
Copy link
Contributor

dr-jts commented Sep 2, 2020

I also note that the original CockroachDB issue involved computing an aggregate union of two geometry collections (one heterogeneous). This seems to be supported in PostGIS, but not sure how GEOS is being used to perform that.

@dr-jts
Copy link
Contributor

dr-jts commented Sep 2, 2020

You should review your upstream code and ensure it meets the contract for GEOS spatial predicates.

This is for a database (i.e. CockroachDB), where the users can specify the kinds of shapes coming in. We're just the messenger. This affects PostGIS as well (https://trac.osgeo.org/geos/ticket/1042).

We don't control the shapes; this was one we happened to bump into whilst randomized testing a variety of different unions that led to this shape. By chance, it also affects intersects.

However, the seg fault as it stands is definitely not a good situation for us as it is not easily recoverable.

If you're using a library, it's your responsibility to ensure that you are not providing inputs to the library which are out of contract for it.

As said, I agree that the lib should not segfault on bad inputs. But the answer is not necessarily to hack a "fix" deep inside the codebase with no knowledge of how that might affect other code in the library. The library should detect known situations which are not handled and report that via standard error mechanism.

@otan
Copy link
Contributor

otan commented Sep 2, 2020

As said, I agree that the lib should not segfault on bad inputs. But the answer is not necessarily to hack a "fix" deep inside the codebase with no knowledge of how that might affect other code in the library. The library should detect known situations which are not handled and report that via standard error mechanism.

It may be more helpful if you gave a pointer as to where / what layer you prefer changed in this situation.

It sounds like if you want GEOMETRYCOLLECTION spatial predicates to not work entirely, it will break existing cases. This seems like it already works with MULTIPOLYGON inside GEOMETRYCOLLECTION if the MULTIPOLYGON has >= 2 shapes within it. Sounds like that would break existing PostGIS cases as well?

edit: eh, this breaks PostGIS too (but seems like it may miss if you hit the PreparedIntersects path):

otan=# select st_intersects('01020000000200000000000000000000000000000000000000000000000000F03F0000000000000000', '0107000000010000000106000000010000000103000000010000000500000008690b3a70a9c347540a11d15993eec7e04b9e4d8fd2cb4702907c2929abe847d02aef5652e3cec72c1b57867da3dd47bbf47698d501eac7ccc0d287b380d44708690b3a70a9c347540a11d15993eec7');
server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.

@dr-jts
Copy link
Contributor

dr-jts commented Sep 2, 2020

It may be more helpful if you gave a pointer as to where / what layer you prefer changed in this situation.

I'm not sure at the moment. In JTS GeometryCollection input to predicates are simply disallowed. I'm not sure why this isn't implemented in GEOS.

It sounds like if you want GEOMETRYCOLLECTION spatial predicates to not work entirely, it will break existing cases. This seems like it already works with MULTIPOLYGON inside GEOMETRYCOLLECTION if the MULTIPOLYGON has >= 2 shapes within it. Sounds like that would break existing PostGIS cases as well?

Are there existing PostGIS unit tests that rely on this?

If a GC with a single MultiPolygon works, that is just a happy accident. But I suppose it could be made explicit behaviour. I'd prefer that was done more explicitly, however, not just as a lucky side-effect of a sub-module of the overlay algorithm. (I.e. explicitly code for unwrapping GCs containing a single element which is itself not a GC).

@dr-jts
Copy link
Contributor

dr-jts commented Sep 2, 2020

Whatever the way this is handled, there needs to be a unit test covering this case. Otherwise this risks a regression failure if and when the predicate code is modified or replaced.

@sumeerbhola
Copy link
Contributor Author

there needs to be a unit test covering this case

This PR includes a change to PointLocatorTest.cpp. Should there be more tests?

@dr-jts
Copy link
Contributor

dr-jts commented Sep 2, 2020

there needs to be a unit test covering this case

This PR includes a change to PointLocatorTest.cpp. Should there be more tests?

Yes, but perhaps they should not be part of this PR. If the ultimate goal is to have GEOS support GeometryCollection inputs to predicates (or overlay operations), then there needs to be tests at that level. As mentioned before, if there aren't unit tests at the level of the actual operation, then there is a risk of future development causing a regression.

This will need to be based on a decision by the GEOS team about how to handle this. Or not - currently GC inputs sometimes work, sometimes probably return the wrong answer, and sometimes cause topology exceptions. To my mind this means they basically aren't handled in a meaningful way.

@otan otan deleted the mpcast_master_fix branch September 8, 2020 15:13
@otan otan restored the mpcast_master_fix branch September 8, 2020 15:22
@strk
Copy link
Member

strk commented Nov 6, 2020

Thanks all, this was merged in master as 07e6046 - backports are in progress

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants