Fix some issues with invalid hex-float literals.

When converting `0x` the converter would assert (or access out of
    boundary).
With `0x1.p1234556666FFFFF` the converter would overflow and not yield
the correct exponent.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2a06c71..02c34e3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.0)
-project(double-conversion VERSION 3.1.4)
+project(double-conversion VERSION 3.1.5)
 
 set(headers
     double-conversion/bignum.h
diff --git a/Changelog b/Changelog
index 647a0d8..606f47f 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,8 @@
+2019-05-25:
+  Fix `0x` for string->double conversion when Hex Floats are allowed.
+  Avoid integer overflow when exponents for hex floats were too big.
+  Update version number.
+
 2019-04-22:
   Fixed warning in gcc4.9. Thanks to Scott McCaskill
     (https://github.com/usefulcat) for the patch.
diff --git a/double-conversion/double-conversion.cc b/double-conversion/double-conversion.cc
index 163d41b..6da28ed 100644
--- a/double-conversion/double-conversion.cc
+++ b/double-conversion/double-conversion.cc
@@ -604,8 +604,8 @@
       saw_digit = true;
       if (Advance(&current, separator, 16, end)) return false;
     }
-    if (!saw_digit) return false;  // Only the '.', but no digits.
   }
+  if (!saw_digit) return false;
   if (*current != 'p' && *current != 'P') return false;
   if (Advance(&current, separator, 16, end)) return false;
   if (*current == '+' || *current == '-') {
@@ -763,7 +763,11 @@
     }
     int written_exponent = 0;
     while (IsDecimalDigitForRadix(**current, 10)) {
-      written_exponent = 10 * written_exponent + **current - '0';
+      // No need to read exponents if they are too big. That could potentially overflow
+      // the `written_exponent` variable.
+      if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
+        written_exponent = 10 * written_exponent + **current - '0';
+      }
       if (Advance(current, separator, radix, end)) break;
     }
     if (is_negative) written_exponent = -written_exponent;
@@ -899,10 +903,11 @@
         (*current == 'x' || *current == 'X')) {
       ++current;
 
+      if (current == end) return junk_string_value_;  // "0x"
+
       bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
                 IsHexFloatString(current, end, separator_, allow_trailing_junk);
 
-      if (current == end) return junk_string_value_;  // "0x"
       if (!parse_as_hex_float && !isDigit(*current, 16)) {
         return junk_string_value_;
       }
diff --git a/double-conversion/ieee.h b/double-conversion/ieee.h
index 4a5fe8f..8327484 100644
--- a/double-conversion/ieee.h
+++ b/double-conversion/ieee.h
@@ -47,6 +47,8 @@
   static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000);
   static const int kPhysicalSignificandSize = 52;  // Excludes the hidden bit.
   static const int kSignificandSize = 53;
+  static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
+  static const int kMaxExponent = 0x7FF - kExponentBias;
 
   Double() : d64_(0) {}
   explicit Double(double d) : d64_(double_to_uint64(d)) {}
@@ -222,9 +224,7 @@
   }
 
  private:
-  static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
   static const int kDenormalExponent = -kExponentBias + 1;
-  static const int kMaxExponent = 0x7FF - kExponentBias;
   static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000);
   static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000);
 
diff --git a/test/cctest/test-conversions.cc b/test/cctest/test-conversions.cc
index 878fd0f..014dd5e 100644
--- a/test/cctest/test-conversions.cc
+++ b/test/cctest/test-conversions.cc
@@ -2682,6 +2682,71 @@
 
   CHECK_EQ(-0.0, StrToD("-0x1p-2000", flags, 0.0, &processed, &all_used));
   CHECK(all_used);
+
+  CHECK_EQ(Double::NaN(), StrToD(" ", flags, Double::NaN(),
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("0x", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD(" 0x ", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD(" 0x 3", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("0x3g", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("x3", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("0x3 foo", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD(" 0x3 foo", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("+ 0x3 foo", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("+", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("-", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("- -0x5", flags, 0.0,  &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("- +0x5", flags, 0.0,  &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("+ +0x5", flags, 0.0,  &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("0xp1", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("0x.p1", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::Infinity(), StrToD("0x1.p10000000000000000", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(0.0, StrToD("0x1.p-10000000000000000", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK(all_used);
 }
 
 
@@ -4669,6 +4734,156 @@
   CHECK_EQ(Single::NaN(), StrToF("x3", flags, 0.0f,
                                  &processed, &all_used));
   CHECK_EQ(0, processed);
+
+  flags = StringToDoubleConverter::ALLOW_HEX_FLOATS;
+
+  CHECK_EQ(3.0f, StrToF("0x3p0", flags, 0.0, &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(0.0f, StrToF("0x.0p0", flags, 0.0, &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(3.0f, StrToF("0x3.0p0", flags, 0.0, &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(3.0f, StrToF("0x3.p0", flags, 0.0, &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(-5634002804104940178441764864.0f, StrToF("-0x123456789012345678901234p0",
+                                             flags, 0.0,
+                                             &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(134217728.0f, StrToF("0x8000001p0", flags, 0.0,
+                                        &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(134217728.0f, StrToF("0x8000000p0", flags, 0.0,
+                                        &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(549755813888.0f, StrToF("0x8000000001p0", flags, 0.0,
+                                     &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(549755813888.0f, StrToF("0x8000000000p0", flags, 0.0,
+                                     &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(549755879424.0f, StrToF("0x8000008001p0", flags, 0.0,
+                                            &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(549755813888.0f, StrToF("0x8000008000p0", flags, 0.0,
+                                            &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(549755944960.0f, StrToF("0x8000018001p0", flags, 0.0,
+                                            &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(549755944960.0f, StrToF("0x8000018000p0", flags, 0.0,
+                                            &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(8796093022208.0f, StrToF("0x8000000001p4", flags, 0.0,
+                                          &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(8796093022208.0f, StrToF("0x8000000000p+4", flags, 0.0,
+                                          &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(8796094070784.0f, StrToF("0x8000008001p04", flags, 0.0,
+                                          &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(34359738368.0f, StrToF("0x8000008000p-4", flags, 0.0,
+                                           &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(34359746560.0f, StrToF("0x8000018001p-04", flags, 0.0,
+                                           &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(8796095119360.0f, StrToF("0x8000018000p4", flags, 0.0,
+                                          &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(Single::Infinity(), StrToF("0x1p2000", flags, 0.0,
+                                      &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(0.0f, StrToF("0x1p-2000", flags, 0.0, &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(-0.0f, StrToF("-0x1p-2000", flags, 0.0, &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(Single::NaN(), StrToF(" ", flags, Single::NaN(),
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("0x", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF(" 0x ", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF(" 0x 3", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("0x3g", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("x3", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("0x3 foo", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF(" 0x3 foo", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("+ 0x3 foo", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("+", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("-", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("- -0x5", flags, 0.0,  &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("- +0x5", flags, 0.0,  &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("+ +0x5", flags, 0.0,  &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("0xp1", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::NaN(), StrToF("0x.p1", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Single::Infinity(), StrToF("0x1.p10000000000000000", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(0.0f, StrToF("0x1.p-10000000000000000", flags, 0.0,
+                                 &processed, &all_used));
+  CHECK(all_used);
 }