[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);
}
{