diff --git a/src/utils.cpp b/src/utils.cpp index 87c46c47ab..27d89f1bf5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -398,17 +398,23 @@ double utils::numeric(const char *file, int line, const std::string &str, bool d } double rv = 0; + auto msg = fmt::format("Floating point number {} in input script or data file is invalid", buf); try { - rv = stod(buf); + std::size_t endpos; + rv = std::stod(buf, &endpos); + if (buf.size() != endpos) { + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } } 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); + 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 @@ -459,10 +465,23 @@ int utils::inumeric(const char *file, int line, const std::string &str, bool do_ } int rv = 0; + auto msg = fmt::format("Integer {} in input script or data file is invalid", buf); try { - rv = stoi(buf); + std::size_t endpos; + rv = std::stoi(buf, &endpos); + if (buf.size() != endpos) { + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + } catch (std::invalid_argument const &) { + 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("Integer {} in input script or data file is out of range", buf); + 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 @@ -514,9 +533,22 @@ bigint utils::bnumeric(const char *file, int line, const std::string &str, bool } long long rv = 0; + auto msg = fmt::format("Integer {} in input script or data file is invalid", buf); try { - rv = stoll(buf); - if (rv > MAXBIGINT) throw std::out_of_range("64-bit"); + std::size_t endpos; + rv = std::stoll(buf, &endpos); + if (buf.size() != endpos) { + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + if ((rv < (-MAXBIGINT - 1) || (rv > MAXBIGINT))) throw std::out_of_range("bigint"); + } catch (std::invalid_argument const &) { + 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("Integer {} in input script or data file is out of range", buf); if (do_abort) @@ -570,9 +602,22 @@ tagint utils::tnumeric(const char *file, int line, const std::string &str, bool } long long rv = 0; + auto msg = fmt::format("Integer {} in input script or data file is invalid", buf); try { - rv = stoll(buf); - if (rv > MAXTAGINT) throw std::out_of_range("64-bit"); + std::size_t endpos; + rv = std::stoll(buf, &endpos); + if (buf.size() != endpos) { + if (do_abort) + lmp->error->one(file, line, msg); + else + lmp->error->all(file, line, msg); + } + if ((rv < (-MAXTAGINT - 1) || (rv > MAXTAGINT))) throw std::out_of_range("tagint"); + } catch (std::invalid_argument const &) { + 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("Integer {} in input script or data file is out of range", buf); if (do_abort) @@ -614,19 +659,19 @@ void utils::bounds(const char *file, int line, const std::string &str, found = str.find_first_of('*'); if (found == std::string::npos) { // contains no '*' - nlo = nhi = strtol(str.c_str(), nullptr, 10); + nlo = nhi = std::stol(str, nullptr, 10); } else if (str.size() == 1) { // is only '*' nlo = nmin; nhi = nmax; } else if (found == 0) { // is '*j' nlo = nmin; - nhi = strtol(str.substr(1).c_str(), nullptr, 10); + nhi = std::stol(str.substr(1), nullptr, 10); } else if (str.size() == found + 1) { // is 'i*' - nlo = strtol(str.c_str(), nullptr, 10); + nlo = std::stol(str, nullptr, 10); nhi = nmax; } else { // is 'i*j' - nlo = strtol(str.c_str(), nullptr, 10); - nhi = strtol(str.substr(found + 1).c_str(), nullptr, 10); + nlo = std::stol(str, nullptr, 10); + nhi = std::stol(str.substr(found + 1), nullptr, 10); } if (error) { @@ -1697,10 +1742,10 @@ double utils::timespec2seconds(const std::string ×pec) int utils::date2num(const std::string &date) { std::size_t found = date.find_first_not_of("0123456789 "); - int num = strtol(date.substr(0, found).c_str(), nullptr, 10); + int num = std::stol(date.substr(0, found), nullptr, 10); auto month = date.substr(found); found = month.find_first_of("0123456789 "); - num += strtol(month.substr(found).c_str(), nullptr, 10) * 10000; + num += std::stol(month.substr(found), nullptr, 10) * 10000; if (num < 1000000) num += 20000000; if (strmatch(month, "^Jan"))