From 596bbb8fe11202a7a207e1645546ef558aa4d285 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Sat, 17 Oct 2026 10:09:18 +0200 Subject: [PATCH] Fix crash in sector model export of an inverted cell box A view without visible cells gives min > max, which underflowed the sector size and threw std::length_error when allocating the arrays. Call stack: [0] performCrashLogging at ResInsight/ApplicationExeCode/RiaMainTools.cpp:178 [1] manageSegFailureSA(int, siginfo_t*, void*) at ResInsight/ApplicationExeCode/RiaMainTools.cpp:310 [5] manageTerminate() at ResInsight/ApplicationExeCode/RiaMainTools.cpp:249 [12] RigResdataGridConverter::exportGrid(QString const&, RigEclipseCaseData*, bool, cvf::Array const*, cvf::Vector3 const&, cvf::Vector3 const&, cvf::Vector3 const&) at ResInsight/ApplicationLibCode/ReservoirDataModel/RigResdataGridConverter.cpp:83 [13] RicExportEclipseSectorModelFeature::exportGrid(RimEclipseView*, RicExportEclipseSectorModelUi const&) at ResInsight/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp:167 [14] RicExportEclipseSectorModelFeature::executeCommand(RimEclipseView*, RicExportEclipseSectorModelUi const&, QString const&) at ResInsight/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp:141 [15] RicExportEclipseSectorModelFeature::openDialogAndExecuteCommand(RimEclipseView*) at ResInsight/ApplicationLibCode/Commands/ExportCommands/RicExportEclipseSectorModelFeature.cpp:118 [16] caf::CmdFeature::actionTriggered(bool) at ResInsight/Fwk/AppFwk/cafCommand/cafCmdFeature.cpp:176 [25] RiaGuiApplication::notify(QObject*, QEvent*) at ResInsight/ApplicationLibCode/Application/RiaGuiApplication.cpp:1879 [31] RiaGuiApplication::notify(QObject*, QEvent*) at ResInsight/ApplicationLibCode/Application/RiaGuiApplication.cpp:1879 [43] RiuViewerCommands::displayContextMenu(QMouseEvent*) at ResInsight/ApplicationLibCode/UserInterface/RiuViewerCommands.cpp:702 [47] RiaGuiApplication::notify(QObject*, QEvent*) at ResInsight/ApplicationLibCode/Application/RiaGuiApplication.cpp:1879 [53] RiaGuiApplication::notify(QObject*, QEvent*) at ResInsight/ApplicationLibCode/Application/RiaGuiApplication.cpp:1879 [64] main at ResInsight/ApplicationExeCode/RiaMain.cpp:267 [65] __libc_start_main at :0 --- .../RigResdataGridConverter.cpp | 4 ++++ .../RigResdataGridConverter-Test.cpp | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/ApplicationLibCode/ReservoirDataModel/RigResdataGridConverter.cpp b/ApplicationLibCode/ReservoirDataModel/RigResdataGridConverter.cpp index 0689cd238d..6664f9a5b3 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigResdataGridConverter.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigResdataGridConverter.cpp @@ -54,6 +54,10 @@ bool RigResdataGridConverter::exportGrid( const QString& resultFileName, const RigMainGrid* mainGrid = eclipseCase->mainGrid(); cvf::Vec3st resolvedMax = max.isUndefined() ? cvf::Vec3st( mainGrid->cellCountI() - 1, mainGrid->cellCountJ() - 1, mainGrid->cellCountK() - 1 ) : max; + + // An inverted box, e.g. the visible cell range of a view without visible cells, underflows the sector size + if ( resolvedMax.x() < min.x() || resolvedMax.y() < min.y() || resolvedMax.z() < min.z() ) return false; + cvf::Vec3st sectorSize( resolvedMax.x() - min.x() + 1, resolvedMax.y() - min.y() + 1, resolvedMax.z() - min.z() + 1 ); RigGridExportAdapter gridAdapter( eclipseCase, min, resolvedMax, RigUniformRefinement( refinement, sectorSize ), cellVisibilityOverrideForActnum ); diff --git a/ApplicationLibCode/UnitTests/RigResdataGridConverter-Test.cpp b/ApplicationLibCode/UnitTests/RigResdataGridConverter-Test.cpp index 9eef821e74..1072a0d647 100644 --- a/ApplicationLibCode/UnitTests/RigResdataGridConverter-Test.cpp +++ b/ApplicationLibCode/UnitTests/RigResdataGridConverter-Test.cpp @@ -27,6 +27,7 @@ #include "RigActiveCellInfo.h" #include "RigEclipseCaseData.h" #include "RigMainGrid.h" +#include "RigReservoirBuilder.h" #include "RimEclipseResultCase.h" #include @@ -727,3 +728,26 @@ TEST( RigResdataGridConverterTest, CornerPointArrayConversion ) EXPECT_TRUE( hasNonZeroZcorn ) << "ZCORN array is all zeros"; EXPECT_TRUE( hasActiveCell ) << "No active cells found"; } + +//-------------------------------------------------------------------------------------------------- +/// An inverted box (min > max), e.g. the visible cell range of a view with no visible cells, +/// underflowed the sector size and threw std::length_error when allocating the export arrays +//-------------------------------------------------------------------------------------------------- +TEST( RigResdataGridConverterTest, ExportGridWithInvertedBoxFails ) +{ + RigReservoirBuilder builder; + builder.setIJKCount( cvf::Vec3st( 3, 3, 3 ) ); + builder.setWorldCoordinates( cvf::Vec3d( 0.0, 0.0, 0.0 ), cvf::Vec3d( 3.0, 3.0, -3.0 ) ); + + cvf::ref eclipseCase = new RigEclipseCaseData( nullptr ); + builder.createGridsAndCells( eclipseCase.p() ); + eclipseCase->mainGrid()->computeCachedData(); + + QTemporaryDir tempDir; + ASSERT_TRUE( tempDir.isValid() ); + QString fileName = tempDir.filePath( "GRID.GRDECL" ); + + cvf::Vec3st min( 2, 2, 2 ); + cvf::Vec3st max( 0, 0, 0 ); + EXPECT_FALSE( RigResdataGridConverter::exportGrid( fileName, eclipseCase.p(), false, nullptr, min, max, cvf::Vec3st( 1, 1, 1 ) ) ); +}