Merge pull request #1065 from jdmcbr/issue1035

Wrap OSRRelease in check for NULL (#1035)
This commit is contained in:
Sean Gillies 2017-07-11 14:38:11 +02:00 committed by GitHub
commit eae51454fe
6 changed files with 54 additions and 34 deletions

View File

@ -32,3 +32,4 @@ cdef class DatasetBase:
cdef const char *get_driver_name(GDALDriverH driver)
cdef OGRSpatialReferenceH _osr_from_crs(object crs) except NULL
cdef _safe_osr_release(OGRSpatialReferenceH srs)

View File

@ -236,7 +236,7 @@ cdef class DatasetBase(object):
crs[k] = v
CPLFree(proj)
OSRRelease(osr)
_safe_osr_release(osr)
return crs
else:
@ -905,8 +905,8 @@ def _transform(src_crs, dst_crs, xs, ys, zs):
CPLFree(x)
CPLFree(y)
CPLFree(z)
OSRRelease(src)
OSRRelease(dst)
_safe_osr_release(src)
_safe_osr_release(dst)
return retval
@ -931,7 +931,7 @@ cdef OGRSpatialReferenceH _osr_from_crs(object crs) except NULL:
auth, val = init.split(':')
if not val:
OSRRelease(osr)
_safe_osr_release(osr)
raise CRSError("Invalid CRS: {!r}".format(crs))
if auth.upper() == 'EPSG':
@ -952,12 +952,20 @@ cdef OGRSpatialReferenceH _osr_from_crs(object crs) except NULL:
log.debug("OSRSetFromUserInput return value: %s", retval)
if retval:
OSRRelease(osr)
_safe_osr_release(osr)
raise CRSError("Invalid CRS: {!r}".format(crs))
return osr
cdef _safe_osr_release(OGRSpatialReferenceH srs):
"""Wrapper to handle OSR release when NULL."""
if srs != NULL:
OSRRelease(srs)
srs = NULL
def _can_create_osr(crs):
"""Evaluate if a valid OGRSpatialReference can be created from crs.
@ -990,5 +998,5 @@ def _can_create_osr(crs):
return False
finally:
OSRRelease(osr)
_safe_osr_release(osr)
CPLFree(wkt)

View File

@ -10,6 +10,7 @@ from rasterio.compat import string_types
from rasterio.errors import CRSError
from rasterio._base cimport _osr_from_crs as osr_from_crs
from rasterio._base cimport _safe_osr_release
log = logging.getLogger(__name__)
@ -28,7 +29,7 @@ class _CRS(UserDict):
retval = OSRIsGeographic(osr_crs)
return bool(retval == 1)
finally:
OSRRelease(osr_crs)
_safe_osr_release(osr_crs)
@property
def is_projected(self):
@ -40,7 +41,7 @@ class _CRS(UserDict):
retval = OSRIsProjected(osr_crs)
return bool(retval == 1)
finally:
OSRRelease(osr_crs)
_safe_osr_release(osr_crs)
def __eq__(self, other):
cdef OGRSpatialReferenceH osr_crs1 = NULL
@ -56,8 +57,8 @@ class _CRS(UserDict):
retval = OSRIsSame(osr_crs1, osr_crs2)
return bool(retval == 1)
finally:
OSRRelease(osr_crs1)
OSRRelease(osr_crs2)
_safe_osr_release(osr_crs1)
_safe_osr_release(osr_crs2)
@property
def wkt(self):
@ -73,7 +74,7 @@ class _CRS(UserDict):
return srcwkt.decode('utf-8')
finally:
CPLFree(srcwkt)
OSRRelease(osr)
_safe_osr_release(osr)
@classmethod
def from_wkt(cls, wkt):
@ -105,4 +106,4 @@ class _CRS(UserDict):
return cls.from_string(proj4.decode('utf-8'))
finally:
CPLFree(proj4)
OSRRelease(osr)
_safe_osr_release(osr)

View File

@ -33,7 +33,8 @@ from rasterio.windows import Window, intersection
from libc.stdio cimport FILE
cimport numpy as np
from rasterio._base cimport _osr_from_crs, get_driver_name, DatasetBase
from rasterio._base cimport (
_osr_from_crs, _safe_osr_release, get_driver_name, DatasetBase)
from rasterio._err cimport exc_wrap_int, exc_wrap_pointer, exc_wrap_vsilfile
from rasterio._shim cimport (
delete_nodata_value, io_band, io_multi_band, io_multi_mask)
@ -103,7 +104,7 @@ cdef class DatasetReaderBase(DatasetBase):
out : numpy ndarray, optional
As with Numpy ufuncs, this is an optional reference to an
output array into which data will be placed. If the height
and width of `out` differ from that of the specified
and width of `out` differ from that of the specified
window (see below), the raster image will be decimated or
replicated using the specified resampling method (also see
below).
@ -1136,7 +1137,7 @@ cdef class DatasetWriterBase(DatasetReaderBase):
GDALSetProjection(self._hds, wkt)
CPLFree(wkt)
OSRRelease(osr)
_safe_osr_release(osr)
self._crs = crs
log.debug("Self CRS: %r", self._crs)
@ -1635,7 +1636,7 @@ cdef class InMemoryRaster:
GDALSetProjection(self._hds, srcwkt)
log.debug("Set CRS on temp source dataset: %s", srcwkt)
CPLFree(<void *>srcwkt)
OSRRelease(osr)
_safe_osr_release(osr)
elif gcps and crs:
gcplist = <GDAL_GCP *>CPLMalloc(len(gcps) * sizeof(GDAL_GCP))

View File

@ -20,7 +20,7 @@ from rasterio.vfs import parse_path, vsi_path
cimport numpy as np
from rasterio._base cimport _osr_from_crs, get_driver_name
from rasterio._base cimport _osr_from_crs, get_driver_name, _safe_osr_release
from rasterio._err cimport exc_wrap_pointer, exc_wrap_int
from rasterio._io cimport (
DatasetReaderBase, InMemoryRaster, in_dtype_range, io_auto)
@ -57,8 +57,8 @@ def _transform_geom(
try:
transform = exc_wrap_pointer(OCTNewCoordinateTransformation(src, dst))
except:
OSRRelease(src)
OSRRelease(dst)
_safe_osr_release(src)
_safe_osr_release(dst)
raise
# Transform options.
@ -92,8 +92,8 @@ def _transform_geom(
OCTDestroyCoordinateTransformation(transform)
if options != NULL:
CSLDestroy(options)
OSRRelease(src)
OSRRelease(dst)
_safe_osr_release(src)
_safe_osr_release(dst)
cdef GDALWarpOptions * create_warp_options(
@ -325,16 +325,15 @@ def _reproject(
log.debug("Set transform on temp source dataset: %d", retval)
try:
osr = _osr_from_crs(src_crs)
OSRExportToWkt(osr, &srcwkt)
src_osr = _osr_from_crs(src_crs)
OSRExportToWkt(src_osr, &srcwkt)
GDALSetProjection(src_dataset, srcwkt)
log.debug("Set CRS on temp source dataset: %s", srcwkt)
finally:
CPLFree(srcwkt)
OSRRelease(osr)
osr = NULL
_safe_osr_release(src_osr)
elif gcps:
gcplist = <GDAL_GCP *>CPLMalloc(len(gcps) * sizeof(GDAL_GCP))
@ -415,8 +414,8 @@ def _reproject(
"Failed to set transform on temp destination dataset.")
try:
osr = _osr_from_crs(dst_crs)
OSRExportToWkt(osr, &dstwkt)
dst_osr = _osr_from_crs(dst_crs)
OSRExportToWkt(dst_osr, &dstwkt)
log.debug("CRS for temp destination dataset: %s.", dstwkt)
@ -425,8 +424,7 @@ def _reproject(
raise ("Failed to set projection on temp destination dataset.")
finally:
CPLFree(dstwkt)
OSRRelease(osr)
osr = NULL
_safe_osr_release(dst_osr)
retval = io_auto(destination, dst_dataset, 1)
@ -585,8 +583,7 @@ def _calculate_default_transform(src_crs, dst_crs, width, height,
osr = _osr_from_crs(dst_crs)
OSRExportToWkt(osr, &wkt)
OSRRelease(osr)
osr = NULL
_safe_osr_release(osr)
with InMemoryRaster(width=width, height=height, transform=transform,
gcps=gcps, crs=src_crs) as temp:
@ -700,9 +697,7 @@ cdef class WarpedVRTReaderBase(DatasetReaderBase):
osr = _osr_from_crs(self.dst_crs)
OSRExportToWkt(osr, &dst_crs_wkt)
finally:
if osr != NULL:
OSRRelease(osr)
osr = NULL
_safe_osr_release(osr)
log.debug("Exported CRS to WKT.")

View File

@ -230,6 +230,20 @@ def test_crs_OSR_no_equivalence():
assert crs1 != crs2
def test_safe_osr_release(tmpdir):
log = logging.getLogger('rasterio._gdal')
log.setLevel(logging.DEBUG)
logfile = str(tmpdir.join('test.log'))
fh = logging.FileHandler(logfile)
log.addHandler(fh)
with rasterio.Env():
CRS({}) == CRS({})
log = open(logfile).read()
assert "Pointer 'hSRS' is NULL in 'OSRRelease'" not in log
def test_from_wkt():
wgs84 = CRS.from_string('+proj=longlat +datum=WGS84 +no_defs')
from_wkt = CRS.from_wkt(wgs84.wkt)