Bug#1059363: gbp-import-dsc crashes when changelog contains leap seconds ("Sun, 1 Jan 2006, 00:59:60 +0100")
On 30/12/23 11:27, Guido Günther wrote: from gbp.git.modifier import GitModifier # noqa: F401 @@ -41,7 +42,11 @@ def rfc822_date_to_git(rfc822_date, fuzzy=False): >>> rfc822_date_to_git('So, 26 Feb 1998 8:50:00 +0100', fuzzy=True) '888479400 +0100' """ +rfc822_date_orig = rfc822_date +rfc822_date = rfc822_date.replace(":60 ", ":59 ") d = dateutil.parser.parse(rfc822_date, fuzzy=fuzzy) +if rfc822_date != rfc822_date_orig: # Handle leap seconds. +d += datetime.timedelta(seconds=1) That works. Could you add a line to the doctest in that function too so we check for and don't break it on accident again. Otherwise I can do it when applying the patch. Hi Guido, I'll be happy to leave the doctest to you. :) Thanks for accepting the patch. PS: Beware: the indentation may be wrong. Regards, -- Gioele Barasbucci.
Bug#1059363: gbp-import-dsc crashes when changelog contains leap seconds ("Sun, 1 Jan 2006, 00:59:60 +0100")
Hi, On Sat, Dec 23, 2023 at 05:09:48PM +0100, Gioele Barabucci wrote: > Control: tags -1 patch > > Hi Guido, > > On 23/12/23 16:57, Guido Günther wrote: > > > the gbp-import-dsc script crashes while parsing changelogs that include > > > leap > > > seconds. > > > > > > dateutil.parser._parser.ParserError: second must be in 0..59: Sun, 1 Jan > > > 2006 00:59:60 +0100 > > > > This looks like a bug in dateutil, can you reassign there? > > Not really: > > > > As of 2023-12 there is an open issue asking for support for leap seconds > > > in > > > dateutils [3]. Ah...I missed that one. We should work around it in gbp then. > from gbp.git.modifier import GitModifier # noqa: F401 > @@ -41,7 +42,11 @@ def rfc822_date_to_git(rfc822_date, fuzzy=False): > >>> rfc822_date_to_git('So, 26 Feb 1998 8:50:00 +0100', fuzzy=True) > '888479400 +0100' > """ > +rfc822_date_orig = rfc822_date > +rfc822_date = rfc822_date.replace(":60 ", ":59 ") > d = dateutil.parser.parse(rfc822_date, fuzzy=fuzzy) > +if rfc822_date != rfc822_date_orig: # Handle leap seconds. > +d += datetime.timedelta(seconds=1) That works. Could you add a line to the doctest in that function too so we check for and don't break it on accident again. Otherwise I can do it when applying the patch. Cheers, -- Guido > seconds = calendar.timegm(d.utctimetuple()) > tz = d.strftime("%z") > return '%d %s' % (seconds, tz) > -- > 2.43.0 >
Bug#1059363: gbp-import-dsc crashes when changelog contains leap seconds ("Sun, 1 Jan 2006, 00:59:60 +0100")
Control: tags -1 patch Hi Guido, On 23/12/23 16:57, Guido Günther wrote: the gbp-import-dsc script crashes while parsing changelogs that include leap seconds. dateutil.parser._parser.ParserError: second must be in 0..59: Sun, 1 Jan 2006 00:59:60 +0100 This looks like a bug in dateutil, can you reassign there? Not really: As of 2023-12 there is an open issue asking for support for leap seconds in dateutils [3]. That issue has been open for almost three years. The dateutils developers say that Python's datetime does not handle leap seconds, so they are not going to mess around with it. In order to deal with Debian policy's request to support :60, application-level workarounds are needed. Please find attached a small patch that fix this issue. Regards, -- Gioele BarabucciFrom 5dd36d1a7ed44f7cd10eb7afeb58e6c747558e91 Mon Sep 17 00:00:00 2001 From: Gioele Barabucci Date: Sat, 23 Dec 2023 17:03:39 +0100 Subject: [PATCH] git: rfc822_date_to_git: Handle leap seconds Closes: #1059363 --- gbp/git/__init__.py | 5 + 1 file changed, 5 insertions(+) diff --git a/gbp/git/__init__.py b/gbp/git/__init__.py index 3d0bb0b9..773ba822 100644 --- a/gbp/git/__init__.py +++ b/gbp/git/__init__.py @@ -17,6 +17,7 @@ """Accessing Git from python""" import calendar +import datetime import dateutil.parser from gbp.git.modifier import GitModifier # noqa: F401 @@ -41,7 +42,11 @@ def rfc822_date_to_git(rfc822_date, fuzzy=False): >>> rfc822_date_to_git('So, 26 Feb 1998 8:50:00 +0100', fuzzy=True) '888479400 +0100' """ +rfc822_date_orig = rfc822_date +rfc822_date = rfc822_date.replace(":60 ", ":59 ") d = dateutil.parser.parse(rfc822_date, fuzzy=fuzzy) +if rfc822_date != rfc822_date_orig: # Handle leap seconds. +d += datetime.timedelta(seconds=1) seconds = calendar.timegm(d.utctimetuple()) tz = d.strftime("%z") return '%d %s' % (seconds, tz) -- 2.43.0
Bug#1059363: gbp-import-dsc crashes when changelog contains leap seconds ("Sun, 1 Jan 2006, 00:59:60 +0100")
Hi, On Sat, Dec 23, 2023 at 04:48:51PM +0100, Gioele Barabucci wrote: > Package: git-buildpackage > Version: 0.9.33 > > Dear git-buildpackage maintainer, > > the gbp-import-dsc script crashes while parsing changelogs that include leap > seconds. > > For example, while parsing the changelog of unicode/5.0, gbp-import-dsc > crashes with > > ``` > File "/usr/lib/python3/dist-packages/gbp/scripts/import_dsc.py", line 116, > in get_author_from_changelog > date = rfc822_date_to_git(dch.date, fuzzy=True) > > File "/usr/lib/python3/dist-packages/gbp/git/__init__.py", line 44, in > rfc822_date_to_git > d = dateutil.parser.parse(rfc822_date, fuzzy=fuzzy) > ^^^ > File "/usr/lib/python3/dist-packages/dateutil/parser/_parser.py", line > 1368, in parse > return DEFAULTPARSER.parse(timestr, **kwargs) >^^ > File "/usr/lib/python3/dist-packages/dateutil/parser/_parser.py", line > 651, in parse > six.raise_from(ParserError(str(e) + ": %s", timestr), e) > File "", line 3, in raise_from > dateutil.parser._parser.ParserError: second must be in 0..59: Sun, 1 Jan > 2006 00:59:60 +0100 > ``` This looks like a bug in dateutil, can you reassign there? Cheers, -- Guido > > Leap seconds (:60) are explicitly permitted by Debian Policy [1] and RFC > 5322 [2] and produced by `date -R`. > > As of 2023-12 there is an open issue asking for support for leap seconds in > dateutils [3]. > > A possible solution to this issue, suggested by olasd, would to parse the > date using the stdlib method `email.utils.parsedate_tz` and handle the leap > seconds manually: > > ``` > import email, datetime > > add_leap_second = False > dateinfo = list(email.utils.parsedate_tz(rfc822_date)) > if dateinfo[5] == 60: > dateinfo[5] = 59 > add_leap_second = True > > date = datetime.datetime(*dateinfo[:6]) > > if add_leap_second: > date += datetime.timedelta(seconds=1) > ``` > > Alternatively: > > ``` > dhc_date = dch.date.replace(":60 ", ":59 ") > date = rfc822_date_to_git(dch.date, fuzzy=True) > if dch_date != dch.date: > date += datetime.timedelta(seconds=1) > ``` > > Regards, > > [1] «ss is the two-digit seconds (00-60)» > https://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog > > [2] «the time-of-day MUST be in the range 00:00:00 through 23:59:60 (the > number of seconds allowing for a leap second; see [RFC1305])» > https://datatracker.ietf.org/doc/html/rfc5322#section-3.3 > > [3] https://github.com/dateutil/dateutil/issues/1018 > > -- > Gioele Barabucci >
Bug#1059363: gbp-import-dsc crashes when changelog contains leap seconds ("Sun, 1 Jan 2006, 00:59:60 +0100")
Package: git-buildpackage Version: 0.9.33 Dear git-buildpackage maintainer, the gbp-import-dsc script crashes while parsing changelogs that include leap seconds. For example, while parsing the changelog of unicode/5.0, gbp-import-dsc crashes with ``` File "/usr/lib/python3/dist-packages/gbp/scripts/import_dsc.py", line 116, in get_author_from_changelog date = rfc822_date_to_git(dch.date, fuzzy=True) File "/usr/lib/python3/dist-packages/gbp/git/__init__.py", line 44, in rfc822_date_to_git d = dateutil.parser.parse(rfc822_date, fuzzy=fuzzy) ^^^ File "/usr/lib/python3/dist-packages/dateutil/parser/_parser.py", line 1368, in parse return DEFAULTPARSER.parse(timestr, **kwargs) ^^ File "/usr/lib/python3/dist-packages/dateutil/parser/_parser.py", line 651, in parse six.raise_from(ParserError(str(e) + ": %s", timestr), e) File "", line 3, in raise_from dateutil.parser._parser.ParserError: second must be in 0..59: Sun, 1 Jan 2006 00:59:60 +0100 ``` Leap seconds (:60) are explicitly permitted by Debian Policy [1] and RFC 5322 [2] and produced by `date -R`. As of 2023-12 there is an open issue asking for support for leap seconds in dateutils [3]. A possible solution to this issue, suggested by olasd, would to parse the date using the stdlib method `email.utils.parsedate_tz` and handle the leap seconds manually: ``` import email, datetime add_leap_second = False dateinfo = list(email.utils.parsedate_tz(rfc822_date)) if dateinfo[5] == 60: dateinfo[5] = 59 add_leap_second = True date = datetime.datetime(*dateinfo[:6]) if add_leap_second: date += datetime.timedelta(seconds=1) ``` Alternatively: ``` dhc_date = dch.date.replace(":60 ", ":59 ") date = rfc822_date_to_git(dch.date, fuzzy=True) if dch_date != dch.date: date += datetime.timedelta(seconds=1) ``` Regards, [1] «ss is the two-digit seconds (00-60)» https://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog [2] «the time-of-day MUST be in the range 00:00:00 through 23:59:60 (the number of seconds allowing for a leap second; see [RFC1305])» https://datatracker.ietf.org/doc/html/rfc5322#section-3.3 [3] https://github.com/dateutil/dateutil/issues/1018 -- Gioele Barabucci