Skip to content

Commit

Permalink
Fix more handling of bad float strings.
Browse files Browse the repository at this point in the history
Fixes #308.
jtv committed Apr 23, 2020
1 parent 2d68a92 commit 29468ef
Showing 3 changed files with 29 additions and 4 deletions.
2 changes: 1 addition & 1 deletion NEWS
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
- Prefer `pg_config` over `pkg-config` for include path (#291).
- Try to plod on if we don't know the PostgreSQL include path.
- Fix error message when starting overlapping transactions and such (#303).
- Fix potential crash when "NaN" isn't 3 bytes long (#307).
- Fix potential crashes when converting invalid strings to floats (#307, #308).
7.0.5
- Compile fix for g++ 10: include `<limits>` (#292).
- Cleaned up error-checking of PG results. (#280).
9 changes: 6 additions & 3 deletions src/strconv.cxx
Original file line number Diff line number Diff line change
@@ -470,6 +470,10 @@ inline bool from_dumb_stringstream(
// These are hard, and popular compilers do not yet implement std::from_chars.
template<typename T> inline T from_string_awful_float(std::string_view text)
{
if (text.empty())
throw pqxx::conversion_error{"Trying to convert empty string to " +
pqxx::type_name<T> + "."};

bool ok{false};
T result;

@@ -479,8 +483,7 @@ template<typename T> inline T from_string_awful_float(std::string_view text)
case 'n':
// Accept "NaN," "nan," etc.
ok =
(text.size() == 3 and
(text[1] == 'A' or text[1] == 'a') and
(text.size() == 3 and (text[1] == 'A' or text[1] == 'a') and
(text[2] == 'N' or text[2] == 'n'));
result = std::numeric_limits<T>::quiet_NaN();
break;
@@ -492,7 +495,7 @@ template<typename T> inline T from_string_awful_float(std::string_view text)
break;

default:
if (text[0] == '-' and valid_infinity_string(&text[1]))
if (text[0] == '-' and valid_infinity_string(text.substr(1)))
{
ok = true;
result = -std::numeric_limits<T>::infinity();
22 changes: 22 additions & 0 deletions test/unit/test_float.cxx
Original file line number Diff line number Diff line change
@@ -84,6 +84,28 @@ void test_bug_262()
}


/// Test conversion of malformed floating-point values.
void test_bad_float()
{
float x [[maybe_unused]];
PQXX_CHECK_THROWS(
x = pqxx::from_string<float>(""), pqxx::conversion_error,
"Conversion of empty string to float was not caught.");

PQXX_CHECK_THROWS(
x = pqxx::from_string<float>("Infancy"), pqxx::conversion_error,
"Misleading infinity was not caught.");
PQXX_CHECK_THROWS(
x = pqxx::from_string<float>("-Infighting"), pqxx::conversion_error,
"Misleading negative infinity was not caught.");

PQXX_CHECK_THROWS(
x = pqxx::from_string<float>("Nanny"), pqxx::conversion_error,
"Conversion of misleading NaN was not caught.");
}


PQXX_REGISTER_TEST(test_infinities);
PQXX_REGISTER_TEST(test_bug_262);
PQXX_REGISTER_TEST(test_bad_float);
} // namespace

0 comments on commit 29468ef

Please sign in to comment.