[PATCH 1/3] Fix x + y < x overflow checks
От | Xi Wang |
---|---|
Тема | [PATCH 1/3] Fix x + y < x overflow checks |
Дата | |
Msg-id | 510100AA.4050105@gmail.com обсуждение исходный текст |
Ответ на | [PATCH 0/3] Work around icc miscompilation (Xi Wang <xi.wang@gmail.com>) |
Ответы |
Re: [PATCH 1/3] Fix x + y < x overflow checks
(Claudio Freire <klaussfreire@gmail.com>)
Re: [PATCH 1/3] Fix x + y < x overflow checks (Robert Haas <robertmhaas@gmail.com>) |
Список | pgsql-hackers |
icc optimizes away the overflow check x + y < x (y > 0), because signed integer overflow is undefined behavior in C. Instead, use a safe precondition test x > INT_MAX - y. ---src/backend/utils/adt/varbit.c | 7 +++++--src/backend/utils/adt/varlena.c | 10 ++++++----src/pl/plpgsql/src/pl_exec.c | 4 ++--3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c index 1712c12..af69200 100644 --- a/src/backend/utils/adt/varbit.c +++ b/src/backend/utils/adt/varbit.c @@ -16,6 +16,8 @@#include "postgres.h" +#include <limits.h> +#include "access/htup_details.h"#include "libpq/pqformat.h"#include "nodes/nodeFuncs.h" @@ -1138,12 +1140,13 @@ bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl) ereport(ERROR, (errcode(ERRCODE_SUBSTRING_ERROR), errmsg("negative substring length not allowed"))); - sp_pl_sl = sp + sl; - if (sp_pl_sl <= sl) + if (sl > INT_MAX - sp) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); + sp_pl_sl = sp + sl; + s1 = bitsubstring(t1, 1, sp - 1, false); s2 = bitsubstring(t1, sp_pl_sl, -1, true); result = bit_catenate(s1,t2); diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 95e41bf..c907f44 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -997,12 +997,13 @@ text_overlay(text *t1, text *t2, int sp, int sl) ereport(ERROR, (errcode(ERRCODE_SUBSTRING_ERROR), errmsg("negative substring length not allowed"))); - sp_pl_sl = sp + sl; - if (sp_pl_sl <= sl) + if (sl > INT_MAX - sp) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); + sp_pl_sl = sp + sl; + s1 = text_substring(PointerGetDatum(t1), 1, sp - 1, false); s2 = text_substring(PointerGetDatum(t1), sp_pl_sl, -1,true); result = text_catenate(s1, t2); @@ -2020,12 +2021,13 @@ bytea_overlay(bytea *t1, bytea *t2, int sp, int sl) ereport(ERROR, (errcode(ERRCODE_SUBSTRING_ERROR), errmsg("negative substring length not allowed"))); - sp_pl_sl = sp + sl; - if (sp_pl_sl <= sl) + if (sl > INT_MAX - sp) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); + sp_pl_sl = sp + sl; + s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false); s2 = bytea_substring(PointerGetDatum(t1), sp_pl_sl,-1, true); result = bytea_catenate(s1, t2); diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 0ecf651..a9cf6df 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -1972,13 +1972,13 @@ exec_stmt_fori(PLpgSQL_execstate *estate, PLpgSQL_stmt_fori *stmt) */ if (stmt->reverse) { - if ((int32) (loop_value - step_value) > loop_value) + if (loop_value < INT_MIN + step_value) break; loop_value -= step_value; } else { - if ((int32) (loop_value + step_value) < loop_value) + if (loop_value > INT_MAX - step_value) break; loop_value += step_value; } -- 1.7.10.4
В списке pgsql-hackers по дате отправления: