Bug 1350097 - handle very long floating point output in cvt_f; r=froydnj
authorTom Tromey <tom@tromey.com>
Fri, 24 Mar 2017 08:18:51 -0600
changeset 350959 02e8fffc17fbd4558bddb8a3c60e243cc2089b0a
parent 350958 1379bfa0f9217effd4c0a8cc70c1c1f1c2afb339
child 350960 aea54747dd32105317836125979a8d550b6286ff
push id31596
push userkwierso@gmail.com
push dateMon, 03 Apr 2017 21:43:13 +0000
treeherdermozilla-central@2a593ea93f66 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1350097, 1060419
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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.