From 538a75fe4e130a797c0e0a2c2a8dd63ae30d3449 Mon Sep 17 00:00:00 2001 From: Lauri Nurmi Date: Wed, 9 Mar 2022 20:14:20 +0200 Subject: [PATCH] Decode 2-digit years properly in ParseRfc822Date() The RFC accepts 2-digit years, and it makes most sense to interpret e.g. 95 as 1995. However, this is an incompatible change, as earlier 95 was literally decoded as 95 AD. Years 00..29 are considered to mean 20xx; 30..99 means 19xx. Closes #22196. --- docs/changes.txt | 3 +++ src/common/datetimefmt.cpp | 21 +++++++++++++++++++++ tests/datetime/datetimetest.cpp | 14 ++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index 73fba50a6a..288cbb616f 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -142,6 +142,9 @@ Changes in behaviour not resulting in compilation errors - wxRichTextParagraph::GetLines() now returns const wxVector& instead of wxList&. +- wxDateTime::ParseRfc822Date() now interprets a 2-digit year as 19xx, or + 20xx for 00..29, whereas earlier e.g. 95 was interpreted literally as 95 AD. + Changes in behaviour which may result in build errors ----------------------------------------------------- diff --git a/src/common/datetimefmt.cpp b/src/common/datetimefmt.cpp index c26a0e64b8..0a8d753c22 100644 --- a/src/common/datetimefmt.cpp +++ b/src/common/datetimefmt.cpp @@ -819,6 +819,27 @@ wxDateTime::ParseRfc822Date(const wxString& originalDate, wxString::const_iterat year *= 10; year += *p++ - '0'; } + else // a 2-digit year + { + // RFC 822 allows 2-digit years, stating that year is + // "any numeric year 1900 or later". + // So how do we interpret e.g. the year '95'? Does it mean: + // a) 1995 + // b) 2095 + // c) literally 95 AD, two millennia ago? + // NOTE! wx traditionally implemented option c! + // However, the most sensible interpretation for 95 is + // probably 1995, so we shall now use that. + // Years 00..29 are considered to mean 20xx. + if ( year >= 30 ) + { + year += 1900; + } + else + { + year += 2000; + } + } if ( *p++ != ' ' ) return false; diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp index 38f8ce1d22..252c7b6c35 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -1100,6 +1100,20 @@ void DateTimeTestCase::TestParseRFC822() true }, + // 2-digit year is accepted by the RFC822 + { + "Sat, 18 Dec 99 10:48:30 -0500", + { 18, wxDateTime::Dec, 1999, 15, 48, 30 }, + true + }, + + // years 00..29 are considered to mean 20xx + { + "Tue, 18 Dec 29 10:48:30 -0500", + { 18, wxDateTime::Dec, 2029, 15, 48, 30 }, + true + }, + // try some bogus ones too { "Sun, 01 Jun 2008 16:30: +0200",