mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 07:00:17 -05:00
Fix crash on stale cell selection when creating highlight part
RivSingleCellPartGenerator uses the grid and cell index stored in the 3D selection item. These are plain indices, and they are not revalidated when the case data is rebuilt behind a live selection. Both RigMainGrid::gridByIndex() and RigGridBase::cell() guard only with CVF_ASSERT, so in release builds a stale index reads out of bounds and the resulting garbage corner indices crash in RigGridBase::cellCornerVertices(). Validate the grid and cell index before creating the mesh drawable.
This commit is contained in:
1 parent
d30d5e7817
commit
842520c5e9
3 files changed
+117
No files matched your search
@@ -228,9 +228,17 @@ cvf::ref<cvf::DrawableGeo> RivSingleCellPartGenerator::createMeshDrawable()
|
||||
{
|
||||
if ( m_rigCaseData && m_cellIndex != cvf::UNDEFINED_SIZE_T )
|
||||
{
|
||||
auto mainGrid = m_rigCaseData->mainGrid();
|
||||
if ( !mainGrid ) return nullptr;
|
||||
|
||||
if ( m_gridIndex >= mainGrid->gridCount() ) return nullptr;
|
||||
|
||||
auto grid = m_rigCaseData->grid( m_gridIndex );
|
||||
if ( !grid ) return nullptr;
|
||||
|
||||
// The selection can be stale after the case data has been reloaded, and the cell index can be out of bounds
|
||||
if ( m_cellIndex >= grid->cellCount() ) return nullptr;
|
||||
|
||||
if ( m_showLgrMeshLines && RiaPreferencesGrid::current()->radialGridMode() == RiaGridDefines::RadialGridMode::CYLINDRICAL )
|
||||
{
|
||||
return createMeshDrawableFromLgrGridCells();
|
||||
|
||||
@@ -37,6 +37,7 @@ set(SOURCE_UNITTEST_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RivAnnotationTools-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RivPipeGeometryGenerator-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RivIjkIntersectionGeometryGenerator-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RivSingleCellPartGenerator-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RivTernaryScalarMapper-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ScalarMapper-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/WellPathAsciiFileReader-Test.cpp
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2026- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigReservoirBuilder.h"
|
||||
|
||||
#include "RivSingleCellPartGenerator.h"
|
||||
|
||||
#include "cvfPart.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Build a regular ni x nj x nk box grid in memory (no file, no view)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<RigEclipseCaseData> buildBoxGrid( int ni, int nj, int nk )
|
||||
{
|
||||
RigReservoirBuilder builder;
|
||||
builder.setIJKCount( cvf::Vec3st( ni, nj, nk ) );
|
||||
builder.setWorldCoordinates( cvf::Vec3d( 0.0, 0.0, 0.0 ), cvf::Vec3d( ni, nj, -nk ) );
|
||||
|
||||
cvf::ref<RigEclipseCaseData> caseData = new RigEclipseCaseData( nullptr );
|
||||
builder.createGridsAndCells( caseData.p() );
|
||||
caseData->mainGrid()->computeCachedData();
|
||||
|
||||
return caseData;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RivSingleCellPartGeneratorTest, ValidCellIndexCreatesDrawable )
|
||||
{
|
||||
cvf::ref<RigEclipseCaseData> caseData = buildBoxGrid( 2, 3, 4 );
|
||||
|
||||
RivSingleCellPartGenerator partGen( caseData.p(), 0, 5, cvf::Vec3d::ZERO );
|
||||
|
||||
cvf::ref<cvf::Part> part = partGen.createPart( cvf::Color3f::RED );
|
||||
ASSERT_TRUE( part.notNull() );
|
||||
EXPECT_TRUE( part->drawable() != nullptr );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// A stale selection can reference a cell index no longer present in the grid
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RivSingleCellPartGeneratorTest, CellIndexOutOfBoundsIsIgnored )
|
||||
{
|
||||
cvf::ref<RigEclipseCaseData> caseData = buildBoxGrid( 2, 3, 4 );
|
||||
|
||||
const size_t cellCount = caseData->mainGrid()->cellCount();
|
||||
|
||||
for ( size_t cellIndex : { cellCount, cellCount + 1000 } )
|
||||
{
|
||||
RivSingleCellPartGenerator partGen( caseData.p(), 0, cellIndex, cvf::Vec3d::ZERO );
|
||||
|
||||
cvf::ref<cvf::Part> part = partGen.createPart( cvf::Color3f::RED );
|
||||
ASSERT_TRUE( part.notNull() );
|
||||
EXPECT_TRUE( part->drawable() == nullptr );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// A stale selection can reference a grid no longer present in the case
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RivSingleCellPartGeneratorTest, GridIndexOutOfBoundsIsIgnored )
|
||||
{
|
||||
cvf::ref<RigEclipseCaseData> caseData = buildBoxGrid( 2, 3, 4 );
|
||||
|
||||
RivSingleCellPartGenerator partGen( caseData.p(), 1, 0, cvf::Vec3d::ZERO );
|
||||
|
||||
cvf::ref<cvf::Part> part = partGen.createPart( cvf::Color3f::RED );
|
||||
ASSERT_TRUE( part.notNull() );
|
||||
EXPECT_TRUE( part->drawable() == nullptr );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RivSingleCellPartGeneratorTest, UndefinedCellIndexIsIgnored )
|
||||
{
|
||||
cvf::ref<RigEclipseCaseData> caseData = buildBoxGrid( 2, 3, 4 );
|
||||
|
||||
RivSingleCellPartGenerator partGen( caseData.p(), 0, cvf::UNDEFINED_SIZE_T, cvf::Vec3d::ZERO );
|
||||
|
||||
cvf::ref<cvf::Part> part = partGen.createPart( cvf::Color3f::RED );
|
||||
ASSERT_TRUE( part.notNull() );
|
||||
EXPECT_TRUE( part->drawable() == nullptr );
|
||||
}
|
||||
Reference in new issue
Block a user