Skip to content

Commit

Permalink
Fix various nullptr dereference when opening project with broken rast…
Browse files Browse the repository at this point in the history
…er provider

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

Number of nullptr checks in QgsRasterLayer class have been just added for
consistency. Some might not be triggerable.
  • Loading branch information
rouault authored and nyalldawson committed Oct 23, 2020
1 parent 7f80077 commit 2d99271
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 20 deletions.
11 changes: 6 additions & 5 deletions src/app/qgisapp.cpp
Expand Up @@ -13254,10 +13254,13 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
case QgsMapLayerType::RasterLayer:
{
const QgsRasterLayer *rlayer = qobject_cast<const QgsRasterLayer *>( layer );
if ( rlayer->dataProvider()->dataType( 1 ) != Qgis::ARGB32
&& rlayer->dataProvider()->dataType( 1 ) != Qgis::ARGB32_Premultiplied )
const QgsRasterDataProvider *dprovider = rlayer->dataProvider();

if ( dprovider
&& dprovider->dataType( 1 ) != Qgis::ARGB32
&& dprovider->dataType( 1 ) != Qgis::ARGB32_Premultiplied )
{
if ( rlayer->dataProvider()->capabilities() & QgsRasterDataProvider::Size )
if ( dprovider->capabilities() & QgsRasterDataProvider::Size )
{
mActionFullHistogramStretch->setEnabled( true );
}
Expand Down Expand Up @@ -13361,8 +13364,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
QgsMapToolIdentify::IdentifyMode identifyMode = settings.enumValue( QStringLiteral( "Map/identifyMode" ), QgsMapToolIdentify::ActiveLayer );
if ( identifyMode == QgsMapToolIdentify::ActiveLayer )
{
const QgsRasterLayer *rlayer = qobject_cast<const QgsRasterLayer *>( layer );
const QgsRasterDataProvider *dprovider = rlayer->dataProvider();
if ( dprovider )
{
// does provider allow the identify map tool?
Expand Down
22 changes: 13 additions & 9 deletions src/app/qgsrasterlayerproperties.cpp
Expand Up @@ -659,16 +659,20 @@ void QgsRasterLayerProperties::sync()
{
QgsSettings myQSettings;

if ( mRasterLayer->dataProvider()->dataType( 1 ) == Qgis::ARGB32
|| mRasterLayer->dataProvider()->dataType( 1 ) == Qgis::ARGB32_Premultiplied )
const QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
if ( !provider )
return;

if ( provider->dataType( 1 ) == Qgis::ARGB32
|| provider->dataType( 1 ) == Qgis::ARGB32_Premultiplied )
{
gboxNoDataValue->setEnabled( false );
gboxCustomTransparency->setEnabled( false );
mOptionsStackedWidget->setCurrentWidget( mOptsPage_Server );
}

// TODO: Wouldn't it be better to just removeWidget() the tabs than delete them? [LS]
if ( !( mRasterLayer->dataProvider()->capabilities() & QgsRasterDataProvider::BuildPyramids ) )
if ( !( provider->capabilities() & QgsRasterDataProvider::BuildPyramids ) )
{
if ( mOptsPage_Pyramids )
{
Expand All @@ -677,7 +681,7 @@ void QgsRasterLayerProperties::sync()
}
}

if ( !( mRasterLayer->dataProvider()->capabilities() & QgsRasterDataProvider::Size ) )
if ( !( provider->capabilities() & QgsRasterDataProvider::Size ) )
{
if ( mOptsPage_Histogram )
{
Expand Down Expand Up @@ -718,23 +722,23 @@ void QgsRasterLayerProperties::sync()
//add current NoDataValue to NoDataValue line edit
// TODO: should be per band
// TODO: no data ranges
if ( mRasterLayer->dataProvider()->sourceHasNoDataValue( 1 ) )
if ( provider->sourceHasNoDataValue( 1 ) )
{
lblSrcNoDataValue->setText( QgsRasterBlock::printValue( mRasterLayer->dataProvider()->sourceNoDataValue( 1 ) ) );
lblSrcNoDataValue->setText( QgsRasterBlock::printValue( provider->sourceNoDataValue( 1 ) ) );
}
else
{
lblSrcNoDataValue->setText( tr( "not defined" ) );
}

mSrcNoDataValueCheckBox->setChecked( mRasterLayer->dataProvider()->useSourceNoDataValue( 1 ) );
mSrcNoDataValueCheckBox->setChecked( provider->useSourceNoDataValue( 1 ) );

bool enableSrcNoData = mRasterLayer->dataProvider()->sourceHasNoDataValue( 1 ) && !std::isnan( mRasterLayer->dataProvider()->sourceNoDataValue( 1 ) );
bool enableSrcNoData = provider->sourceHasNoDataValue( 1 ) && !std::isnan( provider->sourceNoDataValue( 1 ) );

mSrcNoDataValueCheckBox->setEnabled( enableSrcNoData );
lblSrcNoDataValue->setEnabled( enableSrcNoData );

QgsRasterRangeList noDataRangeList = mRasterLayer->dataProvider()->userNoDataValues( 1 );
QgsRasterRangeList noDataRangeList = provider->userNoDataValues( 1 );
QgsDebugMsg( QStringLiteral( "noDataRangeList.size = %1" ).arg( noDataRangeList.size() ) );
if ( !noDataRangeList.isEmpty() )
{
Expand Down
20 changes: 15 additions & 5 deletions src/core/raster/qgsrasterlayer.cpp
Expand Up @@ -214,7 +214,8 @@ int QgsRasterLayer::bandCount() const

QString QgsRasterLayer::bandName( int bandNo ) const
{
return dataProvider()->generateBandName( bandNo );
if ( !mDataProvider ) return QString();
return mDataProvider->generateBandName( bandNo );
}

void QgsRasterLayer::setRendererForDrawingStyle( QgsRaster::DrawingStyle drawingStyle )
Expand Down Expand Up @@ -486,7 +487,8 @@ QPixmap QgsRasterLayer::paletteAsPixmap( int bandNumber )

// Only do this for the GDAL provider?
// Maybe WMS can do this differently using QImage::numColors and QImage::color()
if ( mDataProvider->colorInterpretation( bandNumber ) == QgsRaster::PaletteIndex )
if ( mDataProvider &&
mDataProvider->colorInterpretation( bandNumber ) == QgsRaster::PaletteIndex )
{
QgsDebugMsgLevel( QStringLiteral( "....found paletted image" ), 4 );
QgsColorRampShader myShader;
Expand Down Expand Up @@ -546,7 +548,8 @@ double QgsRasterLayer::rasterUnitsPerPixelX() const
// We can only use one of the mGeoTransform[], so go with the
// horisontal one.

if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size && !qgsDoubleNear( mDataProvider->xSize(), 0.0 ) )
if ( mDataProvider &&
mDataProvider->capabilities() & QgsRasterDataProvider::Size && !qgsDoubleNear( mDataProvider->xSize(), 0.0 ) )
{
return mDataProvider->extent().width() / mDataProvider->xSize();
}
Expand All @@ -555,7 +558,8 @@ double QgsRasterLayer::rasterUnitsPerPixelX() const

double QgsRasterLayer::rasterUnitsPerPixelY() const
{
if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size && !qgsDoubleNear( mDataProvider->ySize(), 0.0 ) )
if ( mDataProvider &&
mDataProvider->capabilities() & QgsRasterDataProvider::Size && !qgsDoubleNear( mDataProvider->ySize(), 0.0 ) )
{
return mDataProvider->extent().height() / mDataProvider->ySize();
}
Expand Down Expand Up @@ -908,6 +912,8 @@ void QgsRasterLayer::computeMinMax( int band,

min = std::numeric_limits<double>::quiet_NaN();
max = std::numeric_limits<double>::quiet_NaN();
if ( !mDataProvider )
return;

if ( limits == QgsRasterMinMaxOrigin::MinMax )
{
Expand Down Expand Up @@ -1312,6 +1318,8 @@ void QgsRasterLayer::setSubLayerVisibility( const QString &name, bool vis )

QDateTime QgsRasterLayer::timestamp() const
{
if ( !mDataProvider )
return QDateTime();
return mDataProvider->timestamp();
}

Expand Down Expand Up @@ -1559,6 +1567,8 @@ void QgsRasterLayer::setTransformContext( const QgsCoordinateTransformContext &t

QStringList QgsRasterLayer::subLayers() const
{
if ( ! mDataProvider )
return QStringList();
return mDataProvider->subLayers();
}

Expand Down Expand Up @@ -2306,7 +2316,7 @@ bool QgsRasterLayer::update()
{
QgsDebugMsgLevel( QStringLiteral( "entered." ), 4 );
// Check if data changed
if ( mDataProvider->dataTimestamp() > mDataProvider->timestamp() )
if ( mDataProvider && mDataProvider->dataTimestamp() > mDataProvider->timestamp() )
{
QgsDebugMsgLevel( QStringLiteral( "reload data" ), 4 );
closeDataProvider();
Expand Down
3 changes: 2 additions & 1 deletion src/gui/qgsmapcanvas.cpp
Expand Up @@ -2452,7 +2452,8 @@ void QgsMapCanvas::startPreviewJob( int number )
for ( QgsMapLayer *layer : layers )
{
context.lastRenderingTimeMs = mLastLayerRenderTime.value( layer->id(), 0 );
if ( !layer->dataProvider()->renderInPreview( context ) )
QgsDataProvider *provider = layer->dataProvider();
if ( provider && !provider->renderInPreview( context ) )
{
QgsDebugMsgLevel( QStringLiteral( "Layer %1 not rendered because it does not match the renderInPreview criterion %2" ).arg( layer->id() ).arg( mLastLayerRenderTime.value( layer->id() ) ), 3 );
continue;
Expand Down

0 comments on commit 2d99271

Please sign in to comment.