fix #190: Merge branch 'throw-when-overflow'

This commit is contained in:
ToruNiina
2022-06-08 01:26:56 +09:00
3 changed files with 57 additions and 0 deletions

View File

@@ -176,3 +176,10 @@ BOOST_AUTO_TEST_CASE(test_nan)
BOOST_CHECK(std::isnan(r.unwrap().first));
}
}
BOOST_AUTO_TEST_CASE(test_overflow)
{
std::istringstream float_overflow (std::string("float-overflow = 1.0e+1024"));
BOOST_CHECK_THROW(toml::parse(float_overflow ), toml::syntax_error);
// istringstream >> float does not set failbit in case of underflow.
}

View File

@@ -90,3 +90,15 @@ BOOST_AUTO_TEST_CASE(test_bin_value)
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0b01_00_00", value(16));
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0b111111", value(63));
}
BOOST_AUTO_TEST_CASE(test_integer_overflow)
{
std::istringstream dec_overflow(std::string("dec-overflow = 9223372036854775808"));
std::istringstream hex_overflow(std::string("hex-overflow = 0x1_00000000_00000000"));
std::istringstream oct_overflow(std::string("oct-overflow = 0o1_000_000_000_000_000_000_000"));
std::istringstream bin_overflow(std::string("bin-overflow = 0b1_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000"));
BOOST_CHECK_THROW(toml::parse(dec_overflow), toml::syntax_error);
BOOST_CHECK_THROW(toml::parse(hex_overflow), toml::syntax_error);
BOOST_CHECK_THROW(toml::parse(oct_overflow), toml::syntax_error);
BOOST_CHECK_THROW(toml::parse(bin_overflow), toml::syntax_error);
}

View File

@@ -57,6 +57,12 @@ parse_binary_integer(location& loc)
{
auto str = token.unwrap().str();
assert(str.size() > 2); // minimum -> 0b1
if(64 <= str.size())
{
// since toml11 uses int64_t, 64bit (unsigned) input cannot be read.
return err(format_underline("toml::parse_binary_integer:",
{{source_location(loc), "too large input (> int64_t)"}}));
}
integer retval(0), base(1);
for(auto i(str.rbegin()), e(str.rend() - 2); i!=e; ++i)
{
@@ -91,6 +97,20 @@ parse_octal_integer(location& loc)
std::istringstream iss(str);
integer retval(0);
iss >> std::oct >> retval;
if(iss.fail())
{
// `istream` sets `failbit` if internally-called `std::num_get::get`
// fails.
// `std::num_get::get` calls `std::strtoll` if the argument type is
// signed.
// `std::strtoll` fails if
// - the value is out_of_range or
// - no conversion is possible.
// since we already checked that the string is valid octal integer,
// so the error reason is out_of_range.
return err(format_underline("toml::parse_octal_integer:",
{{source_location(loc), "out of range"}}));
}
return ok(std::make_pair(retval, token.unwrap()));
}
loc.reset(first);
@@ -111,6 +131,12 @@ parse_hexadecimal_integer(location& loc)
std::istringstream iss(str);
integer retval(0);
iss >> std::hex >> retval;
if(iss.fail())
{
// see parse_octal_integer for detail of this error message.
return err(format_underline("toml::parse_hexadecimal_integer:",
{{source_location(loc), "out of range"}}));
}
return ok(std::make_pair(retval, token.unwrap()));
}
loc.reset(first);
@@ -157,6 +183,12 @@ parse_integer(location& loc)
std::istringstream iss(str);
integer retval(0);
iss >> retval;
if(iss.fail())
{
// see parse_octal_integer for detail of this error message.
return err(format_underline("toml::parse_integer:",
{{source_location(loc), "out of range"}}));
}
return ok(std::make_pair(retval, token.unwrap()));
}
loc.reset(first);
@@ -245,6 +277,12 @@ parse_floating(location& loc)
std::istringstream iss(str);
floating v(0.0);
iss >> v;
if(iss.fail())
{
// see parse_octal_integer for detail of this error message.
return err(format_underline("toml::parse_floating:",
{{source_location(loc), "out of range"}}));
}
return ok(std::make_pair(v, token.unwrap()));
}
loc.reset(first);