Fixed overflow detection in number parsing functions.
This commit is contained in:
@@ -18,6 +18,9 @@ nxt_int_parse(const u_char *p, size_t length)
|
|||||||
u_char c;
|
u_char c;
|
||||||
nxt_uint_t val;
|
nxt_uint_t val;
|
||||||
|
|
||||||
|
static const nxt_uint_t cutoff = NXT_INT_T_MAX / 10;
|
||||||
|
static const nxt_uint_t cutlim = NXT_INT_T_MAX % 10;
|
||||||
|
|
||||||
if (nxt_fast_path(length != 0)) {
|
if (nxt_fast_path(length != 0)) {
|
||||||
|
|
||||||
val = 0;
|
val = 0;
|
||||||
@@ -32,13 +35,13 @@ nxt_int_parse(const u_char *p, size_t length)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = val * 10 + c;
|
if (nxt_slow_path(val >= cutoff && (val > cutoff || c > cutlim))) {
|
||||||
|
|
||||||
if (nxt_slow_path((nxt_int_t) val < 0)) {
|
|
||||||
/* An overflow. */
|
/* An overflow. */
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val = val * 10 + c;
|
||||||
|
|
||||||
length--;
|
length--;
|
||||||
|
|
||||||
} while (length != 0);
|
} while (length != 0);
|
||||||
@@ -61,6 +64,9 @@ nxt_size_t_parse(const u_char *p, size_t length)
|
|||||||
u_char c;
|
u_char c;
|
||||||
size_t val;
|
size_t val;
|
||||||
|
|
||||||
|
static const size_t cutoff = NXT_SIZE_T_MAX / 10;
|
||||||
|
static const size_t cutlim = NXT_SIZE_T_MAX % 10;
|
||||||
|
|
||||||
if (nxt_fast_path(length != 0)) {
|
if (nxt_fast_path(length != 0)) {
|
||||||
|
|
||||||
val = 0;
|
val = 0;
|
||||||
@@ -75,13 +81,13 @@ nxt_size_t_parse(const u_char *p, size_t length)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = val * 10 + c;
|
if (nxt_slow_path(val >= cutoff && (val > cutoff || c > cutlim))) {
|
||||||
|
|
||||||
if (nxt_slow_path((ssize_t) val < 0)) {
|
|
||||||
/* An overflow. */
|
/* An overflow. */
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val = val * 10 + c;
|
||||||
|
|
||||||
length--;
|
length--;
|
||||||
|
|
||||||
} while (length != 0);
|
} while (length != 0);
|
||||||
@@ -101,8 +107,8 @@ nxt_size_t_parse(const u_char *p, size_t length)
|
|||||||
ssize_t
|
ssize_t
|
||||||
nxt_size_parse(const u_char *p, size_t length)
|
nxt_size_parse(const u_char *p, size_t length)
|
||||||
{
|
{
|
||||||
u_char c, unit;
|
u_char unit;
|
||||||
size_t val, max;
|
ssize_t val, max;
|
||||||
nxt_uint_t shift;
|
nxt_uint_t shift;
|
||||||
|
|
||||||
if (nxt_fast_path(length != 0)) {
|
if (nxt_fast_path(length != 0)) {
|
||||||
@@ -130,39 +136,22 @@ nxt_size_parse(const u_char *p, size_t length)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
max = NXT_SIZE_T_MAX;
|
return nxt_size_t_parse(p, length + 1);
|
||||||
shift = 0;
|
|
||||||
length++;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nxt_fast_path(length != 0)) {
|
val = nxt_size_t_parse(p, length);
|
||||||
|
|
||||||
val = 0;
|
if (nxt_fast_path(val >= 0)) {
|
||||||
|
|
||||||
do {
|
|
||||||
c = *p++;
|
|
||||||
|
|
||||||
/* Values below '0' become >= 208. */
|
|
||||||
c = c - '0';
|
|
||||||
|
|
||||||
if (nxt_slow_path(c > 9)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = val * 10 + c;
|
|
||||||
|
|
||||||
if (nxt_slow_path(val > max)) {
|
if (nxt_slow_path(val > max)) {
|
||||||
/* An overflow. */
|
/* An overflow. */
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
length--;
|
val <<= shift;
|
||||||
|
|
||||||
} while (length != 0);
|
|
||||||
|
|
||||||
return val << shift;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@@ -180,6 +169,9 @@ nxt_off_t_parse(const u_char *p, size_t length)
|
|||||||
u_char c;
|
u_char c;
|
||||||
nxt_uoff_t val;
|
nxt_uoff_t val;
|
||||||
|
|
||||||
|
static const nxt_uoff_t cutoff = NXT_OFF_T_MAX / 10;
|
||||||
|
static const nxt_uoff_t cutlim = NXT_OFF_T_MAX % 10;
|
||||||
|
|
||||||
if (nxt_fast_path(length != 0)) {
|
if (nxt_fast_path(length != 0)) {
|
||||||
|
|
||||||
val = 0;
|
val = 0;
|
||||||
@@ -194,13 +186,13 @@ nxt_off_t_parse(const u_char *p, size_t length)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = val * 10 + c;
|
if (nxt_slow_path(val >= cutoff && (val > cutoff || c > cutlim))) {
|
||||||
|
|
||||||
if (nxt_slow_path((nxt_off_t) val < 0)) {
|
|
||||||
/* An overflow. */
|
/* An overflow. */
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val = val * 10 + c;
|
||||||
|
|
||||||
length--;
|
length--;
|
||||||
|
|
||||||
} while (length != 0);
|
} while (length != 0);
|
||||||
@@ -224,6 +216,9 @@ nxt_str_int_parse(nxt_str_t *s)
|
|||||||
size_t length;
|
size_t length;
|
||||||
nxt_uint_t val;
|
nxt_uint_t val;
|
||||||
|
|
||||||
|
static const nxt_uint_t cutoff = NXT_INT_T_MAX / 10;
|
||||||
|
static const nxt_uint_t cutlim = NXT_INT_T_MAX % 10;
|
||||||
|
|
||||||
length = s->length;
|
length = s->length;
|
||||||
|
|
||||||
if (nxt_slow_path(length == 0)) {
|
if (nxt_slow_path(length == 0)) {
|
||||||
@@ -243,13 +238,13 @@ nxt_str_int_parse(nxt_str_t *s)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = val * 10 + c;
|
if (nxt_slow_path(val >= cutoff && (val > cutoff || c > cutlim))) {
|
||||||
|
|
||||||
if (nxt_slow_path((nxt_int_t) val < 0)) {
|
|
||||||
/* An overflow. */
|
/* An overflow. */
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val = val * 10 + c;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
length--;
|
length--;
|
||||||
|
|
||||||
@@ -271,9 +266,13 @@ double
|
|||||||
nxt_number_parse(const u_char **start, const u_char *end)
|
nxt_number_parse(const u_char **start, const u_char *end)
|
||||||
{
|
{
|
||||||
u_char c;
|
u_char c;
|
||||||
|
nxt_bool_t overflow;
|
||||||
nxt_uint_t integral, frac, power;
|
nxt_uint_t integral, frac, power;
|
||||||
const u_char *p;
|
const u_char *p;
|
||||||
|
|
||||||
|
static const nxt_uint_t cutoff = NXT_INT_T_MAX / 10;
|
||||||
|
static const nxt_uint_t cutlim = NXT_INT_T_MAX % 10;
|
||||||
|
|
||||||
p = *start;
|
p = *start;
|
||||||
integral = 0;
|
integral = 0;
|
||||||
|
|
||||||
@@ -291,13 +290,15 @@ nxt_number_parse(const u_char **start, const u_char *end)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
integral = integral * 10 + c;
|
overflow = nxt_expect(0, (integral >= cutoff
|
||||||
|
&& (integral > cutoff || c > cutlim)));
|
||||||
|
|
||||||
if (nxt_slow_path((nxt_int_t) integral < 0)) {
|
if (overflow) {
|
||||||
/* An overflow. */
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
integral = integral * 10 + c;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,13 +330,16 @@ dot:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
frac = frac * 10 + c;
|
overflow = nxt_expect(0, (frac >= cutoff && (frac > cutoff
|
||||||
power *= 10;
|
|| c > cutlim))
|
||||||
|
|| power > cutoff);
|
||||||
|
|
||||||
if (nxt_slow_path((nxt_int_t) frac < 0 || (nxt_int_t) power < 0)) {
|
if (overflow) {
|
||||||
/* An overflow. */
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frac = frac * 10 + c;
|
||||||
|
power *= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
*start = p;
|
*start = p;
|
||||||
|
|||||||
Reference in New Issue
Block a user