diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 9caf5e93e..c57481bfe 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -900,10 +900,8 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o 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 bc27f78f8..e64eb0ee6 100644 --- a/src/hb-buffer-serialize.cc +++ b/src/hb-buffer-serialize.cc @@ -384,10 +384,8 @@ parse_int (const char *pp, const char *end, int32_t *pv) { 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 @@ parse_uint (const char *pp, const char *end, uint32_t *pv) { 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 d5acd2b11..fc67dc0a7 100644 --- a/src/hb-number.cc +++ b/src/hb-number.cc @@ -33,10 +33,12 @@ template 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 @@ _parse_number (const char **pp, const char *end, T *pv, Func f) 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 (pp, end, pv, [] (const char *p, char **end) - { return strtol (p, end, 10); }); + return _parse_number (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 (pp, end, pv, [base] (const char *p, char **end) - { return strtoul (p, end, base); }); + return _parse_number (pp, end, pv, whole_buffer, + [base] (const char *p, char **end) + { return strtoul (p, end, base); }); } @@ -124,14 +131,16 @@ get_C_locale () #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 (pp, end, pv, [] (const char *p, char **end) - { + return _parse_number (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 41a1d7d2e..561620db0 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 0a33f7f29..80d9850c3 100644 --- a/src/test-number.cc +++ b/src/test-number.cc @@ -46,7 +46,7 @@ main (int argc, char **argv) { 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,13 +62,27 @@ main (int argc, char **argv) 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); assert (!*end); } + { + 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; @@ -93,7 +107,6 @@ main (int argc, char **argv) assert (pv == 123); assert (pp - str == 3); assert (end - pp == 1); - assert (!*end); } {