aboutsummaryrefslogtreecommitdiffstats
path: root/time.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-08 12:13:04 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-08 12:13:04 +0000
commit319dc9f6c6e54da0e0c340ace57db1de4606b762 (patch)
treed5233a16e47034d3c75f270c2bb83f3e3123a9c4 /time.c
parent2391ee2c6130797d2885da0fb1180bfba737971a (diff)
downloadruby-319dc9f6c6e54da0e0c340ace57db1de4606b762.tar.gz
* time.c (time_overflow_p): Avoid signed integer overflow.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42445 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'time.c')
-rw-r--r--time.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/time.c b/time.c
index 211fcead07..de914e36e3 100644
--- a/time.c
+++ b/time.c
@@ -2217,24 +2217,25 @@ time_init(int argc, VALUE *argv, VALUE time)
static void
time_overflow_p(time_t *secp, long *nsecp)
{
- time_t tmp, sec = *secp;
+ time_t sec = *secp;
long nsec = *nsecp;
+ long sec2;
if (nsec >= 1000000000) { /* nsec positive overflow */
- tmp = sec + nsec / 1000000000;
- nsec %= 1000000000;
- if (sec > 0 && tmp < 0) {
+ sec2 = nsec / 1000000000;
+ if (TIMET_MAX - sec2 < sec) {
rb_raise(rb_eRangeError, "out of Time range");
}
- sec = tmp;
+ nsec %= 1000000000;
+ sec += sec2;
}
if (nsec < 0) { /* nsec negative overflow */
- tmp = sec + NDIV(nsec,1000000000); /* negative div */
- nsec = NMOD(nsec,1000000000); /* negative mod */
- if (sec < 0 && tmp > 0) {
+ sec2 = NDIV(nsec,1000000000); /* negative div */
+ if (sec < TIMET_MAX - sec2) {
rb_raise(rb_eRangeError, "out of Time range");
}
- sec = tmp;
+ nsec = NMOD(nsec,1000000000); /* negative mod */
+ sec = sec + sec2;
}
#ifndef NEGATIVE_TIME_T
if (sec < 0)