Skip to content

Commit

Permalink
parser: more robust handling of number syntax errors
Browse files Browse the repository at this point in the history
stoi and stod functions are quite permissive and can ignore part of the
input string leaving it not entirely parsed.  Sometimes this could
result in invalid number strings being parsed as valid.  For example
"3ee10" is parsed as the value "3".  This change fixes that and requires
sto[i/d] to parse the entire string.  Any corresponding errors are not
added to the _errmsg collection variable and printed together with
other errors all at once instead of one at a time.

fixes idaholab#10310
  • Loading branch information
rwcarlsen committed Nov 27, 2017
1 parent 4aaa6f5 commit 159d78b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 6 deletions.
21 changes: 15 additions & 6 deletions framework/src/parser/Parser.C
Expand Up @@ -1244,6 +1244,9 @@ Parser::setScalarParameter(const std::string & full_name,
}
catch (hit::Error & err)
{
auto strval = _root->param<std::string>(full_name);
size_t pos = 0;

// handle the case where the user put a number inside quotes - we really shouldn't allow this,
// but "backwards compatibility" :-(
auto & t = typeid(T);
Expand All @@ -1252,34 +1255,40 @@ Parser::setScalarParameter(const std::string & full_name,
{
try
{
auto v = std::stoi(_root->param<std::string>(full_name));
auto v = std::stoi(strval, &pos);
param->set() = *reinterpret_cast<T *>(&v);
if (pos != strval.size())
throw "foo"; // catch below and print error
}
catch (...)
{
mooseError(errormsg(_input_filename,
_errmsg += errormsg(_input_filename,
_root->find(full_name),
"invalid integer syntax for parameter: ",
full_name,
"=",
_root->param<std::string>(full_name)));
strval) +
"\n";
}
}
else if (t == typeid(double))
{
try
{
auto v = std::stod(_root->param<std::string>(full_name));
auto v = std::stod(strval, &pos);
param->set() = *reinterpret_cast<T *>(&v);
if (pos != strval.size())
throw "foo"; // catch below and print error
}
catch (...)
{
mooseError(errormsg(_input_filename,
_errmsg += errormsg(_input_filename,
_root->find(full_name),
"invalid float syntax for parameter: ",
full_name,
"=",
_root->param<std::string>(full_name)));
strval) +
"\n";
}
}
else
Expand Down
43 changes: 43 additions & 0 deletions test/tests/misc/check_error/bad_number.i
@@ -0,0 +1,43 @@
[Mesh]
type = GeneratedMesh
dim = 1
nx = 10
[]

[Variables]
[./u]
[../]
[]

[Kernels]
[./diff]
type = Diffusion
variable = u
[../]
[]

[BCs]
[./left]
type = DirichletBC
variable = u
boundary = left
value = 0
[../]
[./right]
type = DirichletBC
variable = u
boundary = right
value = 1.2eE
[../]
[]

[Executioner]
type = Steady
solve_type = 'PJFNK'
petsc_options_iname = '-pc_type -pc_hypre_type'
petsc_options_value = 'hypre boomeramg'
[]

[Outputs]
exodus = true
[]
7 changes: 7 additions & 0 deletions test/tests/misc/check_error/tests
Expand Up @@ -558,4 +558,11 @@
expect_out = "Function name 'x' could evaluate as a ParsedFunction"
allow_warnings = true
[../]

[./bad_number]
# Check to see if a warning is produced when a function name could evaluate to a ParsedFunction
type = 'RunException'
input = 'bad_number.i'
expect_err = "invalid float syntax for parameter: BCs/right/value"
[../]
[]

0 comments on commit 159d78b

Please sign in to comment.