Skip to content
Permalink
Browse files

Fix various nullptr dereference when opening project with broken rast…

…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 Feb 1, 2020
1 parent f9f1ad7 commit 2eeceb5fa81b5f6133e7a883859f609f96d3543f
@@ -13644,10 +13644,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 );
}
@@ -13733,8 +13736,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?
@@ -213,7 +213,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 )
@@ -485,7 +486,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;
@@ -545,7 +547,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();
}
@@ -554,7 +557,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();
}
@@ -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 )
{
@@ -1312,6 +1318,8 @@ void QgsRasterLayer::setSubLayerVisibility( const QString &name, bool vis )

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

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

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

@@ -2305,7 +2315,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();
@@ -2464,7 +2464,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;
@@ -671,16 +671,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 )
{
@@ -689,7 +693,7 @@ void QgsRasterLayerProperties::sync()
}
}

if ( !( mRasterLayer->dataProvider()->capabilities() & QgsRasterDataProvider::Size ) )
if ( !( provider->capabilities() & QgsRasterDataProvider::Size ) )
{
if ( mOptsPage_Histogram )
{
@@ -730,23 +734,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() )
{

0 comments on commit 2eeceb5

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