diff --git a/src/utils.cpp b/src/utils.cpp index 992feb34e8..bde6dffca5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -395,7 +395,24 @@ double utils::numeric(const char *file, int line, const std::string &str, bool d lmp->error->all(file, line, msg); } - return atof(buf.c_str()); + double rv = 0; + try { + rv = stod(buf); + } catch (std::invalid_argument const &) { + auto msg = fmt::format("Floating point number {} in input script or data file is invalid", buf); + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } catch (std::out_of_range const &) { + auto msg = + fmt::format("Floating point number {} in input script or data file is out of range", buf); + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + return rv; } /* ---------------------------------------------------------------------- @@ -439,7 +456,17 @@ int utils::inumeric(const char *file, int line, const std::string &str, bool do_ lmp->error->all(file, line, msg); } - return atoi(buf.c_str()); + int rv = 0; + try { + rv = stoi(buf); + } catch (std::out_of_range const &) { + auto msg = fmt::format("Integer {} in input script or data file is out of range", buf); + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + return rv; } /* ---------------------------------------------------------------------- @@ -484,7 +511,18 @@ bigint utils::bnumeric(const char *file, int line, const std::string &str, bool lmp->error->all(file, line, msg); } - return ATOBIGINT(buf.c_str()); + long long rv = 0; + try { + rv = stoll(buf); + if (rv > MAXBIGINT) throw std::out_of_range("64-bit"); + } catch (std::out_of_range const &) { + auto msg = fmt::format("Integer {} in input script or data file is out of range", buf); + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + return static_cast(rv); } /* ---------------------------------------------------------------------- @@ -529,7 +567,18 @@ tagint utils::tnumeric(const char *file, int line, const std::string &str, bool lmp->error->all(file, line, msg); } - return ATOTAGINT(buf.c_str()); + long long rv = 0; + try { + rv = stoll(buf); + if (rv > MAXTAGINT) throw std::out_of_range("64-bit"); + } catch (std::out_of_range const &) { + auto msg = fmt::format("Integer {} in input script or data file is out of range", buf); + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + return static_cast(rv); } /* ---------------------------------------------------------------------- diff --git a/unittest/formats/test_input_convert.cpp b/unittest/formats/test_input_convert.cpp index 858275a76f..78a78d08df 100644 --- a/unittest/formats/test_input_convert.cpp +++ b/unittest/formats/test_input_convert.cpp @@ -117,6 +117,17 @@ TEST_F(InputConvertTest, numeric) TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, nullptr, false, lmp);); TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, "2.56D+3", false, lmp);); + TEST_FAILURE(".*ERROR: Floating point number.*out of range.*", + utils::numeric(FLERR, "1.0e2000", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating .*", utils::numeric(FLERR, "--546700-", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "546700+", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "--546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "++546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "+-546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating .*", utils::numeric(FLERR, "5.467e--1", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "4.4e++1", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "--5.0460", false, lmp);); + TEST_FAILURE(".*ERROR: Expected floating.*", utils::numeric(FLERR, "++5.4670", false, lmp);); } TEST_F(InputConvertTest, inumeric) @@ -142,6 +153,13 @@ TEST_F(InputConvertTest, inumeric) TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "0x05", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, nullptr, false, lmp);); + TEST_FAILURE(".*ERROR: Integer.*out of range.*", + utils::inumeric(FLERR, "1263012546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "--546700-", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "546700+", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "--546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "++546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "+-546700", false, lmp);); } TEST_F(InputConvertTest, bnumeric) @@ -167,6 +185,13 @@ TEST_F(InputConvertTest, bnumeric) TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "0x05", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, nullptr, false, lmp);); + TEST_FAILURE(".*ERROR: Integer.*out of range.*", + utils::bnumeric(FLERR, "18446744073709551616123", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "--546700-", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "546700+", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "--546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "++546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "+-546700", false, lmp);); } TEST_F(InputConvertTest, tnumeric) @@ -192,6 +217,17 @@ TEST_F(InputConvertTest, tnumeric) TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "0x05", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, nullptr, false, lmp);); +#if defined(LAMMPS_SMALLBIG) + TEST_FAILURE(".*ERROR: Integer.*out of range.*", + utils::tnumeric(FLERR, "4294967296", false, lmp);); +#endif + TEST_FAILURE(".*ERROR: Integer.*out of range.*", + utils::tnumeric(FLERR, "18446744073709551616123", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "--546700-", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "546700+", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "--546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "++546700", false, lmp);); + TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "+-546700", false, lmp);); } } // namespace LAMMPS_NS