From 68198efac36df4856d044a1b80aa866199059746 Mon Sep 17 00:00:00 2001
From: Xi Wang <xi.wang@gmail.com>
Date: Sat, 26 Jan 2013 05:58:27 -0500
Subject: [PATCH 1/3] time.c (time_overflow_p): fix signed integer overflows

For `sec + n < 0' (sec, n > 0), use `sec > TIMET_MAX - n' instead.

For `sec + n > 0' (sec, n < 0), use `sec < TIMET_MIN - n' instead.
---
 time.c |   16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/time.c b/time.c
index 29565be..738c6b3 100644
--- a/time.c
+++ b/time.c
@@ -2277,24 +2277,22 @@ struct time_object {
 static void
 time_overflow_p(time_t *secp, long *nsecp)
 {
-    time_t tmp, sec = *secp;
+    time_t sec = *secp;
     long nsec = *nsecp;
 
     if (nsec >= 1000000000) {	/* nsec positive overflow */
-	tmp = sec + nsec / 1000000000;
-	nsec %= 1000000000;
-	if (sec > 0 && tmp < 0) {
+	if (sec > TIMET_MAX - nsec / 1000000000) {
 	    rb_raise(rb_eRangeError, "out of Time range");
 	}
-	sec = tmp;
+	sec += nsec / 1000000000;
+	nsec %= 1000000000;
     }
     if (nsec < 0) {		/* nsec negative overflow */
-	tmp = sec + NDIV(nsec,1000000000); /* negative div */
-	nsec = NMOD(nsec,1000000000);      /* negative mod */
-	if (sec < 0 && tmp > 0) {
+	if (sec < TIMET_MIN - NDIV(nsec,1000000000)) {
 	    rb_raise(rb_eRangeError, "out of Time range");
 	}
-	sec = tmp;
+	sec += NDIV(nsec,1000000000); /* negative div */
+	nsec = NMOD(nsec,1000000000); /* negative mod */
     }
 #ifndef NEGATIVE_TIME_T
     if (sec < 0)
-- 
1.7.10


From 6910fcb01356d740269c72a7693dabb0c0a57cd8 Mon Sep 17 00:00:00 2001
From: Xi Wang <xi.wang@gmail.com>
Date: Sat, 26 Jan 2013 06:01:30 -0500
Subject: [PATCH 2/3] xt/openssl/ossl.c (string2hex): fix signed integer
 overflow

For `2 * buf_len < buf_len' (buf_len > 0), use `buf_len > INT_MAX / 2'
instead.
---
 ext/openssl/ossl.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c
index df63294..926cac6 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -18,11 +18,12 @@
 string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
 {
     static const char hex[]="0123456789abcdef";
-    int i, len = 2 * buf_len;
+    int i, len;
 
-    if (buf_len < 0 || len < buf_len) { /* PARANOIA? */
+    if (buf_len < 0 || buf_len > INT_MAX / 2) { /* PARANOIA? */
 	return -1;
     }
+    len = 2 * buf_len;
     if (!hexbuf) { /* if no buf, return calculated len */
 	if (hexbuf_len) {
 	    *hexbuf_len = len;
-- 
1.7.10


From 041b291d35fb540701b9b58013c02815f686a0f4 Mon Sep 17 00:00:00 2001
From: Xi Wang <xi.wang@gmail.com>
Date: Sat, 26 Jan 2013 06:04:13 -0500
Subject: [PATCH 3/3] ext/bigdecimal/bigdecimal.c (AddExponent): fix signed
 integer overflow

Simplify the overflow checks for `(e + n) * BASE_FIG' as:

1) e > MAX / BASE_FIG - n (n > 0),

2) e < MIN / BASE_FIG - n (n < 0).
---
 ext/bigdecimal/bigdecimal.c |   23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index dfb5daa..2a81b64 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -3728,25 +3728,22 @@
     return VpConstOne;
 }
 
+#define SIGNED_VALUE_MAX (SIGNED_VALUE)((~(VALUE)0) >> 1)
+#define SIGNED_VALUE_MIN (SIGNED_VALUE)(~((~(VALUE)0) >> 1))
+
 /* If exponent overflows,then raise exception or returns 0 */
 static int
 AddExponent(Real *a, SIGNED_VALUE n)
 {
     SIGNED_VALUE e = a->exponent;
-    SIGNED_VALUE m = e+n;
-    SIGNED_VALUE eb, mb;
-    if(e>0) {
-        if(n>0) {
-            mb = m*(SIGNED_VALUE)BASE_FIG;
-            eb = e*(SIGNED_VALUE)BASE_FIG;
-            if(mb<eb) goto overflow;
-        }
-    } else if(n<0) {
-        mb = m*(SIGNED_VALUE)BASE_FIG;
-        eb = e*(SIGNED_VALUE)BASE_FIG;
-        if(mb>eb) goto underflow;
+    if (n > 0) {
+        if (e > SIGNED_VALUE_MAX / BASE_FIG - n)
+            goto overflow;
+    } else {
+        if (e < SIGNED_VALUE_MIN / BASE_FIG - n)
+            goto underflow;
     }
-    a->exponent = m;
+    a->exponent = e + n;
     return 1;
 
 /* Overflow/Underflow ==> Raise exception or returns 0 */
-- 
1.7.10

