Gentoo Archives: gentoo-commits

From: Andreas Sturmlechner <asturm@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/qt:master commit in: dev-qt/qtcore/files/, dev-qt/qtcore/
Date: Thu, 30 Sep 2021 11:35:34
Message-Id: 1632999351.e65b89b6e937ac0a2b3a37e07b08407511b6a692.asturm@gentoo
1 commit: e65b89b6e937ac0a2b3a37e07b08407511b6a692
2 Author: Andreas K. Hüttel <dilfridge <AT> gentoo <DOT> org>
3 AuthorDate: Sat Oct 10 17:39:33 2020 +0000
4 Commit: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
5 CommitDate: Thu Sep 30 10:55:51 2021 +0000
6 URL: https://gitweb.gentoo.org/proj/qt.git/commit/?id=e65b89b6
7
8 dev-qt/qtcore: Revert timezone handling to 5.14 state
9
10 This is an obvious workaround, until we and upstream have
11 decided what to do...
12
13 (sync with Gentoo ebuild repository)
14
15 Package-Manager: Portage-3.0.4, Repoman-3.0.1
16 Signed-off-by: Andreas K. Hüttel <dilfridge <AT> gentoo.org>
17 Signed-off-by: Andreas Sturmlechner <asturm <AT> gentoo.org>
18
19 dev-qt/qtcore/files/qtcore-5.15.1-timezone-1.patch | 271 +++++++++++++++++++++
20 dev-qt/qtcore/files/qtcore-5.15.1-timezone-2.patch | 47 ++++
21 dev-qt/qtcore/qtcore-5.15.2.9999.ebuild | 5 +-
22 3 files changed, 322 insertions(+), 1 deletion(-)
23
24 diff --git a/dev-qt/qtcore/files/qtcore-5.15.1-timezone-1.patch b/dev-qt/qtcore/files/qtcore-5.15.1-timezone-1.patch
25 new file mode 100644
26 index 00000000..1c8f1e89
27 --- /dev/null
28 +++ b/dev-qt/qtcore/files/qtcore-5.15.1-timezone-1.patch
29 @@ -0,0 +1,271 @@
30 +From c337f6fae51b987ce7dbed1fd9bea41e6073efbb Mon Sep 17 00:00:00 2001
31 +From: =?UTF-8?q?Andreas=20K=2E=20H=C3=BCttel?= <dilfridge@g.o>
32 +Date: Sat, 10 Oct 2020 19:26:13 +0200
33 +Subject: [PATCH 1/2] Revert "Cache system zone ID when fetched from the
34 + file-system"
35 +
36 +This reverts commit c70ce3d042025c858faffe661f85d2482a2a0d8c.
37 +---
38 + src/corelib/time/qtimezoneprivate_tz.cpp | 205 +++++++----------------
39 + 1 file changed, 64 insertions(+), 141 deletions(-)
40 +
41 +diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp
42 +index c5c70b7364..01f9a6cce0 100644
43 +--- a/src/corelib/time/qtimezoneprivate_tz.cpp
44 ++++ b/src/corelib/time/qtimezoneprivate_tz.cpp
45 +@@ -1,6 +1,5 @@
46 + /****************************************************************************
47 + **
48 +-** Copyright (C) 2020 The Qt Company Ltd.
49 + ** Copyright (C) 2019 Crimson AS <info@×××××××.no>
50 + ** Copyright (C) 2013 John Layt <jlayt@×××.org>
51 + ** Contact: https://www.qt.io/licensing/
52 +@@ -43,19 +42,18 @@
53 + #include "qtimezoneprivate_p.h"
54 + #include "private/qlocale_tools_p.h"
55 +
56 +-#include <QtCore/QDataStream>
57 +-#include <QtCore/QDateTime>
58 + #include <QtCore/QFile>
59 +-#include <QtCore/QHash>
60 + #include <QtCore/QMutex>
61 ++#include <QtCore/QHash>
62 ++#include <QtCore/QDataStream>
63 ++#include <QtCore/QDateTime>
64 +
65 + #include <qdebug.h>
66 +-#include <qplatformdefs.h>
67 +
68 + #include <algorithm>
69 + #include <errno.h>
70 + #include <limits.h>
71 +-#ifndef Q_OS_INTEGRITY
72 ++#if !defined(Q_OS_INTEGRITY)
73 + #include <sys/param.h> // to use MAXSYMLINKS constant
74 + #endif
75 + #include <unistd.h> // to use _SC_SYMLOOP_MAX constant
76 +@@ -1102,146 +1100,28 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs
77 + return last > tranCache().cbegin() ? dataForTzTransition(*--last) : invalidData();
78 + }
79 +
80 +-bool QTzTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
81 +-{
82 +- return tzZones->contains(ianaId);
83 +-}
84 +-
85 +-QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds() const
86 +-{
87 +- QList<QByteArray> result = tzZones->keys();
88 +- std::sort(result.begin(), result.end());
89 +- return result;
90 +-}
91 +-
92 +-QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds(QLocale::Country country) const
93 ++static long getSymloopMax()
94 + {
95 +- // TODO AnyCountry
96 +- QList<QByteArray> result;
97 +- for (auto it = tzZones->cbegin(), end = tzZones->cend(); it != end; ++it) {
98 +- if (it.value().country == country)
99 +- result << it.key();
100 +- }
101 +- std::sort(result.begin(), result.end());
102 +- return result;
103 +-}
104 +-
105 +-// Getting the system zone's ID:
106 +-
107 +-namespace {
108 +-class ZoneNameReader : public QObject
109 +-{
110 +-public:
111 +- QByteArray name()
112 +- {
113 +- /* Assumptions:
114 +- a) Systems don't change which of localtime and TZ they use without a
115 +- reboot.
116 +- b) When they change, they use atomic renames, hence a new device and
117 +- inode for the new file.
118 +- c) If we change which *name* is used for a zone, while referencing
119 +- the same final zoneinfo file, we don't care about the change of
120 +- name (e.g. if Europe/Oslo and Europe/Berlin are both symlinks to
121 +- the same CET file, continuing to use the old name, after
122 +- /etc/localtime changes which of the two it points to, is
123 +- harmless).
124 +-
125 +- The alternative would be to use a file-system watcher, but they are a
126 +- scarce resource.
127 +- */
128 +- const StatIdent local = identify("/etc/localtime");
129 +- const StatIdent tz = identify("/etc/TZ");
130 +- if (!m_name.isEmpty() && m_last.isValid() && (m_last == local || m_last == tz))
131 +- return m_name;
132 +-
133 +- m_name = etcLocalTime();
134 +- if (!m_name.isEmpty()) {
135 +- m_last = local;
136 +- return m_name;
137 +- }
138 +-
139 +- m_name = etcTZ();
140 +- m_last = m_name.isEmpty() ? StatIdent() : tz;
141 +- return m_name;
142 +- }
143 +-
144 +-
145 +-private:
146 +- QByteArray m_name;
147 +- struct StatIdent
148 +- {
149 +- static constexpr unsigned long bad = ~0ul;
150 +- unsigned long m_dev, m_ino;
151 +- StatIdent() : m_dev(bad), m_ino(bad) {}
152 +- StatIdent(const QT_STATBUF &data) : m_dev(data.st_dev), m_ino(data.st_ino) {}
153 +- bool isValid() { return m_dev != bad || m_ino != bad; }
154 +- bool operator==(const StatIdent &other)
155 +- { return other.m_dev == m_dev && other.m_ino == m_ino; }
156 +- };
157 +- StatIdent m_last;
158 +-
159 +- static StatIdent identify(const char *path)
160 +- {
161 +- QT_STATBUF data;
162 +- return QT_STAT(path, &data) == -1 ? StatIdent() : StatIdent(data);
163 +- }
164 +-
165 +- static QByteArray etcLocalTime()
166 +- {
167 +- // On most distros /etc/localtime is a symlink to a real file so extract
168 +- // name from the path
169 +- const QLatin1String zoneinfo("/zoneinfo/");
170 +- QString path = QStringLiteral("/etc/localtime");
171 +- long iteration = getSymloopMax();
172 +- // Symlink may point to another symlink etc. before being under zoneinfo/
173 +- // We stop on the first path under /zoneinfo/, even if it is itself a
174 +- // symlink, like America/Montreal pointing to America/Toronto
175 +- do {
176 +- path = QFile::symLinkTarget(path);
177 +- int index = path.indexOf(zoneinfo);
178 +- if (index >= 0) // Found zoneinfo file; extract zone name from path:
179 +- return path.midRef(index + zoneinfo.size()).toUtf8();
180 +- } while (!path.isEmpty() && --iteration > 0);
181 +-
182 +- return QByteArray();
183 +- }
184 +-
185 +- static QByteArray etcTZ()
186 +- {
187 +- // Some systems (e.g. uClibc) have a default value for $TZ in /etc/TZ:
188 +- const QString path = QStringLiteral("/etc/TZ");
189 +- QFile zone(path);
190 +- if (zone.open(QIODevice::ReadOnly))
191 +- return zone.readAll().trimmed();
192 +-
193 +- return QByteArray();
194 +- }
195 +-
196 +- // Any chain of symlinks longer than this is assumed to be a loop:
197 +- static long getSymloopMax()
198 +- {
199 +-#ifdef SYMLOOP_MAX
200 +- // If defined, at runtime it can only be greater than this, so this is a safe bet:
201 +- return SYMLOOP_MAX;
202 ++#if defined(SYMLOOP_MAX)
203 ++ return SYMLOOP_MAX; // if defined, at runtime it can only be greater than this, so this is a safe bet
204 + #else
205 +- errno = 0;
206 +- long result = sysconf(_SC_SYMLOOP_MAX);
207 +- if (result >= 0)
208 +- return result;
209 +- // result is -1, meaning either error or no limit
210 +- Q_ASSERT(!errno); // ... but it can't be an error, POSIX mandates _SC_SYMLOOP_MAX
211 +-
212 +- // therefore we can make up our own limit
213 +-# ifdef MAXSYMLINKS
214 +- return MAXSYMLINKS;
215 ++ errno = 0;
216 ++ long result = sysconf(_SC_SYMLOOP_MAX);
217 ++ if (result >= 0)
218 ++ return result;
219 ++ // result is -1, meaning either error or no limit
220 ++ Q_ASSERT(!errno); // ... but it can't be an error, POSIX mandates _SC_SYMLOOP_MAX
221 ++
222 ++ // therefore we can make up our own limit
223 ++# if defined(MAXSYMLINKS)
224 ++ return MAXSYMLINKS;
225 + # else
226 +- return 8;
227 ++ return 8;
228 + # endif
229 + #endif
230 +- }
231 +-};
232 + }
233 +
234 ++// TODO Could cache the value and monitor the required files for any changes
235 + QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
236 + {
237 + // Check TZ env var first, if not populated try find it
238 +@@ -1256,9 +1136,28 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
239 + else if (ianaId.startsWith(':'))
240 + ianaId = ianaId.mid(1);
241 +
242 ++ // On most distros /etc/localtime is a symlink to a real file so extract name from the path
243 ++ if (ianaId.isEmpty()) {
244 ++ const QLatin1String zoneinfo("/zoneinfo/");
245 ++ QString path = QFile::symLinkTarget(QStringLiteral("/etc/localtime"));
246 ++ int index = -1;
247 ++ long iteration = getSymloopMax();
248 ++ // Symlink may point to another symlink etc. before being under zoneinfo/
249 ++ // We stop on the first path under /zoneinfo/, even if it is itself a
250 ++ // symlink, like America/Montreal pointing to America/Toronto
251 ++ while (iteration-- > 0 && !path.isEmpty() && (index = path.indexOf(zoneinfo)) < 0)
252 ++ path = QFile::symLinkTarget(path);
253 ++ if (index >= 0) {
254 ++ // /etc/localtime is a symlink to the current TZ file, so extract from path
255 ++ ianaId = path.midRef(index + zoneinfo.size()).toUtf8();
256 ++ }
257 ++ }
258 ++
259 ++ // Some systems (e.g. uClibc) have a default value for $TZ in /etc/TZ:
260 + if (ianaId.isEmpty()) {
261 +- thread_local static ZoneNameReader reader;
262 +- ianaId = reader.name();
263 ++ QFile zone(QStringLiteral("/etc/TZ"));
264 ++ if (zone.open(QIODevice::ReadOnly))
265 ++ ianaId = zone.readAll().trimmed();
266 + }
267 +
268 + // Give up for now and return UTC
269 +@@ -1268,4 +1167,28 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
270 + return ianaId;
271 + }
272 +
273 ++bool QTzTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
274 ++{
275 ++ return tzZones->contains(ianaId);
276 ++}
277 ++
278 ++QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds() const
279 ++{
280 ++ QList<QByteArray> result = tzZones->keys();
281 ++ std::sort(result.begin(), result.end());
282 ++ return result;
283 ++}
284 ++
285 ++QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds(QLocale::Country country) const
286 ++{
287 ++ // TODO AnyCountry
288 ++ QList<QByteArray> result;
289 ++ for (auto it = tzZones->cbegin(), end = tzZones->cend(); it != end; ++it) {
290 ++ if (it.value().country == country)
291 ++ result << it.key();
292 ++ }
293 ++ std::sort(result.begin(), result.end());
294 ++ return result;
295 ++}
296 ++
297 + QT_END_NAMESPACE
298 +--
299 +2.28.0
300 +
301
302 diff --git a/dev-qt/qtcore/files/qtcore-5.15.1-timezone-2.patch b/dev-qt/qtcore/files/qtcore-5.15.1-timezone-2.patch
303 new file mode 100644
304 index 00000000..611c979a
305 --- /dev/null
306 +++ b/dev-qt/qtcore/files/qtcore-5.15.1-timezone-2.patch
307 @@ -0,0 +1,47 @@
308 +From ffc9093a199a542791920b30d1835c3248920aa0 Mon Sep 17 00:00:00 2001
309 +From: =?UTF-8?q?Andreas=20K=2E=20H=C3=BCttel?= <dilfridge@g.o>
310 +Date: Sat, 10 Oct 2020 19:26:35 +0200
311 +Subject: [PATCH 2/2] Revert "Purge two old time-zone lookup fallbacks"
312 +
313 +This reverts commit b0383cbd388336f698ceeac11a4f50cdff931dd9.
314 +---
315 + src/corelib/time/qtimezoneprivate_tz.cpp | 23 +++++++++++++++++++++++
316 + 1 file changed, 23 insertions(+)
317 +
318 +diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp
319 +index 01f9a6cce0..eea6f5e962 100644
320 +--- a/src/corelib/time/qtimezoneprivate_tz.cpp
321 ++++ b/src/corelib/time/qtimezoneprivate_tz.cpp
322 +@@ -1153,6 +1153,29 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
323 + }
324 + }
325 +
326 ++ // On Debian Etch up to Jessie, /etc/localtime is a copy of the relevant
327 ++ // zoneinfo file, whose name is recorded in /etc/timezone:
328 ++ if (ianaId.isEmpty()) {
329 ++ QFile tzif(QStringLiteral("/etc/timezone"));
330 ++ if (tzif.open(QIODevice::ReadOnly))
331 ++ ianaId = tzif.readAll().trimmed();
332 ++ }
333 ++
334 ++ // On some Red Hat distros /etc/localtime is real file with name held in /etc/sysconfig/clock
335 ++ // in a line like ZONE="Europe/Oslo" or TIMEZONE="Europe/Oslo"
336 ++ if (ianaId.isEmpty()) {
337 ++ QFile tzif(QStringLiteral("/etc/sysconfig/clock"));
338 ++ if (tzif.open(QIODevice::ReadOnly)) {
339 ++ while (ianaId.isEmpty() && !tzif.atEnd()) {
340 ++ const QByteArray line(tzif.readLine().trimmed());
341 ++ if (line.startsWith("ZONE="))
342 ++ ianaId = line.mid(6, line.length() - 7);
343 ++ else if (line.startsWith("TIMEZONE="))
344 ++ ianaId = line.mid(10, line.length() - 11);
345 ++ }
346 ++ }
347 ++ }
348 ++
349 + // Some systems (e.g. uClibc) have a default value for $TZ in /etc/TZ:
350 + if (ianaId.isEmpty()) {
351 + QFile zone(QStringLiteral("/etc/TZ"));
352 +--
353 +2.28.0
354 +
355
356 diff --git a/dev-qt/qtcore/qtcore-5.15.2.9999.ebuild b/dev-qt/qtcore/qtcore-5.15.2.9999.ebuild
357 index f5dae178..23956275 100644
358 --- a/dev-qt/qtcore/qtcore-5.15.2.9999.ebuild
359 +++ b/dev-qt/qtcore/qtcore-5.15.2.9999.ebuild
360 @@ -42,7 +42,10 @@ QT5_GENTOO_PRIVATE_CONFIG=(
361 !:xml
362 )
363
364 -PATCHES=( "${FILESDIR}/${PN}-5.14.1-cmake-macro-backward-compat.patch" ) # bug 703306
365 +PATCHES=(
366 + "${FILESDIR}"/${PN}-5.14.1-cmake-macro-backward-compat.patch # bug 703306
367 + "${FILESDIR}"/${PN}-5.15.1-timezone-{1,2}.patch # bug 737914
368 +)
369
370 pkg_pretend() {
371 use kernel_linux || return