summaryrefslogtreecommitdiff
path: root/pp_sys.c
diff options
context:
space:
mode:
authorMichael G. Schwern <schwern@pobox.com>2010-01-31 03:22:08 -0800
committerCraig A. Berry <craigberry@mac.com>2010-02-05 12:49:05 -0600
commitfc003d4b0d731bb670adb07e168c683339ec57e7 (patch)
treeb9a1f4d99883196df80277597ec950669ec41240 /pp_sys.c
parent23d72198749db53785b1c67cd1a37697afb95fc0 (diff)
downloadperl-fc003d4b0d731bb670adb07e168c683339ec57e7.tar.gz
Don't try to calculate a time over the conservative failure boundary.
Otherwise gmtime(2**66) will cause a very, very, very long loop and DOS Perl. Add a test that very, very large times don't send gmtime and localtime into a loop Had to fix some revealed mistakes in op/time.t when warnings were turned on. Fix Time::gmtime and Time::localtime tests to match the new limits of gm/localtime.
Diffstat (limited to 'pp_sys.c')
-rw-r--r--pp_sys.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/pp_sys.c b/pp_sys.c
index 8b5fccbd97..e7cdb594b8 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -4485,6 +4485,15 @@ PP(pp_tms)
#endif /* HAS_TIMES */
}
+/* The 32 bit int year limits the times we can represent to these
+ boundaries with a few days wiggle room to account for time zone
+ offsets
+*/
+/* Sat Jan 3 00:00:00 -2147481748 */
+#define TIME_LOWER_BOUND -67768100567755200.0
+/* Sun Dec 29 12:00:00 2147483647 */
+#define TIME_UPPER_BOUND 67767976233316800.0
+
PP(pp_gmtime)
{
dVAR;
@@ -4513,10 +4522,22 @@ PP(pp_gmtime)
}
}
- if (PL_op->op_type == OP_LOCALTIME)
- err = S_localtime64_r(&when, &tmbuf);
- else
- err = S_gmtime64_r(&when, &tmbuf);
+ if ( TIME_LOWER_BOUND > when ) {
+ Perl_ck_warner(aTHX_ packWARN(WARN_OVERFLOW),
+ "%s(%.0f) too small", opname, when);
+ err = NULL;
+ }
+ else if( when > TIME_UPPER_BOUND ) {
+ Perl_ck_warner(aTHX_ packWARN(WARN_OVERFLOW),
+ "%s(%.0f) too large", opname, when);
+ err = NULL;
+ }
+ else {
+ if (PL_op->op_type == OP_LOCALTIME)
+ err = S_localtime64_r(&when, &tmbuf);
+ else
+ err = S_gmtime64_r(&when, &tmbuf);
+ }
if (err == NULL) {
/* XXX %lld broken for quads */