Bug 1350097 - handle very long floating point output in cvt_f; r?froydnj
Bug 1350097 points out a case where the assertion in cvt_f, added in
https://bugzilla.mozilla.org/show_bug.cgi?id=1060419#c127, triggers.
Before this addition, code calling this printf variant would end up just
printing something invalid, as the truncated value would be emitted.
This patch increases the buffer size to be sufficient for DBL_MAX.
MozReview-Commit-ID: AVphURGa6jL
--- a/js/src/jsapi-tests/testPrintf.cpp
+++ b/js/src/jsapi-tests/testPrintf.cpp
@@ -3,16 +3,17 @@
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/SizePrintfMacros.h"
+#include <cfloat>
#include <stdarg.h>
#include "jsprf.h"
#include "jsapi-tests/tests.h"
static bool
MOZ_FORMAT_PRINTF(2, 3)
@@ -56,16 +57,20 @@ BEGIN_TEST(testPrintf)
CHECK(print_one("27270", "%" PRIuSIZE, (size_t) 27270));
CHECK(print_one("hello", "he%so", "ll"));
CHECK(print_one("(null)", "%s", zero()));
CHECK(print_one("0", "%p", (char *) 0));
CHECK(print_one("h", "%c", 'h'));
CHECK(print_one("1.500000", "%f", 1.5f));
CHECK(print_one("1.5", "%g", 1.5));
+ // Regression test for bug#1350097. The bug was an assertion
+ // failure caused by printing a very long floating point value.
+ print_one("ignore", "%lf", DBL_MAX);
+
CHECK(print_one("2727", "%" PRIu32, (uint32_t) 2727));
CHECK(print_one("aa7", "%" PRIx32, (uint32_t) 2727));
CHECK(print_one("2727", "%" PRIu64, (uint64_t) 2727));
CHECK(print_one("aa7", "%" PRIx64, (uint64_t) 2727));
return true;
}
END_TEST(testPrintf)
--- a/mozglue/misc/Printf.cpp
+++ b/mozglue/misc/Printf.cpp
@@ -250,17 +250,18 @@ mozilla::PrintfTarget::cvt_ll(int64_t nu
/*
* Convert a double precision floating point number into its printable
* form.
*/
bool
mozilla::PrintfTarget::cvt_f(double d, const char* fmt0, const char* fmt1)
{
char fin[20];
- char fout[300];
+ // The size is chosen such that we can print DBL_MAX. See bug#1350097.
+ char fout[320];
int amount = fmt1 - fmt0;
MOZ_ASSERT((amount > 0) && (amount < (int)sizeof(fin)));
if (amount >= (int)sizeof(fin)) {
// Totally bogus % command to sprintf. Just ignore it
return true;
}
memcpy(fin, fmt0, (size_t)amount);
@@ -272,17 +273,17 @@ mozilla::PrintfTarget::cvt_f(double d, c
const char* p = fin;
while (*p) {
MOZ_ASSERT(*p != 'L');
p++;
}
}
#endif
size_t len = SprintfLiteral(fout, fin, d);
- MOZ_ASSERT(len <= sizeof(fout));
+ MOZ_RELEASE_ASSERT(len <= sizeof(fout));
return emit(fout, len);
}
/*
* Convert a string into its printable form. "width" is the output
* width. "prec" is the maximum number of characters of "s" to output,
* where -1 means until NUL.