Skip to content

Commit

Permalink
Fix crash when accessing QgsApplication::dataItemProviderRegistry()
Browse files Browse the repository at this point in the history
without QgsApplication instance.

Also add test to ensure that calling QgsApplication::initQgis()
is safe to do without QgsApplication instance.
  • Loading branch information
nyalldawson committed Nov 6, 2017
1 parent c413f14 commit 2eff873
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/core/qgsapplication.cpp
Expand Up @@ -112,6 +112,7 @@ const char *QgsApplication::QGIS_APPLICATION_NAME = "QGIS3";

QgsApplication::ApplicationMembers *QgsApplication::sApplicationMembers = nullptr;
QgsAuthManager *QgsApplication::sAuthManager = nullptr;
QgsDataItemProviderRegistry *QgsApplication::sDataItemProviderRegistry = nullptr;

QgsApplication::QgsApplication( int &argc, char **argv, bool GUIenabled, const QString &profileFolder, const QString &platformName )
: QApplication( argc, argv, GUIenabled )
Expand Down Expand Up @@ -871,7 +872,8 @@ void QgsApplication::initQgis()
// set the provider plugin path (this creates provider registry)
QgsProviderRegistry::instance( pluginPath() );

instance()->mDataItemProviderRegistry = new QgsDataItemProviderRegistry();
// create data item provider registry
( void )QgsApplication::dataItemProviderRegistry();

// create project instance if doesn't exist
QgsProject::instance();
Expand Down Expand Up @@ -1559,7 +1561,21 @@ QgsRasterRendererRegistry *QgsApplication::rasterRendererRegistry()

QgsDataItemProviderRegistry *QgsApplication::dataItemProviderRegistry()
{
return instance()->mDataItemProviderRegistry;
if ( instance() )
{
if ( !instance()->mDataItemProviderRegistry )
{
instance()->mDataItemProviderRegistry = new QgsDataItemProviderRegistry();
}
return instance()->mDataItemProviderRegistry;
}
else
{
// no QgsApplication instance
if ( !sDataItemProviderRegistry )
sDataItemProviderRegistry = new QgsDataItemProviderRegistry();
return sDataItemProviderRegistry;
}
}

QgsSvgCache *QgsApplication::svgCache()
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsapplication.h
Expand Up @@ -749,6 +749,8 @@ class CORE_EXPORT QgsApplication : public QApplication
QMap<QString, QIcon> mIconCache;

QgsDataItemProviderRegistry *mDataItemProviderRegistry = nullptr;
// ... but in case QgsApplication is never instantiated (eg with custom designer widgets), we fall back to static instance
static QgsDataItemProviderRegistry *sDataItemProviderRegistry;

QgsAuthManager *mAuthManager = nullptr;
// ... but in case QgsApplication is never instantiated (eg with custom designer widgets), we fall back to static instance
Expand Down
9 changes: 9 additions & 0 deletions tests/src/python/test_qgsnoapplication.py
Expand Up @@ -56,6 +56,15 @@ def testNullRepresentation(self):
def testAuthManager(self):
self.assertTrue(QgsApplication.authManager())

def testDataItemProviderRegistry(self):
self.assertTrue(QgsApplication.dataItemProviderRegistry())

def testInit(self):
"""
Test calling QgsApplication.initQgis() without QgsApplication instance
"""
QgsApplication.initQgis()


if __name__ == '__main__':
unittest.main()

0 comments on commit 2eff873

Please sign in to comment.