Skip to content

Commit b0844ad

Browse files
authored
Python bindings: fix use-after-free on sub-geometries of a feature's geometry (#15355)
* Python bindings: fix use-after-free on sub-geometries after their parent is freed * autotest: test sub-geometries after their parent is freed
1 parent 0d57017 commit b0844ad

2 files changed

Lines changed: 37 additions & 0 deletions

File tree

‎autotest/ogr/ogr_basic_test.py‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,37 @@ def test_geom_use_after_feature_delete_2(arg_type):
12361236
geom.ExportToWkt()
12371237

12381238

1239+
def test_subgeom_use_after_feature_delete():
1240+
1241+
feat = ogr.Feature(ogr.FeatureDefn())
1242+
feat.SetGeometry(ogr.CreateGeometryFromWkt("MULTIPOLYGON (((0 0,0 1,1 1,0 0)))"))
1243+
poly = feat.GetGeometryRef().GetGeometryRef(0)
1244+
ring = poly.GetGeometryRef(0)
1245+
1246+
del feat
1247+
1248+
with pytest.raises(Exception):
1249+
poly.ExportToWkt()
1250+
1251+
with pytest.raises(Exception):
1252+
ring.GetPointCount()
1253+
1254+
1255+
def test_subgeom_use_after_geom_destroy():
1256+
1257+
geom = ogr.CreateGeometryFromWkt("MULTIPOLYGON (((0 0,0 1,1 1,0 0)))")
1258+
poly = geom.GetGeometryRef(0)
1259+
ring = poly.GetGeometryRef(0)
1260+
1261+
geom.Destroy()
1262+
1263+
with pytest.raises(Exception):
1264+
poly.ExportToWkt()
1265+
1266+
with pytest.raises(Exception):
1267+
ring.GetPointCount()
1268+
1269+
12391270
def test_geom_use_after_transfer_to_feature_1(tmp_vsimem):
12401271

12411272
ds = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource(tmp_vsimem / "test.shp")

‎swig/include/python/ogr_python.i‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,7 @@ def _WarnIfUserHasNotSpecifiedIfUsingExceptions():
857857
def _invalidate_geom_refs(self):
858858
if hasattr(self, '_geom_references'):
859859
for geom in self._geom_references:
860+
geom._invalidate_geom_refs()
860861
geom.this = None
861862

862863
%}
@@ -994,9 +995,13 @@ def _WarnIfUserHasNotSpecifiedIfUsingExceptions():
994995
%extend OGRGeometryShadow {
995996
%pythoncode %{
996997
def Destroy(self):
998+
self._invalidate_geom_refs()
997999
self.__swig_destroy__(self)
9981000
self.thisown = 0
9991001

1002+
_add_geom_ref = Feature._add_geom_ref
1003+
_invalidate_geom_refs = Feature._invalidate_geom_refs
1004+
10001005
def __str__(self):
10011006
return self.ExportToIsoWkt()
10021007

@@ -1025,6 +1030,7 @@ def _WarnIfUserHasNotSpecifiedIfUsingExceptions():
10251030
%feature("pythonappend") GetGeometryRef %{
10261031
if val is not None:
10271032
val._parent_geom = self
1033+
self._add_geom_ref(val)
10281034
%}
10291035

10301036
}

0 commit comments

Comments
 (0)