[number] Add whole buffer check and test it
This commit is contained in:
parent
3661eb6105
commit
65690b5a4b
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 @@ _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<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 @@ 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<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
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue