Bug 1350097 - handle very long floating point output in cvt_f; r?froydnj draft
authorTom Tromey <tom@tromey.com>
Fri, 24 Mar 2017 08:18:51 -0600
changeset 555101 8e462b6d876ee018c49ec848df2373fd0bf856d6
parent 555100 359d3df04116a521d08eafef7cc77b865b070686
child 622528 bd9cd8ca97c991f216d8a63bc4ca96c628925051
push id52150
push userbmo:ttromey@mozilla.com
push dateMon, 03 Apr 2017 16:18:54 +0000
reviewersfroydnj
bugs1350097, 1060419
milestone55.0a1
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
js/src/jsapi-tests/testPrintf.cpp
mozglue/misc/Printf.cpp
--- 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.