From cdc1361a03189a568b8e29c945fd699da5fbb1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 19 Nov 2020 10:45:22 +0100 Subject: [PATCH] Don't Overrun Formatting Buffer in 'doub_string_ecl' We would write outside the allocated buffer, and fail to write the nul terminator, when presented with inputs of very small size (denormalized numbers in the order of 1.0e-101 or smaller). Switch to using std::snprintf and expand the buffer size to work around this problem. While here, also fix a subtle issue in determining whether or not we should insert the exponent character 'D' into the formatted output. Since we add one upon formatting the number, we also need to use a non-symmetric condition for the 'D' character lest we fail to output correctly formatted versions of -2.9440373045442E-100 (=> -0.29440373045442D-99) -2.9440373045442E+99 (=> -0.29440373045442+100) --- src/opm/io/eclipse/EclOutput.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/opm/io/eclipse/EclOutput.cpp b/src/opm/io/eclipse/EclOutput.cpp index 3431824f6..4be9ee6b0 100644 --- a/src/opm/io/eclipse/EclOutput.cpp +++ b/src/opm/io/eclipse/EclOutput.cpp @@ -489,8 +489,8 @@ std::string EclOutput::make_real_string_ix(float value) const std::string EclOutput::make_doub_string_ecl(double value) const { - char buffer [21]; - std::sprintf (buffer, "%19.13E", value); + char buffer [21 + 1]; + std::snprintf (buffer, sizeof buffer, "%19.13E", value); if (value == 0.0) { return "0.00000000000000D+00"; @@ -507,22 +507,23 @@ std::string EclOutput::make_doub_string_ecl(double value) const std::string tmpstr(buffer); int exp = value < 0.0 ? std::stoi(tmpstr.substr(17, 4)) : std::stoi(tmpstr.substr(16, 4)); + const bool use_exp_char = (exp >= -100) && (exp < 99); if (value < 0.0) { - if (std::abs(exp) < 100) { + if (use_exp_char) { tmpstr = "-0." + tmpstr.substr(1, 1) + tmpstr.substr(3, 13) + "D"; } else { tmpstr = "-0." + tmpstr.substr(1, 1) + tmpstr.substr(3, 13); } } else { - if (std::abs(exp) < 100) { + if (use_exp_char) { tmpstr = "0." + tmpstr.substr(0, 1) + tmpstr.substr(2, 13) + "D"; } else { tmpstr = "0." + tmpstr.substr(0, 1) + tmpstr.substr(2, 13); } } - std::sprintf(buffer, "%+03i", exp + 1); + std::snprintf(buffer, sizeof buffer, "%+03i", exp + 1); tmpstr = tmpstr + buffer; return tmpstr; }