Fix crashes reported by crash telemetry

* Recompute well cell arrays when the grids change

computeWellCellsPrGrid() returned early whenever the arrays had been computed once, so the
size check below it was unreachable and a stale array was kept when the grids changed. The
too-short array triggered an assert in RivReservoirViewPartMgr::computeNativeVisibility.

Return early only when the cached arrays still match the current set of grids.

* Guard against missing GUI application when applying style sheet

RiaGuiApplication::instance() does a dynamic_cast and returns null outside a GUI context. The
assert guarding this is compiled out in release, so the null pointer was dereferenced.

* Guard against missing case in flow characteristics plot field change

The case field can be set to nothing from the UI. RimEclipseResultCase::defaultFlowDiagSolution()
and reservoirViews() were then called on a null pointer.

* Guard against missing case and out of range time steps when updating flow characteristics plot

onLoadDataAndUpdate() dereferenced the case without checking, although the same function handles
a missing case further down. The time step indices come from the flow diagnostics solution, and
were used to index arrays sized by the number of case time steps without a range check.
This commit is contained in:
Magne Sjaastad authored and GitHub committed 2026-08-07 12:12:31 +02:00
1 parent ebf75c09a1
commit 318659e130
5 files changed
+70 -12

No files matched your search

@@ -563,9 +563,10 @@ void RimFlowCharacteristicsPlot::fieldChangedByUi( const caf::PdmFieldHandle* ch
if ( &m_case == changedField )
{
m_flowDiagSolution = m_case->defaultFlowDiagSolution();
// The case field can be set to nothing from the UI
m_flowDiagSolution = m_case() ? m_case()->defaultFlowDiagSolution() : nullptr;
m_currentlyPlottedTimeSteps.clear();
if ( !m_case()->reservoirViews().empty() )
if ( m_case() && !m_case()->reservoirViews().empty() )
{
m_cellFilterView = m_case()->reservoirViews()[0];
}
@@ -607,9 +608,15 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
m_currentlyPlottedTimeSteps = calculatedTimesteps;
}
std::vector<QDateTime> timeStepDates = m_case->timeStepDates();
QStringList timeStepStrings = m_case->timeStepStrings();
std::vector<double> lorenzVals( timeStepDates.size(), HUGE_VAL );
// The case can be missing, as the case field can be set to nothing from the UI
std::vector<QDateTime> timeStepDates;
QStringList timeStepStrings;
if ( m_case() )
{
timeStepDates = m_case()->timeStepDates();
timeStepStrings = m_case()->timeStepStrings();
}
std::vector<double> lorenzVals( timeStepDates.size(), HUGE_VAL );
m_flowCharPlotWidget->removeAllCurves();
@@ -660,7 +667,11 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
m_maxTof() );
timeStepToFlowResultMap[timeStepIdx] = flowCharResults;
}
lorenzVals[timeStepIdx] = timeStepToFlowResultMap[timeStepIdx].m_lorenzCoefficient;
// The time step indices are given by the flow diagnostics solution, and can be out of range for the case
if ( timeStepIdx >= 0 && static_cast<size_t>( timeStepIdx ) < lorenzVals.size() )
{
lorenzVals[timeStepIdx] = timeStepToFlowResultMap[timeStepIdx].m_lorenzCoefficient;
}
}
m_timeStepToFlowResultMap = timeStepToFlowResultMap;
@@ -678,6 +689,8 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
for ( int timeStepIdx : m_currentlyPlottedTimeSteps )
{
if ( timeStepIdx < 0 || static_cast<size_t>( timeStepIdx ) >= timeStepDates.size() ) continue;
const auto& flowCharResults = timeStepToFlowResultMap[timeStepIdx];
m_flowCharPlotWidget->addFlowCapStorageCapCurve( timeStepDates[timeStepIdx],