icc optimizes away `check + VARHDRSZ <= check' since signed integer
overflow is undefined behavior.  Simplify the overflow check for
`VARHDRSZ + count * slen' as `count > (INT_MAX - VARHDRSZ) / slen'.
---
 src/backend/utils/adt/oracle_compat.c |   18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/src/backend/utils/adt/oracle_compat.c 
b/src/backend/utils/adt/oracle_compat.c
index d448088..a85a672 100644
--- a/src/backend/utils/adt/oracle_compat.c
+++ b/src/backend/utils/adt/oracle_compat.c
@@ -15,6 +15,8 @@
  */
 #include "postgres.h"
 
+#include <limits.h>
+
 #include "utils/builtins.h"
 #include "utils/formatting.h"
 #include "mb/pg_wchar.h"
@@ -1034,20 +1036,14 @@ repeat(PG_FUNCTION_ARGS)
                count = 0;
 
        slen = VARSIZE_ANY_EXHDR(string);
-       tlen = VARHDRSZ + (count * slen);
 
        /* Check for integer overflow */
-       if (slen != 0 && count != 0)
-       {
-               int                     check = count * slen;
-               int                     check2 = check + VARHDRSZ;
-
-               if ((check / slen) != count || check2 <= check)
-                       ereport(ERROR,
-                                       
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-                                        errmsg("requested length too large")));
-       }
+       if (slen != 0 && count > (INT_MAX - VARHDRSZ) / slen)
+               ereport(ERROR,
+                               (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+                                errmsg("requested length too large")));
 
+       tlen = VARHDRSZ + (count * slen);
        result = (text *) palloc(tlen);
 
        SET_VARSIZE(result, tlen);
-- 
1.7.10.4



-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to