[number] Add whole buffer check and test it
diff --git a/src/hb-algs.hh b/src/hb-algs.hh
index 9caf5e9..c57481b 100644
--- a/src/hb-algs.hh
+++ b/src/hb-algs.hh
@@ -900,10 +900,8 @@
   unsigned int v;
   const char *p = s;
   const char *end = p + len;
-  if (unlikely (!hb_parse_uint (&p, end, &v, base))) return false;
-
-  /* Check if parser consumed all of the buffer */
-  if (unlikely (p != end)) return false;
+  if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, base)))
+    return false;
 
   *out = v;
   return true;
diff --git a/src/hb-buffer-serialize.cc b/src/hb-buffer-serialize.cc
index bc27f78..e64eb0e 100644
--- a/src/hb-buffer-serialize.cc
+++ b/src/hb-buffer-serialize.cc
@@ -384,10 +384,8 @@
 {
   int v;
   const char *p = pp;
-  if (unlikely (!hb_parse_int (&p, end, &v))) return false;
-
-  /* Check if parser consumed all of the buffer */
-  if (unlikely (p != end)) return false;
+  if (unlikely (!hb_parse_int (&p, end, &v, true/* whole buffer */)))
+    return false;
 
   *pv = v;
   return true;
@@ -398,10 +396,8 @@
 {
   unsigned int v;
   const char *p = pp;
-  if (unlikely (!hb_parse_uint (&p, end, &v))) return false;
-
-  /* Check if parser consumed all of the buffer */
-  if (unlikely (p != end)) return false;
+  if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */)))
+    return false;
 
   *pv = v;
   return true;
diff --git a/src/hb-number.cc b/src/hb-number.cc
index d5acd2b..fc67dc0 100644
--- a/src/hb-number.cc
+++ b/src/hb-number.cc
@@ -33,10 +33,12 @@
 
 template<typename T, typename Func>
 static bool
-_parse_number (const char **pp, const char *end, T *pv, Func f)
+_parse_number (const char **pp, const char *end, T *pv,
+	       bool whole_buffer, Func f)
 {
   char buf[32];
-  unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
+  unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1,
+			     (unsigned int) (end - *pp));
   strncpy (buf, *pp, len);
   buf[len] = '\0';
 
@@ -45,24 +47,29 @@
 
   errno = 0;
   *pv = f (p, &pend);
-  if (unlikely (errno || p == pend)) return false;
+  if (unlikely (errno || p == pend ||
+		/* Check if consumed whole buffer if is requested */
+		(whole_buffer && pend - p != end - *pp))) return false;
 
   *pp += pend - p;
   return true;
 }
 
 bool
-hb_parse_int (const char **pp, const char *end, int *pv)
+hb_parse_int (const char **pp, const char *end, int *pv, bool whole_buffer)
 {
-  return _parse_number<int> (pp, end, pv, [] (const char *p, char **end)
-					  { return strtol (p, end, 10); });
+  return _parse_number<int> (pp, end, pv, whole_buffer,
+			     [] (const char *p, char **end)
+			     { return strtol (p, end, 10); });
 }
 
 bool
-hb_parse_uint (const char **pp, const char *end, unsigned int *pv, int base)
+hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
+	       bool whole_buffer, int base)
 {
-  return _parse_number<unsigned int> (pp, end, pv, [base] (const char *p, char **end)
-						   { return strtoul (p, end, base); });
+  return _parse_number<unsigned int> (pp, end, pv, whole_buffer,
+				      [base] (const char *p, char **end)
+				      { return strtoul (p, end, base); });
 }
 
 
@@ -124,14 +131,16 @@
 #endif /* USE_XLOCALE */
 
 bool
-hb_parse_float (const char **pp, const char *end, float *pv)
+hb_parse_float (const char **pp, const char *end, float *pv,
+		bool whole_buffer)
 {
-  return _parse_number<float> (pp, end, pv, [] (const char *p, char **end)
-					    {
+  return _parse_number<float> (pp, end, pv, whole_buffer,
+			       [] (const char *p, char **end)
+			       {
 #ifdef USE_XLOCALE
-					      return strtod_l (p, end, get_C_locale ());
+				 return strtod_l (p, end, get_C_locale ());
 #else
-					      return strtod (p, end);
+				 return strtod (p, end);
 #endif
-					    });
+			       });
 }
diff --git a/src/hb-number.hh b/src/hb-number.hh
index 41a1d7d..561620d 100644
--- a/src/hb-number.hh
+++ b/src/hb-number.hh
@@ -27,12 +27,15 @@
 #define HB_NUMBER_HH
 
 HB_INTERNAL bool
-hb_parse_int (const char **pp, const char *end, int *pv);
+hb_parse_int (const char **pp, const char *end, int *pv,
+	      bool whole_buffer = false);
 
 HB_INTERNAL bool
-hb_parse_uint (const char **pp, const char *end, unsigned int *pv, int base=10);
+hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
+	       bool whole_buffer = false, int base = 10);
 
 HB_INTERNAL bool
-hb_parse_float (const char **pp, const char *end, float *pv);
+hb_parse_float (const char **pp, const char *end, float *pv,
+		bool whole_buffer = false);
 
 #endif /* HB_NUMBER_HH */
diff --git a/src/test-number.cc b/src/test-number.cc
index 0a33f7f..80d9850 100644
--- a/src/test-number.cc
+++ b/src/test-number.cc
@@ -46,7 +46,7 @@
   {
     const char str[] = "123";
     const char *pp = str;
-    const char *end = str + 3;
+    const char *end = str + strlen (str);
 
     unsigned int pv;
     assert (hb_parse_uint (&pp, end, &pv));
@@ -62,7 +62,7 @@
     const char *end = str + 3;
 
     unsigned int pv;
-    assert (hb_parse_uint (&pp, end, &pv, 16));
+    assert (hb_parse_uint (&pp, end, &pv, true, 16));
     assert (pv == 0x12F);
     assert (pp - str == 3);
     assert (end - pp == 0);
@@ -70,6 +70,20 @@
   }
 
   {
+    const char str[] = "12Fq";
+    const char *pp = str;
+    const char *end = str + 4;
+
+    unsigned int pv;
+    assert (!hb_parse_uint (&pp, end, &pv, true, 16));
+    assert (hb_parse_uint (&pp, end, &pv, false, 16));
+    assert (pv == 0x12F);
+    assert (pp - str == 3);
+    assert (end - pp == 1);
+    assert (!*end);
+  }
+
+  {
     const char str[] = "-123";
     const char *pp = str;
     const char *end = str + 4;
@@ -93,7 +107,6 @@
     assert (pv == 123);
     assert (pp - str == 3);
     assert (end - pp == 1);
-    assert (!*end);
   }
 
   {