Skip to content
Permalink
Browse files

Fix various nullptr dereference when opening project with broken vect…

…or provider

Found when replacing <provider>ogr</provider> by something else.

Number of nullptr checks in QgsVectorLayer class have been just added for
consistency. Some might not be triggerable.
  • Loading branch information
rouault authored and nyalldawson committed Feb 1, 2020
1 parent 2eeceb5 commit 89546fc4dca7247fb01710c16368d32047d1552d
@@ -226,8 +226,9 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
attributeTable->setEnabled( vlayer->isValid() );

// allow editing
unsigned int cap = vlayer->dataProvider()->capabilities();
if ( cap & QgsVectorDataProvider::EditingCapabilities )
const QgsVectorDataProvider *provider = vlayer->dataProvider();
if ( provider &&
( provider->capabilities() & QgsVectorDataProvider::EditingCapabilities ) )
{
if ( toggleEditingAction )
{
@@ -244,7 +245,7 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
if ( allEditsAction->isEnabled() )
menu->addAction( allEditsAction );

if ( vlayer->dataProvider()->supportsSubsetString() )
if ( provider && provider->supportsSubsetString() )
{
QAction *action = menu->addAction( tr( "&Filter…" ), QgisApp::instance(), &QgisApp::layerSubsetString );
action->setEnabled( !vlayer->isEditable() );
@@ -410,8 +410,10 @@ void QgsSourceFieldsProperties::attributesListCellPressed( int /*row*/, int /*co
//NICE FUNCTIONS
void QgsSourceFieldsProperties::updateButtons()
{

int cap = mLayer->dataProvider()->capabilities();
QgsVectorDataProvider *provider = mLayer->dataProvider();
if ( !provider )
return;
const int cap = provider->capabilities();

mToggleEditingButton->setEnabled( ( cap & QgsVectorDataProvider::ChangeAttributeValues ) && !mLayer->readOnly() );

@@ -626,7 +626,8 @@ void QgsVectorLayerProperties::syncToLayer()
mSimplifyDrawingSpinBox->setValue( simplifyMethod.threshold() );

QString remark = QStringLiteral( " (%1)" ).arg( tr( "Not supported" ) );
if ( !( mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::SimplifyGeometries ) )
const QgsVectorDataProvider *provider = mLayer->dataProvider();
if ( !( provider && ( provider->capabilities() & QgsVectorDataProvider::SimplifyGeometries ) ) )
{
mSimplifyDrawingAtProvider->setChecked( false );
mSimplifyDrawingAtProvider->setEnabled( false );
@@ -637,7 +637,7 @@ QgsWkbTypes::Type QgsVectorLayer::wkbType() const

QgsRectangle QgsVectorLayer::boundingBoxOfSelected() const
{
if ( !mValid || !isSpatial() || mSelectedFeatureIds.isEmpty() ) //no selected features
if ( !mValid || !isSpatial() || mSelectedFeatureIds.isEmpty() || !mDataProvider ) //no selected features
{
return QgsRectangle( 0, 0, 0, 0 );
}
@@ -3199,6 +3199,8 @@ QgsFields QgsVectorLayer::fields() const
QgsAttributeList QgsVectorLayer::primaryKeyAttributes() const
{
QgsAttributeList pkAttributesList;
if ( !mDataProvider )
return pkAttributesList;

QgsAttributeList providerIndexes = mDataProvider->pkAttributeIndexes();
for ( int i = 0; i < mFields.count(); ++i )
@@ -3232,7 +3234,7 @@ QgsFeatureSource::FeatureAvailability QgsVectorLayer::hasFeatures() const
return QgsFeatureSource::FeatureAvailability::FeaturesMaybeAvailable;
}

if ( ( !mEditBuffer || addedFeatures.empty() ) && mDataProvider->empty() )
if ( ( !mEditBuffer || addedFeatures.empty() ) && mDataProvider && mDataProvider->empty() )
return QgsFeatureSource::FeatureAvailability::NoFeaturesAvailable;
else
return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
@@ -3295,6 +3297,12 @@ bool QgsVectorLayer::rollBack( bool deleteBuffer )
return false;
}

if ( !mDataProvider )
{
mCommitErrors << tr( "ERROR: no provider" );
return false;
}

bool rollbackExtent = !mEditBuffer->mDeletedFeatureIds.isEmpty() ||
!mEditBuffer->mAddedFeatures.isEmpty() ||
!mEditBuffer->mChangedGeometries.isEmpty();
@@ -3414,7 +3422,7 @@ bool QgsVectorLayer::addFeatures( QgsFeatureList &features, Flags )
void QgsVectorLayer::setCoordinateSystem()
{
// if layer is not spatial, it has not CRS!
setCrs( isSpatial() ? mDataProvider->crs() : QgsCoordinateReferenceSystem() );
setCrs( ( isSpatial() && mDataProvider ) ? mDataProvider->crs() : QgsCoordinateReferenceSystem() );
}

QString QgsVectorLayer::displayField() const
@@ -3784,7 +3792,7 @@ void QgsVectorLayer::updateFields()

QVariant QgsVectorLayer::defaultValue( int index, const QgsFeature &feature, QgsExpressionContext *context ) const
{
if ( index < 0 || index >= mFields.count() )
if ( index < 0 || index >= mFields.count() || !mDataProvider )
return QVariant();

QString expression = mFields.at( index ).defaultValueDefinition().expression();
@@ -4867,7 +4875,11 @@ QString QgsVectorLayer::htmlMetadata() const
myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Comment" ) + QStringLiteral( "</td><td>" ) + dataComment() + QStringLiteral( "</td></tr>\n" );

// encoding
myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Encoding" ) + QStringLiteral( "</td><td>" ) + dataProvider()->encoding() + QStringLiteral( "</td></tr>\n" );
const QgsVectorDataProvider *provider = dataProvider();
if ( provider )
{
myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Encoding" ) + QStringLiteral( "</td><td>" ) + provider->encoding() + QStringLiteral( "</td></tr>\n" );
}

if ( isSpatial() )
{
@@ -5254,7 +5266,7 @@ bool QgsVectorLayer::setDependencies( const QSet<QgsMapLayerDependency> &oDeps )

QgsFieldConstraints::Constraints QgsVectorLayer::fieldConstraints( int fieldIndex ) const
{
if ( fieldIndex < 0 || fieldIndex >= mFields.count() )
if ( fieldIndex < 0 || fieldIndex >= mFields.count() || !mDataProvider )
return nullptr;

QgsFieldConstraints::Constraints constraints = mFields.at( fieldIndex ).constraints().constraints();

0 comments on commit 89546fc

Please sign in to comment.
You can’t perform that action at this time.