diff --git a/ApplicationLibCode/UnitTests/RifReaderEclipseSummary-Test.cpp b/ApplicationLibCode/UnitTests/RifReaderEclipseSummary-Test.cpp index b14d895ada..4be9b6914f 100644 --- a/ApplicationLibCode/UnitTests/RifReaderEclipseSummary-Test.cpp +++ b/ApplicationLibCode/UnitTests/RifReaderEclipseSummary-Test.cpp @@ -27,6 +27,8 @@ #include #include +#include +#include #include @@ -52,6 +54,30 @@ TEST( RifEclEclipseSummary, TestConversionFromNativeCompletionSyntax ) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( RifEclipseSummaryToolsTest, FindSummaryFilesWithDirectoryNamedAsCase ) +{ + // Reproduces https://github.com/OPM/ResInsight/issues/14370: finding the CASE.Snnnn summary data + // files crashed when a non-empty directory with the same name as the case exists next to the files. + QTemporaryDir tempDir; + ASSERT_TRUE( tempDir.isValid() ); + + QDir dir( tempDir.path() ); + ASSERT_TRUE( dir.mkpath( "CASE" ) ); + + for ( const QString& fileName : + { QString( "CASE.SMSPEC" ), QString( "CASE.S0001" ), QString( "CASE.S0002" ), QString( "CASE/ANYFILE.txt" ) } ) + { + QFile file( dir.filePath( fileName ) ); + ASSERT_TRUE( file.open( QIODevice::WriteOnly ) ); + file.write( "dummy" ); + } + + EXPECT_TRUE( RifEclipseSummaryTools::hasSummaryDataFiles( dir.filePath( "CASE.SMSPEC" ) ) ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ThirdParty/Ert/lib/ecl/ecl_util.cpp b/ThirdParty/Ert/lib/ecl/ecl_util.cpp index cc7c921e81..1692b5a107 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_util.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_util.cpp @@ -544,6 +544,9 @@ int ecl_util_fname_report_cmp(const void *f1, const void *f2) { */ static bool numeric_extension_predicate(const char * filename, const char * base, const char leading_char) { + if (!filename || !base) + return false; + if (strncmp(filename, base, strlen(base)) != 0) return false; @@ -604,6 +607,21 @@ static int ecl_util_select_predicate_filelist(const char * path, const char * ba { char * tmp = util_alloc_filename(path, base, NULL); util_alloc_file_components(tmp, &full_path, &pure_base, NULL); + if (!pure_base) { + /* If an existing directory has the same name as the full case path, + util_alloc_file_components() treats the whole string as a path and + returns NULL for the basename. Split on the last path separator + instead to recover the intended base. */ + const char * last_sep = strrchr(tmp, UTIL_PATH_SEP_CHAR); + free(full_path); + if (last_sep) { + full_path = util_alloc_substring_copy(tmp, 0, last_sep - tmp); + pure_base = util_alloc_string_copy(last_sep + 1); + } else { + full_path = NULL; + pure_base = util_alloc_string_copy(tmp); + } + } free(tmp); }