[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;
|
unsigned int v;
|
||||||
const char *p = s;
|
const char *p = s;
|
||||||
const char *end = p + len;
|
const char *end = p + len;
|
||||||
if (unlikely (!hb_parse_uint (&p, end, &v, base))) return false;
|
if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, base)))
|
||||||
|
return false;
|
||||||
/* Check if parser consumed all of the buffer */
|
|
||||||
if (unlikely (p != end)) return false;
|
|
||||||
|
|
||||||
*out = v;
|
*out = v;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -384,10 +384,8 @@ parse_int (const char *pp, const char *end, int32_t *pv)
|
||||||
{
|
{
|
||||||
int v;
|
int v;
|
||||||
const char *p = pp;
|
const char *p = pp;
|
||||||
if (unlikely (!hb_parse_int (&p, end, &v))) return false;
|
if (unlikely (!hb_parse_int (&p, end, &v, true/* whole buffer */)))
|
||||||
|
return false;
|
||||||
/* Check if parser consumed all of the buffer */
|
|
||||||
if (unlikely (p != end)) return false;
|
|
||||||
|
|
||||||
*pv = v;
|
*pv = v;
|
||||||
return true;
|
return true;
|
||||||
|
@ -398,10 +396,8 @@ parse_uint (const char *pp, const char *end, uint32_t *pv)
|
||||||
{
|
{
|
||||||
unsigned int v;
|
unsigned int v;
|
||||||
const char *p = pp;
|
const char *p = pp;
|
||||||
if (unlikely (!hb_parse_uint (&p, end, &v))) return false;
|
if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */)))
|
||||||
|
return false;
|
||||||
/* Check if parser consumed all of the buffer */
|
|
||||||
if (unlikely (p != end)) return false;
|
|
||||||
|
|
||||||
*pv = v;
|
*pv = v;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -33,10 +33,12 @@
|
||||||
|
|
||||||
template<typename T, typename Func>
|
template<typename T, typename Func>
|
||||||
static bool
|
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];
|
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);
|
strncpy (buf, *pp, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
|
|
||||||
|
@ -45,24 +47,29 @@ _parse_number (const char **pp, const char *end, T *pv, Func f)
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*pv = f (p, &pend);
|
*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;
|
*pp += pend - p;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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 _parse_number<int> (pp, end, pv, whole_buffer,
|
||||||
{ return strtol (p, end, 10); });
|
[] (const char *p, char **end)
|
||||||
|
{ return strtol (p, end, 10); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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 _parse_number<unsigned int> (pp, end, pv, whole_buffer,
|
||||||
{ return strtoul (p, end, base); });
|
[base] (const char *p, char **end)
|
||||||
|
{ return strtoul (p, end, base); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,14 +131,16 @@ get_C_locale ()
|
||||||
#endif /* USE_XLOCALE */
|
#endif /* USE_XLOCALE */
|
||||||
|
|
||||||
bool
|
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
|
#ifdef USE_XLOCALE
|
||||||
return strtod_l (p, end, get_C_locale ());
|
return strtod_l (p, end, get_C_locale ());
|
||||||
#else
|
#else
|
||||||
return strtod (p, end);
|
return strtod (p, end);
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,15 @@
|
||||||
#define HB_NUMBER_HH
|
#define HB_NUMBER_HH
|
||||||
|
|
||||||
HB_INTERNAL bool
|
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_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_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 */
|
#endif /* HB_NUMBER_HH */
|
||||||
|
|
|
@ -46,7 +46,7 @@ main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char str[] = "123";
|
const char str[] = "123";
|
||||||
const char *pp = str;
|
const char *pp = str;
|
||||||
const char *end = str + 3;
|
const char *end = str + strlen (str);
|
||||||
|
|
||||||
unsigned int pv;
|
unsigned int pv;
|
||||||
assert (hb_parse_uint (&pp, end, &pv));
|
assert (hb_parse_uint (&pp, end, &pv));
|
||||||
|
@ -62,13 +62,27 @@ main (int argc, char **argv)
|
||||||
const char *end = str + 3;
|
const char *end = str + 3;
|
||||||
|
|
||||||
unsigned int pv;
|
unsigned int pv;
|
||||||
assert (hb_parse_uint (&pp, end, &pv, 16));
|
assert (hb_parse_uint (&pp, end, &pv, true, 16));
|
||||||
assert (pv == 0x12F);
|
assert (pv == 0x12F);
|
||||||
assert (pp - str == 3);
|
assert (pp - str == 3);
|
||||||
assert (end - pp == 0);
|
assert (end - pp == 0);
|
||||||
assert (!*end);
|
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 str[] = "-123";
|
||||||
const char *pp = str;
|
const char *pp = str;
|
||||||
|
@ -93,7 +107,6 @@ main (int argc, char **argv)
|
||||||
assert (pv == 123);
|
assert (pv == 123);
|
||||||
assert (pp - str == 3);
|
assert (pp - str == 3);
|
||||||
assert (end - pp == 1);
|
assert (end - pp == 1);
|
||||||
assert (!*end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue