mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2026-01-02 03:57:55 +08:00
Compare commits
2 Commits
bbf8bdb087
...
c7aa78d294
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7aa78d294 | ||
|
|
a2826e8983 |
@@ -129,9 +129,14 @@ std::string FpToString(T v, int precision = 0) {
|
||||
}
|
||||
}
|
||||
|
||||
std::array<char, 28> output_buffer; // max digits of size_t plus sign, a dot and 2 letters for 'e+' or 'e-' and 4 letters for the exponent
|
||||
// Case 1 - scientific notation: max digits of size_t plus sign, a dot and 2 letters for 'e+' or 'e-' and 4 letters for the exponent
|
||||
// Case 2 - default notation: require up to precision number of digits and one for a potential sign
|
||||
std::array<char, 28> output_buffer;
|
||||
auto output_ptr = &output_buffer[0];
|
||||
|
||||
// Helper variable that in Case 2 counts the overflowing number of zeros that do not fit into the buffer.
|
||||
int overflow_zeros = 0;
|
||||
|
||||
// print '-' symbol for negative numbers
|
||||
if (r.is_negative) {
|
||||
*(output_ptr++) = '-';
|
||||
@@ -178,12 +183,22 @@ std::string FpToString(T v, int precision = 0) {
|
||||
// print digits before point
|
||||
int const before_decimal_digits = digits_ct + r.exponent;
|
||||
if (before_decimal_digits > 0) {
|
||||
// print digits before point
|
||||
// print non-zero digits before point
|
||||
for (int i{0}; i < std::min(before_decimal_digits, digits_ct); ++i) {
|
||||
*(output_ptr++) = *(digits_iter++);
|
||||
}
|
||||
|
||||
// number of digits that have to be zero
|
||||
int const zero_digits_ct = before_decimal_digits - digits_ct;
|
||||
|
||||
// space left in the output_buffer (-1 because we need it for null-termination)
|
||||
int const buffer_empty_space = output_buffer.data() + output_buffer.size() - output_ptr - 1;
|
||||
|
||||
// print all zeros not fitting into the buffer at the end of the function
|
||||
overflow_zeros = std::max(0, zero_digits_ct - buffer_empty_space);
|
||||
|
||||
// print trailing zeros before point
|
||||
for (int i{0}; i < before_decimal_digits - digits_ct; ++i) {
|
||||
for (int i{0}; i < zero_digits_ct - overflow_zeros; ++i) {
|
||||
*(output_ptr++) = '0';
|
||||
}
|
||||
|
||||
@@ -207,7 +222,9 @@ std::string FpToString(T v, int precision = 0) {
|
||||
}
|
||||
}
|
||||
*output_ptr = '\0';
|
||||
return std::string{&output_buffer[0], output_ptr};
|
||||
auto ret_value = std::string{&output_buffer[0], output_ptr};
|
||||
ret_value.resize(ret_value.size() + overflow_zeros, '0');
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace {
|
||||
template <typename T>
|
||||
static std::string convert_with_stringstream(T v, size_t precision = 0) {
|
||||
std::stringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
if (precision > 0) {
|
||||
ss << std::setprecision(precision);
|
||||
}
|
||||
@@ -238,5 +239,9 @@ TEST(FpToStringTest, conversion_float) {
|
||||
EXPECT_EQ("-1.3e-05", FpToString(-1.299e-5f, 2));
|
||||
}
|
||||
|
||||
TEST(FpToStringTest, vulnerability_stack_buffer_overflow) {
|
||||
EXPECT_EQ(FpToString(1.0e100, 200), "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace YAML
|
||||
|
||||
Reference in New Issue
Block a user