Skip to content

Commit f74ac92

Browse files
committed
[GRASS] use vectNewMapStruct() in mapRegion(), fixes crash when running modules with GRASS lib compiled by different compiler
1 parent 8ce9930 commit f74ac92

File tree

3 files changed

+57
-26
lines changed

3 files changed

+57
-26
lines changed

src/plugins/grass/qgsgrassplugin.cpp

+12-12
Original file line numberDiff line numberDiff line change
@@ -380,29 +380,29 @@ void QgsGrassPlugin::newVector()
380380
QgsGrass::getDefaultLocation(),
381381
QgsGrass::getDefaultMapset() );
382382

383-
try
383+
struct Map_info *Map = 0;
384+
G_TRY
384385
{
385-
struct Map_info Map;
386-
Vect_open_new( &Map, name.toUtf8().data(), 0 );
386+
Map = QgsGrass::vectNewMapStruct();
387+
Vect_open_new( Map, name.toUtf8().data(), 0 );
387388

388389
#if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \
389390
( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR >= 4 ) || GRASS_VERSION_MAJOR > 6 )
390-
Vect_build( &Map );
391+
Vect_build( Map );
391392
#else
392-
Vect_build( &Map, stderr );
393+
Vect_build( Map, stderr );
393394
#endif
394-
Vect_set_release_support( &Map );
395-
Vect_close( &Map );
395+
Vect_set_release_support( Map );
396+
Vect_close( Map );
397+
QgsGrass::vectDestroyMapStruct( Map );
396398
}
397-
catch ( QgsGrass::Exception &e )
399+
G_CATCH( QgsGrass::Exception &e )
398400
{
399-
QMessageBox::warning( 0, tr( "Warning" ),
400-
tr( "Cannot create new vector: %1" ).arg( e.what() ) );
401+
QgsGrass::warning( tr( "Cannot create new vector: %1" ).arg( e.what() ) );
402+
QgsGrass::vectDestroyMapStruct( Map );
401403
return;
402404
}
403405

404-
405-
406406
// Open in GRASS vector provider
407407

408408
QString uri = QgsGrass::getDefaultGisdbase() + "/"

src/providers/grass/qgsgrass.cpp

+43-13
Original file line numberDiff line numberDiff line change
@@ -1113,9 +1113,9 @@ QStringList QgsGrass::vectorLayers( const QString& gisdbase, const QString& loca
11131113
//Vect_set_open_level( 2 );
11141114

11151115
// TODO: We are currently using vectDestroyMapStruct in G_CATCH blocks because we know
1116-
// that it does cannot call another G_fatal_error, but once we switch to hypothetical Vect_destroy_map_struct
1116+
// that it cannot call another G_fatal_error, but once we switch to hypothetical Vect_destroy_map_struct
11171117
// it should be verified if it can still be in G_CATCH
1118-
struct Map_info *map = vectNewMapStruct();
1118+
struct Map_info *map = 0;
11191119
int level = -1;
11201120

11211121
// Vect_open_old_head GRASS is raising fatal error if topo exists but it is in different (older) version.
@@ -1124,6 +1124,7 @@ QStringList QgsGrass::vectorLayers( const QString& gisdbase, const QString& loca
11241124

11251125
G_TRY
11261126
{
1127+
map = vectNewMapStruct();
11271128
level = Vect_open_old_head( map, ( char * ) mapName.toUtf8().data(), ( char * ) mapset.toUtf8().data() );
11281129
}
11291130
G_CATCH( QgsGrass::Exception &e )
@@ -1647,24 +1648,44 @@ bool QgsGrass::mapRegion( QgsGrassObject::Type type, QString gisdbase,
16471648
}
16481649
catch ( QgsGrass::Exception &e )
16491650
{
1650-
QgsGrass::warning( e );
1651+
warning( e );
16511652
return false;
16521653
}
16531654

1654-
struct Map_info Map;
1655-
1656-
int level = Vect_open_old_head( &Map,
1657-
map.toUtf8().data(), mapset.toUtf8().data() );
1655+
struct Map_info *Map = 0;
1656+
int level = -1;
1657+
G_TRY
1658+
{
1659+
Map = vectNewMapStruct();
1660+
level = Vect_open_old_head( Map, map.toUtf8().data(), mapset.toUtf8().data() );
1661+
}
1662+
G_CATCH( QgsGrass::Exception &e )
1663+
{
1664+
warning( e );
1665+
vectDestroyMapStruct( Map );
1666+
return false;
1667+
}
16581668

16591669
if ( level < 2 )
16601670
{
1661-
QMessageBox::warning( 0, QObject::tr( "Warning" ),
1662-
QObject::tr( "Cannot read vector map region" ) );
1671+
warning( QObject::tr( "Cannot read vector map region" ) );
1672+
if ( level == 1 )
1673+
{
1674+
G_TRY
1675+
{
1676+
Vect_close( Map );
1677+
}
1678+
G_CATCH( QgsGrass::Exception &e )
1679+
{
1680+
QgsDebugMsg( e.what() );
1681+
}
1682+
}
1683+
vectDestroyMapStruct( Map );
16631684
return false;
16641685
}
16651686

16661687
BOUND_BOX box;
1667-
Vect_get_map_box( &Map, &box );
1688+
Vect_get_map_box( Map, &box );
16681689
window->north = box.N;
16691690
window->south = box.S;
16701691
window->west = box.W;
@@ -1686,7 +1707,8 @@ bool QgsGrass::mapRegion( QgsGrassObject::Type type, QString gisdbase,
16861707
}
16871708
G_adjust_Cell_head3( window, 0, 0, 0 );
16881709

1689-
Vect_close( &Map );
1710+
Vect_close( Map );
1711+
vectDestroyMapStruct( Map );
16901712
}
16911713
else if ( type == QgsGrassObject::Region )
16921714
{
@@ -1700,8 +1722,16 @@ bool QgsGrass::mapRegion( QgsGrassObject::Type type, QString gisdbase,
17001722
return false;
17011723
}
17021724
#else
1703-
// TODO7: unfortunately G__get_window does not return error code and calls G_fatal_error on error
1704-
G__get_window( window, ( char * ) "windows", map.toUtf8().data(), mapset.toUtf8().data() );
1725+
// G__get_window does not return error code in GRASS 7 and calls G_fatal_error on error
1726+
G_TRY
1727+
{
1728+
G__get_window( window, ( char * ) "windows", map.toUtf8().data(), mapset.toUtf8().data() );
1729+
}
1730+
G_CATCH( QgsGrass::Exception &e )
1731+
{
1732+
warning( e );
1733+
return false;
1734+
}
17051735
#endif
17061736
}
17071737
return true;

src/providers/grass/qgsgrass.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,8 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
502502
/** Show warning dialog with exception message */
503503
static void warning( QgsGrass::Exception &e );
504504

505-
// Allocate struct Map_info
505+
/** Allocate struct Map_info. Call to this function may result in G_fatal_error
506+
* and must be surrounded by G_TRY/G_CATCH. */
506507
static struct Map_info * vectNewMapStruct();
507508
// Free struct Map_info
508509
static void vectDestroyMapStruct( struct Map_info *map );

0 commit comments

Comments
 (0)