[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