From bd73b8d2cd6de4ced39064b2c152e692c2ebe342 Mon Sep 17 00:00:00 2001 From: Kevin B Kenny Date: Wed, 27 Feb 2008 02:08:23 +0000 Subject: * 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]. --- ChangeLog | 13 +++++++++++++ doc/clock.n | 1 + generic/tclClock.c | 14 +++++++++++++- library/clock.tcl | 15 ++++++++------- tests/clock.test | 38 +++++++++++++++++++++++++++++++++++++- 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 + + * 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 * 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 -- cgit v0.12