Guard against null case and view when painting overlay and creating intersections

Four crashes reported from release builds share the same shape: a pointer that
is null during teardown or before a view is fully created is dereferenced
without a check.

RiuViewer::paintOverlayItems() used the owner case of the view and of the
comparison view without checking it, and dereferenced the result of a
dynamic_cast directly. The owner case is null while a case is being closed.

RicIntersectionFeatureImpl::createIntersectionBoxSlize() checked
activeMainOrComparisonGridView() but dereferenced activeGridView(), which is a
different object and can be null or have no viewer.

RimEclipseContourMapView::onCreateDisplayModel() called viewer()->mainCamera()
before the viewer exists.

RimCorrelationPlotCollection::applyFirstEnsembleFieldAddressesToPlot() called
front() on the ensemble parameter vector, which is empty for an ensemble
without realization parameters.
This commit is contained in:
Magne Sjaastad
2026-08-07 12:21:41 +02:00
parent 842520c5e9
commit 593f27dcf4
4 changed files with 14 additions and 8 deletions
@@ -35,7 +35,8 @@ void RicIntersectionFeatureImpl::createIntersectionBoxSlize( const QString& name
RimGridView* activeView = RiaApplication::instance()->activeGridView();
RimGridView* activeMainOrComparisonView = RiaApplication::instance()->activeMainOrComparisonGridView();
if ( activeMainOrComparisonView )
// activeGridView() and activeMainOrComparisonGridView() are different objects, both must be checked
if ( activeMainOrComparisonView && activeView && activeView->viewer() )
{
RimIntersectionCollection* coll = activeMainOrComparisonView->intersectionCollection();
CVF_ASSERT( coll );
@@ -210,7 +210,7 @@ void RimEclipseContourMapView::onCreateDisplayModel()
updateGeometry();
}
if ( viewer()->mainCamera()->viewMatrix() == sm_defaultViewMatrix )
if ( viewer() && viewer()->mainCamera() && viewer()->mainCamera()->viewMatrix() == sm_defaultViewMatrix )
{
zoomAll();
}
@@ -320,8 +320,9 @@ void RimCorrelationPlotCollection::applyFirstEnsembleFieldAddressesToPlot( RimAb
auto crossPlot = dynamic_cast<RimParameterResultCrossPlot*>( plot );
if ( crossPlot )
{
crossPlot->setEnsembleParameter(
RimSummaryEnsembleTools::alphabeticEnsembleParameters( ensembles.front()->allSummaryCases() ).front().name );
// An ensemble without realization parameters has no parameters to select
const auto parameters = RimSummaryEnsembleTools::alphabeticEnsembleParameters( ensembles.front()->allSummaryCases() );
if ( !parameters.empty() ) crossPlot->setEnsembleParameter( parameters.front().name );
}
}
}
@@ -432,9 +432,11 @@ void RiuViewer::paintOverlayItems( QPainter* painter )
int columnPos = trueWidth - columnWidth - margin - edgeAxisFrameBorderWidth;
if ( isComparisonViewActive() )
Rim3dView* rimView = dynamic_cast<Rim3dView*>( m_rimView.p() );
if ( isComparisonViewActive() && rimView )
{
Rim3dView* compView = dynamic_cast<Rim3dView*>( m_rimView.p() )->activeComparisonView();
Rim3dView* compView = rimView->activeComparisonView();
if ( compView )
{
columnWidth = 200;
@@ -445,15 +447,17 @@ void RiuViewer::paintOverlayItems( QPainter* painter )
if ( m_showInfoText )
{
// The owner case is nullptr while the case is being closed
if ( rimView->ownerCase() )
{
Rim3dView* view = dynamic_cast<Rim3dView*>( m_rimView.p() );
m_shortInfoLabel->setText( "<center>" + view->ownerCase()->caseUserDescription() + "</center>" );
m_shortInfoLabel->setText( "<center>" + rimView->ownerCase()->caseUserDescription() + "</center>" );
QPoint topLeft = QPoint( columnPos, yPos );
m_shortInfoLabel->resize( columnWidth, m_shortInfoLabel->sizeHint().height() );
m_shortInfoLabel->render( painter, topLeft );
}
if ( compView->ownerCase() )
{
m_shortInfoLabelCompView->setText( "<center>" + compView->ownerCase()->caseUserDescription() + "</center>" );
QPoint topLeft = QPoint( compViewItemsXPos, yPos );