[postgis-devel] [PostGIS] #1782: [raster] rtpg_getSR fails for any spatial reference system not in EPSG.
PostGIS
trac at osgeo.org
Wed Apr 18 12:00:50 PDT 2012
#1782: [raster] rtpg_getSR fails for any spatial reference system not in EPSG.
----------------------+-----------------------------------------------------
Reporter: kempisty | Owner: pracine
Type: defect | Status: new
Priority: medium | Milestone: PostGIS 2.0.1
Component: raster | Version: 2.0.x
Keywords: |
----------------------+-----------------------------------------------------
While trying to ST_Clip a raster against a geometry, using a custom
spatial reference system (I gave it an arbitrary srid of 40000), I
discovered that rtpg_getSR(int srid) fails for any reference system in
spatial_ref_sys that does not have EPSG as its auth name. It never
attempts to send the proj4text or srtext to GDAL.
Further, if you try to work around this by supplying a bogus 'EPSG' auth
name and auth_srid for the custom reference system, tuptable->vals[i]
goes out of bounds, segfaults, and brings down the postgres server.
In the code, the following query selects an EPSG id, a proj4text, and a
srtext from spatial_ref_sys. (aligned it a bit for reading)
{{{
snprintf(sql, len,
"SELECT
CASE
WHEN upper(auth_name) = 'EPSG' AND length(auth_srid::text) > 0
THEN upper(auth_name) || ':' || auth_srid
ELSE ''
END,
proj4text,
srtext
FROM spatial_ref_sys
WHERE srid = %d
LIMIT 1"
, srid);
spi_result = SPI_execute(sql, TRUE, 0);
}}}
If auth_name is not EPSG, then this first column of the return value will
be a zero length string.
Later...
{{{
tmp = SPI_getvalue(tuple, tupdesc, 1);
if (NULL == tmp || !strlen(tmp)) {
elog(ERROR, "rtpg_getSR: Cannot find SRID (%d) in
spatial_ref_sys.", srid);
if (SPI_tuptable) SPI_freetuptable(tuptable);
SPI_finish();
return NULL;
}
}}}
That code block sees the zero-length string in column 1 of the tuple
returned from spatial_ref_sys. The function errors and returns NULL
without ever trying to send proj4text or srtext to GDAL.
More bad things happen in the code around that check.
{{{
tupdesc = SPI_tuptable->tupdesc;
tuptable = SPI_tuptable;
/* which tuple to use? */
for (i = 0; i < 3; i++) {
tuple = tuptable->vals[i];
tmp = SPI_getvalue(tuple, tupdesc, 1);
if (NULL == tmp || !strlen(tmp)) {
elog(ERROR, "rtpg_getSR: Cannot find SRID (%d) in
spatial_ref_sys.", srid);
if (SPI_tuptable) SPI_freetuptable(tuptable);
SPI_finish();
return NULL;
}
}}}
If we give this function a bogus EPSG and auth_srid, such as auth_name =
'EPSG' and auth_srid=40000, GDAL throws an error -- as expected -- and
then we come back to the top for the second iteration through the FOR
loop. Presumably, we're going to now try the proj4text. That's when we
hit this:
{{{
/* which tuple to use? */
for (i = 0; i < 3; i++) {
tuple = tuptable->vals[i];
}}}
tuptable->vals has one array element for each row returned from our query.
The query returns only one row, so there is only tuptable->vals 0. The
code tries to reference tuptable->vals 1 , which is out of bounds, and
segfaults.
It should loop through the three columns, like so:
{{{
tupdesc = SPI_tuptable->tupdesc;
tuptable = SPI_tuptable;
tuple = tuptable->vals[0];
/* which column to use? */
for (i = 1; i < 4; i++) {
tmp = SPI_getvalue(tuple, tupdesc, i);
}}}
Sorry for not just attaching some patches... I'm pretty new here, just
getting my feet wet.
--
Ticket URL: <http://trac.osgeo.org/postgis/ticket/1782>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.
More information about the postgis-devel
mailing list