mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 07:00:17 -05:00
#14901: Guard against crashes from corrupt Eclipse files and incomplete frustum
- RifEclipseOutputFileTools::timeSteps: avoid integer division by zero when the restart file has no INTEHEAD - libecl ecl_grid: return NULL when the main EGRID grid cannot be created, and skip NNCHEAD blocks that cannot be read - libecl well_info: skip wells when the restart header cannot be read - cvf::Frustum::isOutside: do not assert on an incomplete frustum, cull nothing Fixes #14901.
This commit is contained in:
1 parent
9722bfbaed
commit
92e269ef4d
6 files changed
+136
-8
No files matched your search
@@ -2,9 +2,25 @@
|
||||
|
||||
#include "cvfBoundingBox.h"
|
||||
#include "cvfCamera.h"
|
||||
#include "cvfFrustum.h"
|
||||
|
||||
using namespace cvf;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Camera::computeViewFrustum() returns an empty frustum for a degenerate projection matrix. View
|
||||
/// frustum culling in ModelBasicList::partVisible() then asserted in Frustum::isOutside().
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( CvfCameraCrashTriageTest, IncompleteFrustumDoesNotCull )
|
||||
{
|
||||
Frustum frustum;
|
||||
|
||||
BoundingBox bb;
|
||||
bb.add( Vec3d( 0, 0, 0 ) );
|
||||
bb.add( Vec3d( 1, 1, 1 ) );
|
||||
|
||||
EXPECT_FALSE( frustum.isOutside( bb ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// computeFitViewEyePosition() used to assert/abort (CVF_ASSERT in Plane::distanceToOrigin) when
|
||||
/// the view direction and up vector are parallel: dir^up then becomes a zero vector, producing an
|
||||
|
||||
@@ -23,8 +23,12 @@
|
||||
#include "RigEclipseCaseData.h"
|
||||
|
||||
#include "ert/ecl/ecl_kw_magic.h"
|
||||
#include <ert/ecl/ecl_endian_flip.h>
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_kw.h>
|
||||
#include <ert/ecl/fortio.h>
|
||||
#include <ert/ecl_well/well_info.hpp>
|
||||
|
||||
#include "RiaStringEncodingTools.h"
|
||||
#include "RiaTestDataDirectory.h"
|
||||
@@ -207,6 +211,101 @@ TEST( RigReservoirTest, OpenGridFileWithoutDimensKeyword )
|
||||
EXPECT_FALSE( readerInterfaceEcl->open( gridFileName, reservoir.p() ) );
|
||||
}
|
||||
|
||||
TEST( RigReservoirTest, OpenEgridWithInvalidGridHeader )
|
||||
{
|
||||
// ecl_grid_alloc_EGRID__() returns NULL for invalid grid dimensions. The caller dereferenced the NULL main
|
||||
// grid and crashed instead of returning NULL.
|
||||
QTemporaryDir tempDir;
|
||||
ASSERT_TRUE( tempDir.isValid() );
|
||||
|
||||
QString gridFileName = QDir( tempDir.path() ).filePath( "TEST.EGRID" );
|
||||
{
|
||||
std::vector<int> intData( 100, 0 );
|
||||
std::vector<float> floatData( 1, 0.0f );
|
||||
|
||||
fortio_type* fortio = fortio_open_writer( RiaStringEncodingTools::toNativeEncoded( gridFileName ).data(), false, ECL_ENDIAN_FLIP );
|
||||
ASSERT_TRUE( fortio );
|
||||
|
||||
auto writeKeyword = [fortio]( const char* name, int size, ecl_data_type type, const void* data )
|
||||
{
|
||||
ecl_kw_type* kw = ecl_kw_alloc_new( name, size, type, data );
|
||||
ecl_kw_fwrite( kw, fortio );
|
||||
ecl_kw_free( kw );
|
||||
};
|
||||
|
||||
// GRIDHEAD with zero grid dimensions is rejected
|
||||
writeKeyword( "FILEHEAD", (int)intData.size(), ECL_INT, intData.data() );
|
||||
writeKeyword( "GRIDHEAD", (int)intData.size(), ECL_INT, intData.data() );
|
||||
writeKeyword( "COORD", (int)floatData.size(), ECL_FLOAT, floatData.data() );
|
||||
writeKeyword( "ZCORN", (int)floatData.size(), ECL_FLOAT, floatData.data() );
|
||||
|
||||
fortio_fclose( fortio );
|
||||
}
|
||||
|
||||
EXPECT_EQ( nullptr, ecl_grid_alloc( RiaStringEncodingTools::toNativeEncoded( gridFileName ).data() ) );
|
||||
}
|
||||
|
||||
TEST( RigReservoirTest, ReadWellsFromRestartFileWithoutIntehead )
|
||||
{
|
||||
// ecl_rsthead_alloc() returns NULL when INTEHEAD is missing or unreadable (truncated file). The well reader
|
||||
// dereferenced the NULL header and crashed.
|
||||
QTemporaryDir tempDir;
|
||||
ASSERT_TRUE( tempDir.isValid() );
|
||||
|
||||
QString restartFileName = QDir( tempDir.path() ).filePath( "TEST.UNRST" );
|
||||
{
|
||||
std::vector<int> data( 1, 1 );
|
||||
ecl_kw_fwrite_param( RiaStringEncodingTools::toNativeEncoded( restartFileName ).data(),
|
||||
false,
|
||||
"SEQNUM",
|
||||
ECL_INT,
|
||||
(int)data.size(),
|
||||
data.data() );
|
||||
}
|
||||
|
||||
ecl_file_type* ecl_file = ecl_file_open( RiaStringEncodingTools::toNativeEncoded( restartFileName ).data(), 0 );
|
||||
ASSERT_TRUE( ecl_file );
|
||||
|
||||
well_info_type* wellInfo = well_info_alloc( { "GLOBAL" } );
|
||||
well_info_add_UNRST_wells( wellInfo, ecl_file, false );
|
||||
EXPECT_EQ( 0, well_info_get_num_wells( wellInfo ) );
|
||||
|
||||
well_info_free( wellInfo );
|
||||
ecl_file_close( ecl_file );
|
||||
}
|
||||
|
||||
TEST( RigReservoirTest, TimeStepsFromFileWithoutIntehead )
|
||||
{
|
||||
// A restart file without INTEHEAD gives no time steps, and computing the header keyword count per time step
|
||||
// divided by zero.
|
||||
QTemporaryDir tempDir;
|
||||
ASSERT_TRUE( tempDir.isValid() );
|
||||
|
||||
QString restartFileName = QDir( tempDir.path() ).filePath( "TEST.UNRST" );
|
||||
{
|
||||
std::vector<int> data( 1, 1 );
|
||||
ecl_kw_fwrite_param( RiaStringEncodingTools::toNativeEncoded( restartFileName ).data(),
|
||||
false,
|
||||
"SEQNUM",
|
||||
ECL_INT,
|
||||
(int)data.size(),
|
||||
data.data() );
|
||||
}
|
||||
|
||||
ecl_file_type* ecl_file = ecl_file_open( RiaStringEncodingTools::toNativeEncoded( restartFileName ).data(), 0 );
|
||||
ASSERT_TRUE( ecl_file );
|
||||
|
||||
std::vector<QDateTime> timeSteps;
|
||||
std::vector<double> daysSinceSimulationStart;
|
||||
size_t perTimeStepHeaderKeywordCount = 0;
|
||||
RifEclipseOutputFileTools::timeSteps( ecl_file, &timeSteps, &daysSinceSimulationStart, &perTimeStepHeaderKeywordCount );
|
||||
|
||||
EXPECT_TRUE( timeSteps.empty() );
|
||||
EXPECT_EQ( size_t( 0 ), perTimeStepHeaderKeywordCount );
|
||||
|
||||
ecl_file_close( ecl_file );
|
||||
}
|
||||
|
||||
TEST( RigReservoirTest, BasicTest10kRestart )
|
||||
{
|
||||
RifEclipseUnifiedRestartFileAccess unrstAccess;
|
||||
|
||||
Reference in new issue
Block a user