Skip to content

Commit 4011004

Browse files
committed
resolve BUGFIX avoid variable overflow
1 parent fefe987 commit 4011004

File tree

1 file changed

+48
-10
lines changed

1 file changed

+48
-10
lines changed

src/resolve.c

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <assert.h>
1919
#include <string.h>
2020
#include <ctype.h>
21+
#include <inttypes.h>
2122
#include <limits.h>
2223

2324
#include "libyang.h"
@@ -49,12 +50,46 @@ struct parsed_pred {
4950
} *pred;
5051
};
5152

53+
static int
54+
check_overflow_mul(int64_t num1, int64_t num2)
55+
{
56+
if (((num1 == -1) && (num2 == INT64_MIN)) || ((num2 == -1) && (num1 == INT64_MIN))) {
57+
return 1;
58+
}
59+
60+
if ((num1 > INT64_MAX / num2) || (num1 < INT64_MIN / num2)) {
61+
return 1;
62+
}
63+
64+
return 0;
65+
}
66+
67+
static int
68+
check_overflow_sub(int64_t num1, int64_t num2)
69+
{
70+
if (((num2 < 0) && (num1 > INT64_MAX + num2)) || ((num2 > 0) && (num1 < INT64_MIN + num2))) {
71+
return 1;
72+
}
73+
74+
return 0;
75+
}
76+
77+
static int
78+
check_overflow_add(int64_t num1, int64_t num2)
79+
{
80+
if (((num2 > 0) && (num1 > INT64_MAX - num2)) || ((num2 < 0) && (num1 < INT64_MIN - num2))) {
81+
return 1;
82+
}
83+
84+
return 0;
85+
}
86+
5287
int
5388
parse_range_dec64(const char **str_num, uint8_t dig, int64_t *num)
5489
{
5590
const char *ptr;
5691
int minus = 0;
57-
int64_t ret = 0, prev_ret;
92+
int64_t ret = 0;
5893
int8_t str_exp, str_dig = -1, trailing_zeros = 0;
5994

6095
ptr = *str_num;
@@ -83,17 +118,21 @@ parse_range_dec64(const char **str_num, uint8_t dig, int64_t *num)
83118
}
84119
++str_dig;
85120
} else {
86-
prev_ret = ret;
121+
if (check_overflow_mul(ret, 10)) {
122+
return 1;
123+
}
124+
ret *= 10;
125+
87126
if (minus) {
88-
ret = ret * 10 - (ptr[0] - '0');
89-
if (ret > prev_ret) {
127+
if (check_overflow_sub(ret, ptr[0] - '0')) {
90128
return 1;
91129
}
130+
ret -= ptr[0] - '0';
92131
} else {
93-
ret = ret * 10 + (ptr[0] - '0');
94-
if (ret < prev_ret) {
132+
if (check_overflow_add(ret, ptr[0] - '0')) {
95133
return 1;
96134
}
135+
ret += ptr[0] - '0';
97136
}
98137
if (str_dig > -1) {
99138
++str_dig;
@@ -126,12 +165,11 @@ parse_range_dec64(const char **str_num, uint8_t dig, int64_t *num)
126165
if ((str_exp - 1) + (dig - str_dig) > 18) {
127166
return 1;
128167
}
129-
prev_ret = ret;
130-
ret *= dec_pow(dig - str_dig);
131-
if ((minus && (ret > prev_ret)) || (!minus && (ret < prev_ret))) {
168+
169+
if (check_overflow_mul(ret, dec_pow(dig - str_dig))) {
132170
return 1;
133171
}
134-
172+
ret *= dec_pow(dig - str_dig);
135173
}
136174
if (str_dig > dig) {
137175
return 1;

0 commit comments

Comments
 (0)