[number] Add overflow checks used to be done in parse_bcd
Which were removed in 1083df8
This commit is contained in:
parent
47d82713a1
commit
39cf8e21be
|
@ -30,8 +30,10 @@
|
|||
|
||||
#include "hb.hh"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#line 35 "hb-number-parser.hh"
|
||||
|
||||
#line 37 "hb-number-parser.hh"
|
||||
static const unsigned char _double_parser_trans_keys[] = {
|
||||
0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u,
|
||||
46u, 101u, 0
|
||||
|
@ -91,7 +93,7 @@ static const int double_parser_error = 0;
|
|||
static const int double_parser_en_main = 1;
|
||||
|
||||
|
||||
#line 55 "hb-number-parser.rl"
|
||||
#line 70 "hb-number-parser.rl"
|
||||
|
||||
|
||||
constexpr double _pow2 (double x) { return x * x; }
|
||||
|
@ -130,7 +132,9 @@ strtod_rl (const char *buf, char **end_ptr)
|
|||
double frac = 0;
|
||||
double frac_count = 0;
|
||||
unsigned int exp = 0;
|
||||
bool neg = false, exp_neg = false;
|
||||
bool neg = false, exp_neg = false, exp_overflow = false;
|
||||
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
|
||||
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
|
||||
p = buf;
|
||||
pe = p + strlen (p);
|
||||
|
||||
|
@ -139,12 +143,12 @@ strtod_rl (const char *buf, char **end_ptr)
|
|||
|
||||
int cs;
|
||||
|
||||
#line 143 "hb-number-parser.hh"
|
||||
#line 147 "hb-number-parser.hh"
|
||||
{
|
||||
cs = double_parser_start;
|
||||
}
|
||||
|
||||
#line 148 "hb-number-parser.hh"
|
||||
#line 152 "hb-number-parser.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
|
@ -170,26 +174,39 @@ _resume:
|
|||
|
||||
switch ( _double_parser_trans_actions[_trans] ) {
|
||||
case 1:
|
||||
#line 37 "hb-number-parser.rl"
|
||||
#line 39 "hb-number-parser.rl"
|
||||
{ neg = true; }
|
||||
break;
|
||||
case 4:
|
||||
#line 38 "hb-number-parser.rl"
|
||||
#line 40 "hb-number-parser.rl"
|
||||
{ exp_neg = true; }
|
||||
break;
|
||||
case 2:
|
||||
#line 40 "hb-number-parser.rl"
|
||||
{ value = value * 10. + ((*p) - '0'); }
|
||||
#line 42 "hb-number-parser.rl"
|
||||
{
|
||||
value = value * 10. + ((*p) - '0');
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
#line 41 "hb-number-parser.rl"
|
||||
{ frac = frac * 10. + ((*p) - '0'); ++frac_count; }
|
||||
#line 45 "hb-number-parser.rl"
|
||||
{
|
||||
if (likely (frac <= MAX_FRACT / 10))
|
||||
{
|
||||
frac = frac * 10. + ((*p) - '0');
|
||||
++frac_count;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
#line 42 "hb-number-parser.rl"
|
||||
{ exp = exp * 10 + ((*p) - '0'); }
|
||||
#line 52 "hb-number-parser.rl"
|
||||
{
|
||||
if (likely (exp * 10 + ((*p) - '0') <= MAX_EXP))
|
||||
exp = exp * 10 + ((*p) - '0');
|
||||
else
|
||||
exp_overflow = true;
|
||||
}
|
||||
break;
|
||||
#line 193 "hb-number-parser.hh"
|
||||
#line 210 "hb-number-parser.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
|
@ -201,7 +218,7 @@ _again:
|
|||
_out: {}
|
||||
}
|
||||
|
||||
#line 104 "hb-number-parser.rl"
|
||||
#line 121 "hb-number-parser.rl"
|
||||
|
||||
|
||||
*end_ptr = (char *) p;
|
||||
|
@ -209,12 +226,17 @@ _again:
|
|||
if (frac_count) value += frac / _pow10 (frac_count);
|
||||
if (neg) value *= -1.;
|
||||
|
||||
if (unlikely (exp_overflow))
|
||||
{
|
||||
if (value == 0) return value;
|
||||
if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
|
||||
else return neg ? -DBL_MAX : DBL_MAX;
|
||||
}
|
||||
|
||||
if (exp)
|
||||
{
|
||||
if (exp_neg)
|
||||
value /= _pow10 (exp);
|
||||
else
|
||||
value *= _pow10 (exp);
|
||||
if (exp_neg) value /= _pow10 (exp);
|
||||
else value *= _pow10 (exp);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "hb.hh"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
%%{
|
||||
|
||||
machine double_parser;
|
||||
|
@ -37,9 +39,22 @@ write data;
|
|||
action see_neg { neg = true; }
|
||||
action see_exp_neg { exp_neg = true; }
|
||||
|
||||
action add_int { value = value * 10. + (fc - '0'); }
|
||||
action add_frac { frac = frac * 10. + (fc - '0'); ++frac_count; }
|
||||
action add_exp { exp = exp * 10 + (fc - '0'); }
|
||||
action add_int {
|
||||
value = value * 10. + (fc - '0');
|
||||
}
|
||||
action add_frac {
|
||||
if (likely (frac <= MAX_FRACT / 10))
|
||||
{
|
||||
frac = frac * 10. + (fc - '0');
|
||||
++frac_count;
|
||||
}
|
||||
}
|
||||
action add_exp {
|
||||
if (likely (exp * 10 + (fc - '0') <= MAX_EXP))
|
||||
exp = exp * 10 + (fc - '0');
|
||||
else
|
||||
exp_overflow = true;
|
||||
}
|
||||
|
||||
num = [0-9]+;
|
||||
|
||||
|
@ -90,7 +105,9 @@ strtod_rl (const char *buf, char **end_ptr)
|
|||
double frac = 0;
|
||||
double frac_count = 0;
|
||||
unsigned int exp = 0;
|
||||
bool neg = false, exp_neg = false;
|
||||
bool neg = false, exp_neg = false, exp_overflow = false;
|
||||
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
|
||||
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
|
||||
p = buf;
|
||||
pe = p + strlen (p);
|
||||
|
||||
|
@ -108,12 +125,17 @@ strtod_rl (const char *buf, char **end_ptr)
|
|||
if (frac_count) value += frac / _pow10 (frac_count);
|
||||
if (neg) value *= -1.;
|
||||
|
||||
if (unlikely (exp_overflow))
|
||||
{
|
||||
if (value == 0) return value;
|
||||
if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
|
||||
else return neg ? -DBL_MAX : DBL_MAX;
|
||||
}
|
||||
|
||||
if (exp)
|
||||
{
|
||||
if (exp_neg)
|
||||
value /= _pow10 (exp);
|
||||
else
|
||||
value *= _pow10 (exp);
|
||||
if (exp_neg) value /= _pow10 (exp);
|
||||
else value *= _pow10 (exp);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
|
Loading…
Reference in New Issue