Changeset: 8c9cde34bbcd for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/8c9cde34bbcd
Modified Files:
sql/server/rel_select.c
Branch: Jul2021
Log Message:
Do a more defensive overflow detection on the sum of digits and use the right
size macro
diffs (50 lines):
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -497,9 +497,10 @@ check_arguments_and_find_largest_any_typ
if (res && res->digits == 0 && (t = exp_subtype(e)) &&
(!strcmp(res->type->base.name, "char") || !strcmp(res->type->base.name,
"varchar"))) {
unsigned int tdigits = type_digits_to_char_digits(t);
if (sf->func->fix_scale == DIGITS_ADD) {
- rdigits += tdigits;
- if (rdigits >= (unsigned int) INT_MAX)
+ unsigned int nvalue = rdigits + tdigits;
+ if (nvalue < rdigits || nvalue >= (unsigned
int) INT32_MAX)
return sql_error(sql, 02,
SQLSTATE(42000) "SELECT: output number of digits for %s is too large",
sf->func->base.name);
+ rdigits = nvalue;
} else if (sf->func->fix_scale == INOUT && n ==
exps->h) {
rdigits = tdigits;
} else {
@@ -3045,9 +3046,13 @@ rel_binop_(mvc *sql, sql_rel *rel, sql_e
exp_sum_scales(f, l, r);
} else if (f->func->fix_scale == DIGITS_ADD) {
sql_subtype *res = f->res->h->data;
- res->digits = (t1->digits && t2->digits)?t1->digits +
t2->digits:0;
- if (res->digits >= (unsigned int) INT_MAX)
- return sql_error(sql, 02, SQLSTATE(42000)
"SELECT: output number of digits for %s is too large", fname);
+ if (t1->digits && t2->digits) {
+ res->digits = t1->digits + t2->digits;
+ if (res->digits < t1->digits || res->digits <
t2->digits || res->digits >= (unsigned int) INT32_MAX)
+ return sql_error(sql, 02,
SQLSTATE(42000) "SELECT: output number of digits for %s is too large", fname);
+ } else {
+ res->digits = 0;
+ }
}
if (card == card_relation && l->card > CARD_ATOM) {
sql_subfunc *zero_or_one = sql_bind_func(sql, "sys",
"zero_or_one", exp_subtype(l), NULL, F_AGGR);
@@ -3160,9 +3165,13 @@ rel_binop_(mvc *sql, sql_rel *rel, sql_e
exp_sum_scales(f, l, r);
} else if (f->func->fix_scale ==
DIGITS_ADD) {
sql_subtype *res =
f->res->h->data;
- res->digits = (t1->digits &&
t2->digits)?t1->digits + t2->digits:0;
- if (res->digits >= (unsigned
int) INT32_MAX)
- return sql_error(sql,
02, SQLSTATE(42000) "SELECT: output number of digits for %s is too large",
fname);
+ if (t1->digits && t2->digits) {
+ res->digits =
t1->digits + t2->digits;
+ if (res->digits <
t1->digits || res->digits < t2->digits || res->digits >= (unsigned int)
INT32_MAX)
+ return
sql_error(sql, 02, SQLSTATE(42000) "SELECT: output number of digits for %s is
too large", fname);
+ } else {
+ res->digits = 0;
+ }
}
return exp_binop(sql->sa, l, r, f);
}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list