Submitter | Florent Gallaire |
---|---|
Date | April 4, 2016, 2:40 p.m. |
Message ID | <CAB9F1ccD_2LyxVYSdj0rkf5L+dpj=9Hg1HxSaFPHd8C8GHg8_g@mail.gmail.com> |
Download | mbox | patch |
Permalink | /patch/14345/ |
State | Changes Requested |
Delegated to: | Yuya Nishihara |
Headers | show |
Comments
On Mon, 4 Apr 2016 16:40:23 +0200, Florent Gallaire wrote: > # HG changeset patch > # User Florent Gallaire <fgallaire@gmail.com> > # Date 1459780256 -7200 > # Mon Apr 04 16:30:56 2016 +0200 > # Node ID 0fb1c7daaaf8a5c90ae4dce904a60013b9abe5aa > # Parent ff0d3b6b287f89594bd8d0308fe2810d2a18ea01 > date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513) It appears that the devs agreed to allow negative timestamps, and the code looks mostly good to me. I wanted to queue this, but I got test failure on Windows. Can you take a look? > + if abs(d) > 0x7fffffff: > + d = cmp(d, 0) * 0x7fffffff Nit: cmp() isn't guaranteed to return -1 or 1, and it's been removed in Python3. Perhaps it could be replaced by min() and max(). https://docs.python.org/2.7/library/functions.html#cmp http://stackoverflow.com/a/10635142 > --- a/tests/test-commit.t Tue Mar 29 12:29:00 2016 -0500 > +++ b/tests/test-commit.t Mon Apr 04 16:30:56 2016 +0200 > @@ -27,8 +27,57 @@ > $ hg commit -d '111111111111 0' -m commit-7 > abort: date exceeds 32 bits: 111111111111 > [255] > - $ hg commit -d '-7654321 3600' -m commit-7 > - abort: negative date value: -7654321 > + $ hg commit -d '-111111111111 0' -m commit-7 > + abort: date exceeds 32 bits: -111111111111 > + [255] > + $ echo foo >> foo > + $ hg commit -d '1901-12-13 20:45:53 +0000' -m commit-7-2 > + $ echo foo >> foo > + $ hg commit -d '-2147483647 0' -m commit-7-3 > + $ hg commit -d '1901-12-13 20:45:52 +0000' -m commit-7 Perhaps we should test datestr(), for example: $ hg log -T '{rev} {date|isodatesec}\n' -l2 3 1901-12-13 20:45:53 +0000 2 1901-12-13 20:45:53 +0000 > + abort: date exceeds 32 bits: -2147483648 > + [255] > + $ hg commit -d '-2147483648 0' -m commit-7 > + abort: date exceeds 32 bits: -2147483648 > + [255] > + $ hg commit -d '1900-01-01 00:00:00 +0000' -m commit-7 > + abort: date exceeds 32 bits: -2208988800 > + [255] I got different error on Windows XP (32bit) probably because parsedate() doesn't support overflow dates. Because this patch doesn't touch parsing of date strings, I think we can drop the tests of "1900-01-01" and "1899-12-31". $ hg commit -d '1900-01-01 00:00:00' -m commit-7 - abort: date exceeds 32 bits: -2208988800 + abort: invalid date: '1900-01-01 00:00:00' [255] $ hg commit -d '1900-01-01 +0000' -m commit-7 abort: date exceeds 32 bits: -2208988800 [255] $ hg commit -d '1900-01-01' -m commit-7 - abort: date exceeds 32 bits: -2208988800 + abort: invalid date: '1900-01-01' [255] $ hg commit -d '-2208988800 0' -m commit-7 abort: date exceeds 32 bits: -2208988800 > + $ hg commit -d '1900-01-01 00:00:00' -m commit-7 > + abort: date exceeds 32 bits: -2208988800 > + [255] > + $ hg commit -d '1900-01-01 +0000' -m commit-7 > + abort: date exceeds 32 bits: -2208988800 > + [255] > + $ hg commit -d '1900-01-01' -m commit-7 > + abort: date exceeds 32 bits: -2208988800 > + [255] > + $ hg commit -d '-2208988800 0' -m commit-7 > + abort: date exceeds 32 bits: -2208988800 > + [255] > + $ hg commit -d '1899-12-31 23:59:59 +0000' -m commit-7 > + abort: date exceeds 32 bits: -2208988801 > + [255] > + $ hg commit -d '1899-12-31 23:59:59' -m commit-7 > + abort: invalid date: '1899-12-31 23:59:59' > + [255] > + $ hg commit -d '-2208988801 0' -m commit-7 > + abort: date exceeds 32 bits: -2208988801 > + [255] > + $ hg commit -d '1899-12-31 00:00:00 +0000' -m commit-7 > + abort: date exceeds 32 bits: -2209075200 > + [255] > + $ hg commit -d '1899-12-31 00:00:00' -m commit-7 > + abort: invalid date: '1899-12-31 00:00:00' > + [255] > + $ hg commit -d '1899-12-31 +0000' -m commit-7 > + abort: date exceeds 32 bits: -2209075200 > + [255] > + $ hg commit -d '1899-12-31' -m commit-7 > + abort: invalid date: '1899-12-31' > + [255] > + $ hg commit -d '-2209075200 0' -m commit-7 > + abort: date exceeds 32 bits: -2209075200 > [255]
2016-04-06 16:25 GMT+02:00 Yuya Nishihara <yuya@tcha.org>: >> + if abs(d) > 0x7fffffff: >> + d = cmp(d, 0) * 0x7fffffff > > Nit: cmp() isn't guaranteed to return -1 or 1, and it's been removed in Python3. > Perhaps it could be replaced by min() and max(). > > https://docs.python.org/2.7/library/functions.html#cmp > http://stackoverflow.com/a/10635142 > Problems seem unlikely but still possible, I will fix that the simpler way. > Perhaps we should test datestr(), for example: > > $ hg log -T '{rev} {date|isodatesec}\n' -l2 > 3 1901-12-13 20:45:53 +0000 > 2 1901-12-13 20:45:53 +0000 Yes, that's fine. > I got different error on Windows XP (32bit) probably because parsedate() > doesn't support overflow dates. Because this patch doesn't touch parsing of > date strings, I think we can drop the tests of "1900-01-01" and "1899-12-31". I agree. Florent
Patch
diff -r ff0d3b6b287f -r 0fb1c7daaaf8 mercurial/util.py --- a/mercurial/util.py Tue Mar 29 12:29:00 2016 -0500 +++ b/mercurial/util.py Mon Apr 04 16:30:56 2016 +0200 @@ -1578,9 +1578,6 @@ number of seconds away from UTC. if timezone is false, do not append time zone to string.""" t, tz = date or makedate() - if t < 0: - t = 0 # time.gmtime(lt) fails on Windows for lt < -43200 - tz = 0 if "%1" in format or "%2" in format or "%z" in format: sign = (tz > 0) and "-" or "+" minutes = abs(tz) // 60 @@ -1588,12 +1585,14 @@ format = format.replace("%z", "%1%2") format = format.replace("%1", "%c%02d" % (sign, q)) format = format.replace("%2", "%02d" % r) - try: - t = time.gmtime(float(t) - tz) - except ValueError: - # time was out of range - t = time.gmtime(sys.maxint) - s = time.strftime(format, t) + d = t - tz + if abs(d) > 0x7fffffff: + d = cmp(d, 0) * 0x7fffffff + # Never use time.gmtime() and datetime.datetime.fromtimestamp() + # because they use the gmtime() system call which is buggy on Windows + # for negative values. + t = datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=d) + s = t.strftime(format) return s def shortdate(date=None): @@ -1714,8 +1713,6 @@ # to UTC+14 if abs(when) > 0x7fffffff: raise Abort(_('date exceeds 32 bits: %d') % when) - if when < 0: - raise Abort(_('negative date value: %d') % when) if offset < -50400 or offset > 43200: raise Abort(_('impossible time zone offset: %d') % offset) return when, offset diff -r ff0d3b6b287f -r 0fb1c7daaaf8 tests/test-commit.t --- a/tests/test-commit.t Tue Mar 29 12:29:00 2016 -0500 +++ b/tests/test-commit.t Mon Apr 04 16:30:56 2016 +0200 @@ -27,8 +27,57 @@ $ hg commit -d '111111111111 0' -m commit-7 abort: date exceeds 32 bits: 111111111111 [255] - $ hg commit -d '-7654321 3600' -m commit-7 - abort: negative date value: -7654321 + $ hg commit -d '-111111111111 0' -m commit-7 + abort: date exceeds 32 bits: -111111111111 + [255] + $ echo foo >> foo + $ hg commit -d '1901-12-13 20:45:53 +0000' -m commit-7-2 + $ echo foo >> foo + $ hg commit -d '-2147483647 0' -m commit-7-3 + $ hg commit -d '1901-12-13 20:45:52 +0000' -m commit-7 + abort: date exceeds 32 bits: -2147483648 + [255] + $ hg commit -d '-2147483648 0' -m commit-7 + abort: date exceeds 32 bits: -2147483648 + [255] + $ hg commit -d '1900-01-01 00:00:00 +0000' -m commit-7 + abort: date exceeds 32 bits: -2208988800 + [255] + $ hg commit -d '1900-01-01 00:00:00' -m commit-7 + abort: date exceeds 32 bits: -2208988800 + [255] + $ hg commit -d '1900-01-01 +0000' -m commit-7 + abort: date exceeds 32 bits: -2208988800 + [255] + $ hg commit -d '1900-01-01' -m commit-7 + abort: date exceeds 32 bits: -2208988800 + [255] + $ hg commit -d '-2208988800 0' -m commit-7 + abort: date exceeds 32 bits: -2208988800 + [255] + $ hg commit -d '1899-12-31 23:59:59 +0000' -m commit-7 + abort: date exceeds 32 bits: -2208988801 + [255] + $ hg commit -d '1899-12-31 23:59:59' -m commit-7 + abort: invalid date: '1899-12-31 23:59:59' + [255] + $ hg commit -d '-2208988801 0' -m commit-7 + abort: date exceeds 32 bits: -2208988801 + [255] + $ hg commit -d '1899-12-31 00:00:00 +0000' -m commit-7 + abort: date exceeds 32 bits: -2209075200 + [255] + $ hg commit -d '1899-12-31 00:00:00' -m commit-7 + abort: invalid date: '1899-12-31 00:00:00' + [255] + $ hg commit -d '1899-12-31 +0000' -m commit-7 + abort: date exceeds 32 bits: -2209075200 + [255] + $ hg commit -d '1899-12-31' -m commit-7 + abort: invalid date: '1899-12-31' + [255] + $ hg commit -d '-2209075200 0' -m commit-7 + abort: date exceeds 32 bits: -2209075200 [255] commit added file that has been deleted @@ -54,7 +103,7 @@ dir/file committing manifest committing changelog - committed changeset 2:d2a76177cb42 + committed changeset 4:76aab26859d7 $ echo > dir.file $ hg add @@ -78,7 +127,7 @@ dir/file committing manifest committing changelog - committed changeset 3:1cd62a2d8db5 + committed changeset 5:9a50557f1baf $ cd .. $ hg commit -m commit-14 does-not-exist @@ -102,7 +151,7 @@ dir/file committing manifest committing changelog - committed changeset 4:49176991390e + committed changeset 6:4b4c75bf422d An empty date was interpreted as epoch origin _______________________________________________