Refs #27472 -- Fixed crash during pickling of empty GEOS point.

This commit is contained in:
Sergey Fedoseev 2018-07-09 20:02:12 +05:00 committed by Tim Graham
parent bdcde79c5f
commit 3411c5551a
3 changed files with 16 additions and 3 deletions

View File

@ -87,15 +87,21 @@ class GEOSGeometryBase(GEOSBase):
return '<%s object at %s>' % (self.geom_type, hex(addressof(self.ptr))) return '<%s object at %s>' % (self.geom_type, hex(addressof(self.ptr)))
# Pickling support # Pickling support
def _to_pickle_wkb(self):
return bytes(self.wkb)
def _from_pickle_wkb(self, wkb):
return wkb_r().read(memoryview(wkb))
def __getstate__(self): def __getstate__(self):
# The pickled state is simply a tuple of the WKB (in string form) # The pickled state is simply a tuple of the WKB (in string form)
# and the SRID. # and the SRID.
return bytes(self.wkb), self.srid return self._to_pickle_wkb(), self.srid
def __setstate__(self, state): def __setstate__(self, state):
# Instantiating from the tuple state that was pickled. # Instantiating from the tuple state that was pickled.
wkb, srid = state wkb, srid = state
ptr = wkb_r().read(memoryview(wkb)) ptr = self._from_pickle_wkb(wkb)
if not ptr: if not ptr:
raise GEOSException('Invalid Geometry loaded from pickled state.') raise GEOSException('Invalid Geometry loaded from pickled state.')
self.ptr = ptr self.ptr = ptr

View File

@ -40,6 +40,12 @@ class Point(GEOSGeometry):
# createPoint factory. # createPoint factory.
super().__init__(point, srid=srid) super().__init__(point, srid=srid)
def _to_pickle_wkb(self):
return None if self.empty else super()._to_pickle_wkb()
def _from_pickle_wkb(self, wkb):
return self._create_empty() if wkb is None else super()._from_pickle_wkb(wkb)
def _ogr_ptr(self): def _ogr_ptr(self):
return gdal.geometries.Point._create_empty() if self.empty else super()._ogr_ptr() return gdal.geometries.Point._create_empty() if self.empty else super()._ogr_ptr()

View File

@ -1181,7 +1181,8 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
tgeoms.extend(get_geoms(self.geometries.multilinestrings, 4326)) tgeoms.extend(get_geoms(self.geometries.multilinestrings, 4326))
tgeoms.extend(get_geoms(self.geometries.polygons, 3084)) tgeoms.extend(get_geoms(self.geometries.polygons, 3084))
tgeoms.extend(get_geoms(self.geometries.multipolygons, 3857)) tgeoms.extend(get_geoms(self.geometries.multipolygons, 3857))
tgeoms.append(Point(srid=4326))
tgeoms.append(Point())
for geom in tgeoms: for geom in tgeoms:
s1 = pickle.dumps(geom) s1 = pickle.dumps(geom)
g1 = pickle.loads(s1) g1 = pickle.loads(s1)