Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
abe634c
enforce refArray regex
arng40 Nov 4, 2025
e03d340
xsd
arng40 Nov 4, 2025
dc6c48f
Merge branch 'develop' into bugfix/dudes/rtt-sourceflux
arng40 Nov 5, 2025
b015667
add regex spaces
arng40 Nov 5, 2025
d237499
Merge branch 'bugfix/dudes/rtt-sourceflux' of https://github.com/GEOS…
arng40 Nov 5, 2025
77c7b3e
uncrustify
arng40 Nov 5, 2025
ff77135
fix test
arng40 Nov 7, 2025
e8be705
Merge branch 'develop' into bugfix/dudes/rtt-sourceflux
arng40 Nov 21, 2025
b89c41a
add & update test
arng40 Nov 21, 2025
071b15c
Merge branch 'develop' into bugfix/dudes/rtt-sourceflux
arng40 Nov 24, 2025
95710e3
add tests and update validation regex
arng40 Dec 2, 2025
f2724e4
add test for refArray
arng40 Dec 2, 2025
e53891a
Merge branch 'develop' into bugfix/dudes/rtt-sourceflux
arng40 Dec 2, 2025
c5513f4
uncrust
arng40 Dec 2, 2025
1a51f53
try to remove std::ws
arng40 Dec 3, 2025
05c7ae1
try to trimed
arng40 Dec 3, 2025
332370c
uncrustify
arng40 Dec 4, 2025
3dafc57
review adressed
arng40 Dec 5, 2025
768a9cc
Merge branch 'develop' into bugfix/dudes/rtt-sourceflux
arng40 Dec 10, 2025
21a424a
Merge branch 'develop' into bugfix/dudes/rtt-sourceflux
arng40 Dec 15, 2025
4a08915
remove useless code & add test for non array
arng40 Dec 19, 2025
731d29d
Merge branch 'develop' into bugfix/dudes/rtt-sourceflux
arng40 Dec 19, 2025
5d57b45
Merge branch 'develop' into bugfix/dudes/rtt-sourceflux
arng40 Dec 22, 2025
a17d0f4
Merge remote-tracking branch 'origin/develop' into bugfix/dudes/rtt-s…
arng40 Jan 7, 2026
26988ae
remove assert
arng40 Jan 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/coreComponents/codingUtilities/RTTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ rtTypes::RegexMapType rtTypes::createBasicTypesRegexMap()
// string_view const ru = "[\\d]+";// unused

string_view const intDesc = "Input value must be a signed int (eg. -123, 455, +789, etc.)";
string_view const intRegex = "[+-]?[\\d]+";
string_view const intRegex = "\\s*[+-]?[\\d]+\\s*";

// Explanation of parts:
// [+-]?[\\d]* matches an optional +/- at the beginning, any numbers preceding the decimal
Expand All @@ -160,28 +160,31 @@ rtTypes::RegexMapType rtTypes::createBasicTypesRegexMap()
// ([eE][-+]?[\\d]+|\\s*) matches an optional scientific notation number
// Note: the xsd regex implementation does not allow an empty branch, so use allow whitespace at the end
string_view const realDesc = "Input value must be a real number (eg. 1, .25, +2.3, -.4, 5.6e7, -8E-9, etc.)";
string_view const realRegex = "[+-]?[\\d]*([\\d]\\.?|\\.[\\d])[\\d]*([eE][-+]?[\\d]+|\\s*)";
string_view const realRegex = "\\s*[+-]?[\\d]*([\\d]\\.?|\\.[\\d])[\\d]*([eE][-+]?[\\d]+|\\s*)";

string_view const R1Desc = "Input value must be a R1Tensor, an array of 3 real numbers surrounded by braces and separated by commas (eg. \"{ 1, .25, +2.3}\", \"{ -.4, 5.6e7, -8E-9\", etc.) .";
string const R1Regex = "\\s*\\{\\s*(" + string( realRegex ) + "\\s*,\\s*){2}" + string( realRegex ) + "\\s*\\}\\s*";
string_view const R2Desc = "Input value must be a R2SymTensor, an array of 6 real numbers surrounded by braces and separated by commas (eg. \"{ 1, .25, +2.3, -.4, 5.6e7, -8E-9\", etc.) .";
string const R2Regex = "\\s*\\{\\s*(" + string( realRegex ) + "\\s*,\\s*){5}" + string( realRegex ) + "\\s*\\}\\s*";

string_view const strDesc = "Input value must be a string that cannot be empty, contain any whitespaces nor the characters , { }";
string_view const strRegex = "[^,\\{\\}\\s]+\\s*";
string_view const strRegex = "\\s*[^,\\{\\}\\s]+\\s*";
string_view const strEDesc = "Input value must be a string that cannot contain any whitespaces nor the characters , { }";
string_view const strERegex = "[^,\\{\\}\\s]*\\s*";
string_view const strERegex = "\\s*[^,\\{\\}\\s]*\\s*";

string_view const pathDesc = "Input value must be a string that cannot be empty, contain any whitespaces nor the characters * ? < > | : \" ";
string_view const pathRegex = "[^*?<>\\|:\";,\\s]+\\s*";
string_view const pathRegex = "\\s*[^*?<>\\|:\";,\\s]+\\s*";
string_view const pathEDesc = "Input value must be a string that cannot contain any whitespaces nor the characters * ? < > | : \" ";
string_view const pathERegex = "[^*?<>\\|:\";,\\s]*\\s*";
string_view const pathERegex = "\\s*[^*?<>\\|:\";,\\s]*\\s*";

string_view const groupNameDesc = "Input value must be a string that cannot be empty and contains only upper/lower letters, digits, and the characters . - _";
string_view const groupNameRegex = "[a-zA-Z0-9.\\-_]+";
string_view const groupNameRegex = "\\s*[a-zA-Z0-9.\\-_]+\\s*";
// to reference groups, we need to support the / for paths, and * [ ] for fnmatch patterns.
string_view const groupNameRefDesc = "Input value must be a string that can contain only upper/lower letters, digits, and the characters . - _ / * [ ]";
string_view const groupNameRefRegex = "[a-zA-Z0-9.\\-_/*\\[\\]]*";
string_view const groupNameRefRegex = "\\s*[a-zA-Z0-9.\\-_/*\\[\\]]*\\s*";
// to reference an array of groups, we need to support the / for paths, and * [ ] for fnmatch patterns.
string_view const groupNameRefArrayDesc = "Input value must be a list of strings that can contain only upper/lower letters, digits, and the characters . - _ / * [ ]";
string_view const groupNameRefArrayRegex = "\\s*\\{([a-zA-Z0-9.\\-_/*\\[\\], ]+)*\\}\\s*";


// Build master list of regexes
Expand Down Expand Up @@ -220,7 +223,7 @@ rtTypes::RegexMapType rtTypes::createBasicTypesRegexMap()
{ string( CustomTypes::plotLevel ), Regex( intRegex, intDesc ) },
{ string( CustomTypes::groupName ), Regex( groupNameRegex, groupNameDesc ) },
{ string( CustomTypes::groupNameRef ), Regex( groupNameRefRegex, groupNameRefDesc ) },
{ string( CustomTypes::groupNameRefArray ), constructArrayRegex( groupNameRefRegex, groupNameRefDesc, 1 ) }
{ string( CustomTypes::groupNameRefArray ), Regex( groupNameRefArrayRegex, groupNameRefArrayDesc ) }
};
return regexMap;
}
Expand Down
107 changes: 99 additions & 8 deletions src/coreComponents/dataRepository/unitTests/testXmlWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ INSTANTIATE_TEST_SUITE_P(
real64AttributeTests,
real64AttributeTestFixture,
::testing::Values( std::make_tuple( "1", 1, false ),
std::make_tuple( "1 ", 1, false ),
std::make_tuple( " 1", 1, false ),
std::make_tuple( " 1 ", 1, false ),
std::make_tuple( "-23", -23, false ),
std::make_tuple( "4.5", 4.5, false ),
std::make_tuple( "4.", 4.0, false ),
Expand All @@ -260,7 +263,6 @@ INSTANTIATE_TEST_SUITE_P(
std::make_tuple( "1.234gamma", 0, true ),
std::make_tuple( "1.2.3", 0, true ),
std::make_tuple( "1e2.3 ", 0, true ),
std::make_tuple( "1 ", 0, true ),
std::make_tuple( "1e", 0, true ),
std::make_tuple( "1e-", 0, true ),
std::make_tuple( "1e+", 0, true )));
Expand All @@ -284,6 +286,9 @@ INSTANTIATE_TEST_SUITE_P(
real32AttributeTests,
real32AttributeTestFixture,
::testing::Values( std::make_tuple( "1", 1, false ),
std::make_tuple( "1 ", 1, false ),
std::make_tuple( " 1", 1, false ),
std::make_tuple( " 1 ", 1, false ),
std::make_tuple( "-23", -23, false ),
std::make_tuple( "4.5", 4.5, false ),
std::make_tuple( "4.", 4.0, false ),
Expand All @@ -301,7 +306,6 @@ INSTANTIATE_TEST_SUITE_P(
std::make_tuple( "1.234gamma", 0, true ),
std::make_tuple( "1.2.3", 0, true ),
std::make_tuple( "1e2.3 ", 0, true ),
std::make_tuple( "1 ", 0, true ),
std::make_tuple( "1e", 0, true ),
std::make_tuple( "1e-", 0, true ),
std::make_tuple( "1e+", 0, true )));
Expand All @@ -319,13 +323,15 @@ INSTANTIATE_TEST_SUITE_P(
integerAttributeTests,
integerAttributeTestFixture,
::testing::Values( std::make_tuple( "1", 1, false ),
std::make_tuple( "1 ", 1, false ),
std::make_tuple( " 1", 1, false ),
std::make_tuple( " 1 ", 1, false ),
std::make_tuple( "-23", -23, false ),
std::make_tuple( "4.5", 0, true ),
std::make_tuple( "4.", 0, true ),
std::make_tuple( "alpha", 0, true ),
std::make_tuple( "1beta234", 0, true ),
std::make_tuple( "1234gamma", 0, true ),
std::make_tuple( "1 ", 0, true ),
std::make_tuple( "1 2", 0, true )));


Expand Down Expand Up @@ -374,12 +380,14 @@ TEST( testXmlWrapper, testGroupNamesFormats )
GroupNameTest( groupNameRegex, "testname01" ),
GroupNameTest( groupNameRegex, "test_name" ),
GroupNameTest( groupNameRegex, "test-name" ),
GroupNameTest( groupNameRegex, "test.name" ),
GroupNameTest( groupNameRegex, " testname " ),
GroupNameTest( groupNameRegex, " \t testname \n " ),
};
for( GroupNameTest const & input : workingInputs )
{
EXPECT_NO_THROW( xmlWrapper::stringToInputVariable( groupName, input.m_valueToTest, input.m_regex ) );
EXPECT_STREQ( input.m_valueToTest.c_str(), groupName.c_str() );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the place that needs to be reworked.

EXPECT_NO_THROW( xmlWrapper::stringToInputVariable( groupName, input.m_valueToTest, input.m_regex ) )
<< "Parsing input '"<< input.m_valueToTest
<< "' with regex '" << input.m_regex.m_regexStr << "' didn't throw an InputError as expected.";;
}
}
{
Expand All @@ -391,13 +399,96 @@ TEST( testXmlWrapper, testGroupNamesFormats )
//white spaces
GroupNameTest( groupNameRegex, "test name" ),
GroupNameTest( groupNameRegex, "test\tname" ),
GroupNameTest( groupNameRegex, "testname " ),
GroupNameTest( groupNameRegex, " testname" ),
//fordbiden characters
GroupNameTest( groupNameRegex, "test/name" ),
GroupNameTest( groupNameRegex, "test:name" ),
GroupNameTest( groupNameRegex, "test;name" ),
GroupNameTest( groupNameRegex, "test\\name" ),
GroupNameTest( groupNameRegex, "{[arrayElement]}" ),
GroupNameTest( groupNameRegex, "{name1,name2,name3}" ),
};
for( GroupNameTest const & input : erroneousInputs )
{
EXPECT_THROW( xmlWrapper::stringToInputVariable( groupName, input.m_valueToTest, input.m_regex ),
InputError ) << "Parsing input '"<< input.m_valueToTest
<< "' with regex '" << input.m_regex.m_regexStr << "' didn't throw an InputError as expected.";
}
}
}
TEST( testXmlWrapper, testGroupNamesArrayFormats )
{
struct GroupNameTest
{
Regex const & m_regex;
string m_valueToTest;
GroupNameTest( Regex const & regex, string_view valueToTest ):
m_regex( regex ), m_valueToTest( valueToTest ) {}
};

Regex const & groupNameRefArrayRegex = rtTypes::getTypeRegex< string >( rtTypes::CustomTypes::groupNameRefArray );
string groupName;

{
stdVector< GroupNameTest > workingInputs = {
GroupNameTest( groupNameRefArrayRegex, "{}" ),
GroupNameTest( groupNameRefArrayRegex, " {} " ),
GroupNameTest( groupNameRefArrayRegex, " \t {} \n " ),
GroupNameTest( groupNameRefArrayRegex, "{groupName}" ),
GroupNameTest( groupNameRefArrayRegex, "{123name}" ),
GroupNameTest( groupNameRefArrayRegex, "{name123}" ),
GroupNameTest( groupNameRefArrayRegex, "{a-Z0-9./*[]-_,}" ),
GroupNameTest( groupNameRefArrayRegex, "{name.with-special_chars}" ),
GroupNameTest( groupNameRefArrayRegex, "{path/to/resource*}" ),
GroupNameTest( groupNameRefArrayRegex, "{[arrayElement]}" ),
GroupNameTest( groupNameRefArrayRegex, "{name1,name2,name3}" ),
};
for( GroupNameTest const & input : workingInputs )
{
EXPECT_NO_THROW( xmlWrapper::stringToInputVariable( groupName, input.m_valueToTest, input.m_regex ) );
}
}
{
stdVector< GroupNameTest > erroneousInputs = {
GroupNameTest( groupNameRefArrayRegex, "" ),
GroupNameTest( groupNameRefArrayRegex, " " ),
GroupNameTest( groupNameRefArrayRegex, " \t " ),
GroupNameTest( groupNameRefArrayRegex, "{\t}" ),
GroupNameTest( groupNameRefArrayRegex, "{test:name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test;name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test\\name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test|name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test^name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test$name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test&name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test#name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test!name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test%name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test@name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test(name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test)name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test=name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test+name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test<name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test>name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test\tname}" ),
GroupNameTest( groupNameRefArrayRegex, "{test\nname}" ),
GroupNameTest( groupNameRefArrayRegex, "{test\rname}" ),
GroupNameTest( groupNameRefArrayRegex, "groupName" ),
GroupNameTest( groupNameRefArrayRegex, "{groupName" ),
GroupNameTest( groupNameRefArrayRegex, "groupName}" ),
GroupNameTest( groupNameRefArrayRegex, "{groupName}} " ),
GroupNameTest( groupNameRefArrayRegex, "{}groupName" ),
GroupNameTest( groupNameRefArrayRegex, "groupName{}" ),
GroupNameTest( groupNameRefArrayRegex, "{hello, \t\n\r ,world}" ),
GroupNameTest( groupNameRefArrayRegex, "test{groupName}" ),
GroupNameTest( groupNameRefArrayRegex, "{groupName}test" ),
GroupNameTest( groupNameRefArrayRegex, "{groupName} test" ),
GroupNameTest( groupNameRefArrayRegex, "{element with space, another}" ),
GroupNameTest( groupNameRefArrayRegex, "{element, element with space, 123.456, a-b}" ),
GroupNameTest( groupNameRefArrayRegex, "{ space at ends } " ),
GroupNameTest( groupNameRefArrayRegex, "{valuewith,,commas }" ),
GroupNameTest( groupNameRefArrayRegex, "{ value with , commas }" ),
GroupNameTest( groupNameRefArrayRegex, "{{groupname}}" ),
};
for( GroupNameTest const & input : erroneousInputs )
{
Expand Down
4 changes: 2 additions & 2 deletions src/coreComponents/dataRepository/xmlWrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ std::enable_if_t< traits::CanStreamInto< std::istringstream, T > >
stringToInputVariable( T & target, string const & value, Regex const & regex )
{
validateString( value, regex );

std::istringstream ss( value );
string_view stringTrimed = stringutilities::trimSpaces( value );
std::istringstream ss( (string( stringTrimed )) );
ss >> target;
GEOS_THROW_IF( ss.fail() || !ss.eof(),
"Error detected while parsing string \"" << value <<
Expand Down
Loading
Loading