summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--doc/clock.n1
-rw-r--r--generic/tclClock.c14
-rw-r--r--library/clock.tcl15
-rw-r--r--tests/clock.test38
5 files changed, 72 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index e46d6be..e483231 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2008-02-27 Kevin B. Kenny <kennykb@acm.org>
+
+ * doc/clock.n: Corrected minor indentation gaffe in the
+ penultimate paragraph. [Bug 1898025]
+ * generic/tclClock.c (ParseClockFormatArgs): Changed to check that
+ the clock value is in the range of a 64-bit integer. [Bug 1862555]
+ * library/clock.tcl (::tcl::clock::format, ::tcl::clock::scan,
+ ::tcl::clock::add, ::tcl::clock::LocalizeFormat): Fixed bugs
+ in caching of localized strings that caused weird results when
+ localized date/time formats were used. [Bug 1902423]
+ * tests/clock.test (clock-61.*, clock-62.1): Regression tests
+ for [Bug 1862555] and [Bug 1902423].
+
2008-02-26 Joe English <jenglish@users.sourceforge.net>
* generic/tclIORChan.c(enum MethodName),
diff --git a/doc/clock.n b/doc/clock.n
index fa1d6ad..600722b 100644
--- a/doc/clock.n
+++ b/doc/clock.n
@@ -882,6 +882,7 @@ unit can be specified as a singular or plural, as in \fB3 weeks\fR.
These modifiers may also be specified:
\fBtomorrow\fR, \fByesterday\fR, \fBtoday\fR, \fBnow\fR,
\fBlast\fR, \fBthis\fR, \fBnext\fR, \fBago\fR.
+.PP
The actual date is calculated according to the following steps.
.PP
First, any absolute date and/or time is processed and converted.
diff --git a/generic/tclClock.c b/generic/tclClock.c
index af88334..12c2e64 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclClock.c,v 1.65 2008/02/27 00:12:25 das Exp $
+ * RCS: @(#) $Id: tclClock.c,v 1.66 2008/02/27 02:08:27 kennykb Exp $
*/
#include "tclInt.h"
@@ -65,6 +65,7 @@ typedef enum ClockLiteral {
LIT_CE,
LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR,
LIT_ERA, LIT_GMT, LIT_GREGORIAN,
+ LIT_INTEGER_VALUE_TOO_LARGE,
LIT_ISO8601WEEK, LIT_ISO8601YEAR,
LIT_JULIANDAY, LIT_LOCALSECONDS,
LIT_MONTH,
@@ -80,6 +81,7 @@ static const char *const literals[] = {
"CE",
"dayOfMonth", "dayOfWeek", "dayOfYear",
"era", ":GMT", "gregorian",
+ "integer value too large to represent",
"iso8601Week", "iso8601Year",
"julianDay", "localSeconds",
"month",
@@ -417,6 +419,16 @@ ClockGetdatefieldsObjCmd(
return TCL_ERROR;
}
+ /*
+ * fields.seconds could be an unsigned number that overflowed. Make
+ * sure that it isn't.
+ */
+
+ if (objv[1]->typePtr == &tclBignumType) {
+ Tcl_SetObjResult(interp, literals[LIT_INTEGER_VALUE_TOO_LARGE]);
+ return TCL_ERROR;
+ }
+
/*
* Convert UTC time to local.
*/
diff --git a/library/clock.tcl b/library/clock.tcl
index 79ffc3e..c657234 100644
--- a/library/clock.tcl
+++ b/library/clock.tcl
@@ -13,7 +13,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: clock.tcl,v 1.46 2008/02/06 01:13:07 kennykb Exp $
+# RCS: @(#) $Id: clock.tcl,v 1.47 2008/02/27 02:08:27 kennykb Exp $
#
#----------------------------------------------------------------------
@@ -668,6 +668,7 @@ proc ::tcl::clock::format { args } {
variable TZData
lassign [ParseFormatArgs {*}$args] format locale timezone
+ set locale [string tolower $locale]
set clockval [lindex $args 0]
# Get the data for time changes in the given zone
@@ -1222,7 +1223,7 @@ proc ::tcl::clock::scan { args } {
set string [lindex $args 0]
set format {}
set gmt 0
- set locale C
+ set locale c
set timezone [GetSystemTimeZone]
# Pick up command line options.
@@ -1240,7 +1241,7 @@ proc ::tcl::clock::scan { args } {
set gmt $value
}
-l - -lo - -loc - -loca - -local - -locale {
- set locale $value
+ set locale [string tolower $value]
}
-t - -ti - -tim - -time - -timez - -timezo - -timezon - -timezone {
set timezone $value
@@ -2379,7 +2380,7 @@ proc ::tcl::clock::EnterLocale { locale oldLocaleVar } {
set locale ${oldLocale}_windows
if { ![dict exists $McLoaded $locale] } {
LoadWindowsDateTimeFormats $locale
- dict set mcloaded $locale {}
+ dict set McLoaded $locale {}
}
}
}
@@ -2575,7 +2576,7 @@ proc ::tcl::clock::LocalizeFormat { locale format } {
%EY [mc LOCALE_YEAR_FORMAT]\
%+ {%a %b %e %H:%M:%S %Z %Y}] $format]
- dict set McLoaded $locale FORMAT $format $inFormat
+ dict set McLoaded $locale FORMAT $inFormat $format
return $format
}
@@ -4331,7 +4332,7 @@ proc ::tcl::clock::add { clockval args } {
set offsets {}
set gmt 0
- set locale C
+ set locale c
set timezone [GetSystemTimeZone]
foreach { a b } $args {
@@ -4348,7 +4349,7 @@ proc ::tcl::clock::add { clockval args } {
set gmt $b
}
-l - -lo - -loc - -loca - -local - -locale {
- set locale $b
+ set locale [string tolower $b]
}
-t - -ti - -tim - -time - -timez - -timezo - -timezon -
-timezone {
diff --git a/tests/clock.test b/tests/clock.test
index 257b5bd..c36f5fe 100644
--- a/tests/clock.test
+++ b/tests/clock.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: clock.test,v 1.82 2008/02/06 01:13:07 kennykb Exp $
+# RCS: @(#) $Id: clock.test,v 1.83 2008/02/27 02:08:27 kennykb Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
@@ -36592,6 +36592,42 @@ test clock-60.12 {case insensitive month names} {
clock scan "1 DECEMBER 2000" -gmt true -format "%d %b %Y"
} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"]
+test clock-61.1 {overflow of a wide integer on output} {*}{
+ -body {
+ clock format 0x8000000000000000 -format %s -gmt true
+ }
+ -result {integer value too large to represent}
+ -returnCodes error
+}
+test clock-61.2 {overflow of a wide integer on output} {*}{
+ -body {
+ clock format -0x8000000000000001 -format %s -gmt true
+ }
+ -result {integer value too large to represent}
+ -returnCodes error
+}
+test clock-61.3 {near-miss overflow of a wide integer on output} {
+ clock format 0x7fffffffffffffff -format %s -gmt true
+} [expr 0x7fffffffffffffff]
+test clock-61.4 {near-miss overflow of a wide integer on output} {
+ clock format -0x8000000000000000 -format %s -gmt true
+} [expr -0x8000000000000000]
+
+test clock-62.1 {Bug 1902423} {*}{
+ -setup {::tcl::clock::ClearCaches}
+ -body {
+ set s 1204049747
+ set f1 [clock format $s -format {%Y-%m-%d %T} -locale C]
+ set f2 [clock format $s -format {%Y-%m-%d %H:%M:%S} -locale C]
+ if {$f1 ne $f2} {
+ subst "$f2 is not $f1"
+ } else {
+ subst "ok"
+ }
+ }
+ -result ok
+}
+
# cleanup
namespace delete ::testClock