Skip to content

Commit

Permalink
Fix various crashes on a vector layer with a broken provider
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault committed May 31, 2021
1 parent 0c0a1f8 commit 452ce09
Show file tree
Hide file tree
Showing 12 changed files with 243 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/app/qgisapp.cpp
Expand Up @@ -8742,7 +8742,7 @@ void QgisApp::fieldCalculator()
void QgisApp::attributeTable( QgsAttributeTableFilterModel::FilterMode filter )
{
QgsVectorLayer *myLayer = qobject_cast<QgsVectorLayer *>( activeLayer() );
if ( !myLayer )
if ( !myLayer || !myLayer->dataProvider() )
{
return;
}
Expand Down Expand Up @@ -9016,7 +9016,7 @@ void QgisApp::saveStyleFile( QgsMapLayer *layer )
layer = activeLayer();
}

if ( !layer )
if ( !layer || !layer->dataProvider() )
return;

switch ( layer->type() )
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgisappinterface.cpp
Expand Up @@ -507,7 +507,7 @@ void QgisAppInterface::showLayerProperties( QgsMapLayer *l, const QString &page

QDialog *QgisAppInterface::showAttributeTable( QgsVectorLayer *l, const QString &filterExpression )
{
if ( l )
if ( l && l->dataProvider() )
{
QgsAttributeTableDialog *dialog = new QgsAttributeTableDialog( l, QgsAttributeTableFilterModel::ShowFilteredList );
dialog->setFilterExpression( filterExpression );
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsmaptoolidentifyaction.cpp
Expand Up @@ -94,7 +94,7 @@ void QgsMapToolIdentifyAction::showAttributeTable( QgsMapLayer *layer, const QLi
resultsDialog()->clear();

QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
if ( !vl )
if ( !vl || !vl->dataProvider() )
return;

QString filter = QStringLiteral( "$id IN (" );
Expand Down
7 changes: 4 additions & 3 deletions src/app/qgsprojectproperties.cpp
Expand Up @@ -821,7 +821,10 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
currentLayer = it.value();
if ( currentLayer->type() == QgsMapLayerType::VectorLayer )
{

QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( currentLayer );
QgsVectorDataProvider *provider = vlayer->dataProvider();
if ( !provider )
continue;
QTableWidgetItem *twi = new QTableWidgetItem( QString::number( j ) );
twWFSLayers->setVerticalHeaderItem( j, twi );

Expand All @@ -839,8 +842,6 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
psb->setValue( QgsProject::instance()->readNumEntry( QStringLiteral( "WFSLayersPrecision" ), "/" + currentLayer->id(), 8 ) );
twWFSLayers->setCellWidget( j, 2, psb );

QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( currentLayer );
QgsVectorDataProvider *provider = vlayer->dataProvider();
if ( ( provider->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) && ( provider->capabilities() & QgsVectorDataProvider::ChangeGeometries ) )
{
QCheckBox *cbu = new QCheckBox();
Expand Down
12 changes: 7 additions & 5 deletions src/core/qgsrelationmanager.cpp
Expand Up @@ -290,12 +290,15 @@ QList<QgsRelation> QgsRelationManager::discoverRelations( const QList<QgsRelatio
QList<QgsRelation> result;
for ( const QgsVectorLayer *layer : std::as_const( layers ) )
{
const auto constDiscoverRelations = layer->dataProvider()->discoverRelations( layer, layers );
for ( const QgsRelation &relation : constDiscoverRelations )
if ( const QgsVectorDataProvider *provider = layer->dataProvider() )
{
if ( !hasRelationWithEqualDefinition( existingRelations, relation ) )
const auto constDiscoverRelations = provider->discoverRelations( layer, layers );
for ( const QgsRelation &relation : constDiscoverRelations )
{
result.append( relation );
if ( !hasRelationWithEqualDefinition( existingRelations, relation ) )
{
result.append( relation );
}
}
}
}
Expand Down Expand Up @@ -342,4 +345,3 @@ void QgsRelationManager::setPolymorphicRelations( const QList<QgsPolymorphicRela
for ( const QgsPolymorphicRelation &newRelation : relations )
addPolymorphicRelation( newRelation );
}

8 changes: 6 additions & 2 deletions src/core/vector/qgsvectorlayer.cpp
Expand Up @@ -284,7 +284,8 @@ QgsVectorLayer *QgsVectorLayer::clone() const
layer->addJoin( join );
}

layer->setProviderEncoding( dataProvider()->encoding() );
if ( mDataProvider )
layer->setProviderEncoding( mDataProvider->encoding() );
layer->setDisplayExpression( displayExpression() );
layer->setMapTipTemplate( mapTipTemplate() );
layer->setReadOnly( isReadOnly() );
Expand Down Expand Up @@ -3756,7 +3757,10 @@ void QgsVectorLayer::setRenderer( QgsFeatureRenderer *r )

void QgsVectorLayer::addFeatureRendererGenerator( QgsFeatureRendererGenerator *generator )
{
mRendererGenerators << generator;
if ( generator )
{
mRendererGenerators << generator;
}
}

void QgsVectorLayer::removeFeatureRendererGenerator( const QString &id )
Expand Down
28 changes: 18 additions & 10 deletions src/core/vector/qgsvectorlayerfeatureiterator.cpp
Expand Up @@ -34,7 +34,9 @@
QgsVectorLayerFeatureSource::QgsVectorLayerFeatureSource( const QgsVectorLayer *layer )
{
QMutexLocker locker( &layer->mFeatureSourceConstructorMutex );
mProviderFeatureSource.reset( layer->dataProvider()->featureSource() );
const QgsVectorDataProvider *provider = layer->dataProvider();
if ( provider )
mProviderFeatureSource.reset( provider->featureSource() );
mFields = layer->fields();
mId = layer->id();

Expand Down Expand Up @@ -75,7 +77,7 @@ QgsVectorLayerFeatureSource::QgsVectorLayerFeatureSource( const QgsVectorLayer *
{
#endif
// If we are inside a transaction the iterator "sees" the current status
if ( layer->dataProvider() && ! layer->dataProvider()->transaction() )
if ( provider && ! provider->transaction() )
{
mAddedFeatures = QgsFeatureMap( layer->editBuffer()->addedFeatures() );
mChangedGeometries = QgsGeometryMap( layer->editBuffer()->changedGeometries() );
Expand Down Expand Up @@ -293,13 +295,16 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
}
else // no filter or filter by rect
{
if ( mSource->mHasEditBuffer )
{
mChangedFeaturesIterator = mSource->mProviderFeatureSource->getFeatures( mChangedFeaturesRequest );
}
else
if ( mSource->mProviderFeatureSource )
{
mProviderIterator = mSource->mProviderFeatureSource->getFeatures( mProviderRequest );
if ( mSource->mHasEditBuffer )
{
mChangedFeaturesIterator = mSource->mProviderFeatureSource->getFeatures( mChangedFeaturesRequest );
}
else
{
mProviderIterator = mSource->mProviderFeatureSource->getFeatures( mProviderRequest );
}
}

rewindEditBuffer();
Expand Down Expand Up @@ -437,8 +442,11 @@ bool QgsVectorLayerFeatureIterator::fetchFeature( QgsFeature &f )
if ( mProviderIterator.isClosed() )
{
mChangedFeaturesIterator.close();
mProviderIterator = mSource->mProviderFeatureSource->getFeatures( mProviderRequest );
mProviderIterator.setInterruptionChecker( mInterruptionChecker );
if ( mSource->mProviderFeatureSource )
{
mProviderIterator = mSource->mProviderFeatureSource->getFeatures( mProviderRequest );
mProviderIterator.setInterruptionChecker( mInterruptionChecker );
}
}

while ( mProviderIterator.nextFeature( f ) )
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsmaptoolidentify.cpp
Expand Up @@ -537,7 +537,7 @@ QMap<QString, QString> QgsMapToolIdentify::derivedAttributesForPoint( const QgsP

bool QgsMapToolIdentify::identifyVectorLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsVectorLayer *layer, const QgsGeometry &geometry, const QgsIdentifyContext &identifyContext )
{
if ( !layer || !layer->isSpatial() )
if ( !layer || !layer->isSpatial() || !layer->dataProvider() )
return false;

if ( !layer->isInScaleRange( mCanvas->mapSettings().scale() ) )
Expand Down
8 changes: 6 additions & 2 deletions src/gui/vector/qgsfieldcalculator.cpp
Expand Up @@ -59,9 +59,13 @@ QgsFieldCalculator::QgsFieldCalculator( QgsVectorLayer *vl, QWidget *parent )

if ( !vl )
return;
QgsVectorDataProvider *dataProvider = vl->dataProvider();
if ( !dataProvider )
return;

mCanAddAttribute = vl->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes;
mCanChangeAttributeValue = vl->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
const QgsVectorDataProvider::Capabilities caps = dataProvider->capabilities();
mCanAddAttribute = caps & QgsVectorDataProvider::AddAttributes;
mCanChangeAttributeValue = caps & QgsVectorDataProvider::ChangeAttributeValues;

QgsExpressionContext expContext( QgsExpressionContextUtils::globalProjectLayerScopes( mVectorLayer ) );

Expand Down
7 changes: 6 additions & 1 deletion src/gui/vector/qgssourcefieldsproperties.cpp
Expand Up @@ -321,6 +321,11 @@ void QgsSourceFieldsProperties::editingToggled()

void QgsSourceFieldsProperties::addAttributeClicked()
{
if ( !mLayer || !mLayer->dataProvider() )
{
return;
}

QgsAddAttrDialog dialog( mLayer, this );
if ( dialog.exec() == QDialog::Accepted )
{
Expand Down Expand Up @@ -364,7 +369,7 @@ void QgsSourceFieldsProperties::deleteAttributeClicked()

void QgsSourceFieldsProperties::calculateFieldClicked()
{
if ( !mLayer )
if ( !mLayer || !mLayer->dataProvider() )
{
return;
}
Expand Down
2 changes: 2 additions & 0 deletions src/gui/vector/qgsvectorlayerproperties.cpp
Expand Up @@ -1143,6 +1143,8 @@ void QgsVectorLayerProperties::loadDefaultMetadata()

void QgsVectorLayerProperties::saveStyleAs()
{
if ( !mLayer->dataProvider() )
return;
QgsVectorLayerSaveStyleDialog dlg( mLayer );
QgsSettings settings;

Expand Down

0 comments on commit 452ce09

Please sign in to comment.