From 5f0c3f8a54d688e2b300cddc6bf8acd4aae3e17c Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 27 Aug 2026 15:43:51 +0200 Subject: [PATCH] #14632 Guard against out-of-range time step index when loading results A case in an ensemble can have fewer time steps than the case defining the time step axis of a statistics case. The time step index was used to index m_cellScalarResults directly, reading past the end of the vector in Release where CAF_ASSERT is a no-op. --- .../RigSoilResultCalculator.cpp | 25 +++++++------------ .../RigCaseCellResultsData.cpp | 15 +++++++++-- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSoilResultCalculator.cpp b/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSoilResultCalculator.cpp index 65e1d5b5e2..875a5719f1 100644 --- a/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSoilResultCalculator.cpp +++ b/ApplicationLibCode/ReservoirDataModel/ResultCalculators/RigSoilResultCalculator.cpp @@ -94,10 +94,7 @@ void RigSoilResultCalculator::calculate( const RigEclipseResultAddress& resVarAd timeStepIndex ); // Early exit if none of SWAT or SGAS is present - if ( scalarIndexSWAT == cvf::UNDEFINED_SIZE_T && scalarIndexSGAS == cvf::UNDEFINED_SIZE_T ) - { - return; - } + if ( scalarIndexSWAT == cvf::UNDEFINED_SIZE_T && scalarIndexSGAS == cvf::UNDEFINED_SIZE_T ) return; size_t soilResultValueCount = 0; size_t soilTimeStepCount = 0; @@ -124,8 +121,13 @@ void RigSoilResultCalculator::calculate( const RigEclipseResultAddress& resVarAd } } + // The result may be present in metadata but unavailable for this time step. + if ( soilResultValueCount == 0 ) return; + // Make sure memory is allocated for the new SOIL results size_t soilResultScalarIndex = m_resultsData->findScalarResultIndexFromAddress( resVarAddr ); + if ( soilResultScalarIndex == cvf::UNDEFINED_SIZE_T ) return; + m_resultsData->m_cellScalarResults[soilResultScalarIndex].resize( soilTimeStepCount ); if ( !m_resultsData->cellScalarResults( resVarAddr, timeStepIndex ).empty() ) @@ -143,28 +145,19 @@ void RigSoilResultCalculator::calculate( const RigEclipseResultAddress& resVarAd if ( scalarIndexSWAT != cvf::UNDEFINED_SIZE_T ) { swatForTimeStep = &( m_resultsData->cellScalarResults( SWATAddr, timeStepIndex ) ); - if ( swatForTimeStep->empty() ) - { - swatForTimeStep = nullptr; - } + if ( swatForTimeStep->empty() ) swatForTimeStep = nullptr; } if ( scalarIndexSGAS != cvf::UNDEFINED_SIZE_T ) { sgasForTimeStep = &( m_resultsData->cellScalarResults( SGASAddr, timeStepIndex ) ); - if ( sgasForTimeStep->empty() ) - { - sgasForTimeStep = nullptr; - } + if ( sgasForTimeStep->empty() ) sgasForTimeStep = nullptr; } if ( scalarIndexSSOL != cvf::UNDEFINED_SIZE_T ) { ssolForTimeStep = &( m_resultsData->cellScalarResults( SSOLAddr, timeStepIndex ) ); - if ( ssolForTimeStep->empty() ) - { - ssolForTimeStep = nullptr; - } + if ( ssolForTimeStep->empty() ) ssolForTimeStep = nullptr; } std::vector* soilForTimeStep = m_resultsData->modifiableCellScalarResult( resVarAddr, timeStepIndex ); diff --git a/ApplicationLibCode/ReservoirDataModel/RigCaseCellResultsData.cpp b/ApplicationLibCode/ReservoirDataModel/RigCaseCellResultsData.cpp index 9ba4e7c928..a874301773 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigCaseCellResultsData.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -1765,7 +1765,11 @@ size_t RigCaseCellResultsData::findOrLoadKnownScalarResultForTimeStep( const Rig if ( mustBeCalculated( soilScalarResultIndex ) ) { - m_cellScalarResults[soilScalarResultIndex].resize( maxTimeStepCount() ); + // A case in an ensemble can have fewer time steps than the case defining the time step axis + const size_t timeStepCount = maxTimeStepCount(); + if ( timeStepIndex >= timeStepCount ) return cvf::UNDEFINED_SIZE_T; + + m_cellScalarResults[soilScalarResultIndex].resize( timeStepCount ); std::vector& values = m_cellScalarResults[soilScalarResultIndex][timeStepIndex]; if ( values.empty() ) @@ -1782,7 +1786,11 @@ size_t RigCaseCellResultsData::findOrLoadKnownScalarResultForTimeStep( const Rig if ( mustBeCalculated( sgasScalarResultIndex ) ) { - m_cellScalarResults[sgasScalarResultIndex].resize( maxTimeStepCount() ); + // A case in an ensemble can have fewer time steps than the case defining the time step axis + const size_t timeStepCount = maxTimeStepCount(); + if ( timeStepIndex >= timeStepCount ) return cvf::UNDEFINED_SIZE_T; + + m_cellScalarResults[sgasScalarResultIndex].resize( timeStepCount ); if ( m_cellScalarResults[sgasScalarResultIndex][timeStepIndex].empty() ) { @@ -1817,6 +1825,9 @@ size_t RigCaseCellResultsData::findOrLoadKnownScalarResultForTimeStep( const Rig if ( type == RiaDefines::ResultCatType::DYNAMIC_NATIVE && timeStepCount > 0 ) { + // A case in an ensemble can have fewer time steps than the case defining the time step axis + if ( timeStepIndex >= timeStepCount ) return cvf::UNDEFINED_SIZE_T; + m_cellScalarResults[scalarResultIndex].resize( timeStepCount ); std::vector& values = m_cellScalarResults[scalarResultIndex][timeStepIndex];