diff options
author | Robert Griebl <robert.griebl@qt.io> | 2023-12-15 10:56:55 +0100 |
---|---|---|
committer | Robert Griebl <robert.griebl@qt.io> | 2023-12-15 14:21:26 +0100 |
commit | f6daf2dd3b5e77e6f4d489441dd9cfadcc738d85 (patch) | |
tree | e3183a7bdf3154c781a5026dca06c044b58c75e4 | |
parent | f42443655b2852641ceee5863b05d53f1a87772d (diff) |
Get rid of the UTF-8 locale check for libarchive
Modern libarchive 3 versions are able to deal with UTF-8 encodings
explicitly, so we don't have to rely on the locale setting of the
whole process for libarchive to pick up the right encoding implicitly.
Change-Id: I002deb582a9267d11361520b1d514f4b43ee2a5e
Pick-to: 6.7
Reviewed-by: Dominik Holland <dominik.holland@qt.io>
-rw-r--r-- | src/main-lib/main.cpp | 10 | ||||
-rw-r--r-- | src/package-lib/packagecreator.cpp | 18 | ||||
-rw-r--r-- | src/package-lib/packageextractor.cpp | 2 | ||||
-rw-r--r-- | src/package-lib/packageutilities.cpp | 87 | ||||
-rw-r--r-- | src/package-lib/packageutilities.h | 3 | ||||
-rw-r--r-- | src/tools/package-server/package-server.cpp | 7 | ||||
-rw-r--r-- | src/tools/packager/packager.cpp | 8 | ||||
-rw-r--r-- | tests/auto/applicationinstaller/tst_applicationinstaller.cpp | 3 | ||||
-rw-r--r-- | tests/auto/packagecreator/tst_packagecreator.cpp | 3 | ||||
-rw-r--r-- | tests/auto/packageextractor/tst_packageextractor.cpp | 3 |
10 files changed, 9 insertions, 135 deletions
diff --git a/src/main-lib/main.cpp b/src/main-lib/main.cpp index 2435294b..4b65eee8 100644 --- a/src/main-lib/main.cpp +++ b/src/main-lib/main.cpp @@ -197,10 +197,6 @@ int &Main::preConstructor(int &argc, char **argv, InitFlags initFlags) Sudo::forkServer(Sudo::DropPrivilegesPermanently); StartupTimer::instance()->checkpoint("after sudo server fork"); } -#if QT_CONFIG(am_installer) - // try to set a reasonable locale - we later verify with checkCorrectLocale() if we succeeded - PackageUtilities::ensureCorrectLocale(); -#endif return argc; } @@ -606,12 +602,6 @@ void Main::setupQuickLauncher(const QHash<std::pair<QString, QString>, int> &run void Main::setupInstaller(bool allowUnsigned, const QStringList &caCertificatePaths) Q_DECL_NOEXCEPT_EXPR(false) { #if QT_CONFIG(am_installer) - if (Q_UNLIKELY(!PackageUtilities::checkCorrectLocale())) { - // we should really throw here, but so many embedded systems are badly set up - qCWarning(LogDeployment) << "The appman installer needs a UTF-8 locale to work correctly: " - "even automatically switching to C.UTF-8 or en_US.UTF-8 failed."; - } - // make sure the installation and document dirs are valid Q_ASSERT(!m_installationDir.isEmpty()); const auto instPath = QDir(m_installationDir).canonicalPath(); diff --git a/src/package-lib/packagecreator.cpp b/src/package-lib/packagecreator.cpp index 2125b131..d42a6103 100644 --- a/src/package-lib/packagecreator.cpp +++ b/src/package-lib/packagecreator.cpp @@ -36,20 +36,6 @@ QT_BEGIN_NAMESPACE_AM -/*! \internal - This is a workaround for the stupid filename encoding handling in libarchive: - the 'hdrcharset' option is not taken into consideration at all, plus the Windows - version simply defaults to hard-coded (non-UTF8) encoding. - This trick gets us consistent behavior on all platforms. -*/ -static void fixed_archive_entry_set_pathname(archive_entry *entry, const QString &pathname) -{ - wchar_t *wchars = new wchar_t[size_t(pathname.length()) + 1]; - wchars[pathname.toWCharArray(wchars)] = 0; - archive_entry_copy_pathname_w(entry, wchars); - delete[] wchars; -} - PackageCreator::PackageCreator(const QDir &sourceDir, QIODevice *output, const InstallationReport &report, QObject *parent) : QObject(parent) @@ -247,7 +233,7 @@ bool PackageCreatorPrivate::create() if (!entry) throw Exception(Error::Archive, "[libarchive] could not create a new archive_entry object"); - fixed_archive_entry_set_pathname(entry, file); // please note: this is a special function (see top of file) + archive_entry_set_pathname_utf8(entry, file.toUtf8().constData()); archive_entry_set_size(entry, static_cast<__LA_INT64_T>(fi.size())); archive_entry_set_mode(entry, mode); @@ -361,7 +347,7 @@ bool PackageCreatorPrivate::addVirtualFile(struct archive *ar, const QString &fi struct archive_entry *entry = archive_entry_new(); if (entry) { - fixed_archive_entry_set_pathname(entry, file); + archive_entry_set_pathname_utf8(entry, file.toUtf8().constData()); archive_entry_set_mode(entry, S_IFREG | S_IREAD); archive_entry_set_size(entry, data.size()); archive_entry_set_mtime(entry, time(nullptr), 0); diff --git a/src/package-lib/packageextractor.cpp b/src/package-lib/packageextractor.cpp index 8d5e2e86..0dd66b7a 100644 --- a/src/package-lib/packageextractor.cpp +++ b/src/package-lib/packageextractor.cpp @@ -240,7 +240,7 @@ void PackageExtractorPrivate::extract() __LA_MODE_T entryMode = archive_entry_mode(entry); PackageEntryType packageEntryType; - QString entryPath = QString::fromWCharArray(archive_entry_pathname_w(entry)) + QString entryPath = QString::fromUtf8(archive_entry_pathname_utf8(entry)) .normalized(QString::NormalizationForm_C); switch (entryMode & S_IFMT) { diff --git a/src/package-lib/packageutilities.cpp b/src/package-lib/packageutilities.cpp index bfbc1e1c..4a362ea3 100644 --- a/src/package-lib/packageutilities.cpp +++ b/src/package-lib/packageutilities.cpp @@ -17,93 +17,12 @@ #include "global.h" #include "logging.h" -#include <clocale> - QT_BEGIN_NAMESPACE_AM -bool PackageUtilities::ensureCorrectLocale() -{ - static bool once = false; - if (once) - return true; - once = true; - - // We need to make sure we are running in a Unicode locale, since we are - // running into problems when unpacking packages with libarchive that - // contain non-ASCII characters. - // This has to be done *before* the QApplication constructor to avoid - // the initialization of the text codecs. - -#if defined(Q_OS_WIN) - // Windows is UTF16 - return true; -#else - - // check if umlaut-a converts correctly - auto checkUtf = []() -> bool { - const wchar_t umlaut_w[2] = { 0x00e4, 0x0000 }; - char umlaut_mb[2]; - size_t umlaut_mb_len = wcstombs(umlaut_mb, umlaut_w, sizeof(umlaut_mb)); - - return (umlaut_mb_len == 2 && umlaut_mb[0] == '\xc3' && umlaut_mb[1] == '\xa4'); - }; - - // init locales from env variables - setlocale(LC_ALL, ""); - - // check if this is enough to have an UTF-8 locale - if (checkUtf()) - return true; - - qCWarning(LogDeployment) << "The current locale is not UTF-8 capable. Trying to find a capable one now, " - "but this is time consuming and should be avoided"; - - // LC_ALL trumps all the rest, so if this is not specifying an UTF-8 locale, we need to unset it - QByteArray lc_all = qgetenv("LC_ALL"); - if (!lc_all.isEmpty() && !(lc_all.endsWith(".UTF-8") || lc_all.endsWith(".UTF_8"))) { - unsetenv("LC_ALL"); - setlocale(LC_ALL, ""); - } - - // check again - if (checkUtf()) - return true; - - // now the time-consuming part: trying to switch to a well-known UTF-8 locale - const char *locales[] = { -#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) - "UTF-8" -#else - "C.UTF-8", "en_US.UTF-8" -#endif - }; - for (const char *loc : locales) { - if (const char *old = setlocale(LC_CTYPE, loc)) { - if (checkUtf()) { - if (setenv("LC_CTYPE", loc, 1) == 0) - return true; - } - setlocale(LC_CTYPE, old); - } - } - - return false; -#endif -} - -bool PackageUtilities::checkCorrectLocale() -{ - // see ensureCorrectLocale() above. Call this after the QApplication - // constructor as a sanity check. -#if defined(Q_OS_WIN) - return true; -#else - // check if umlaut-a converts correctly - return QString::fromUtf8("\xc3\xa4").toLocal8Bit() == "\xc3\xa4"; -#endif -} - +//TODO: remove in 6.9 +bool PackageUtilities::ensureCorrectLocale() { return true; } +bool PackageUtilities::checkCorrectLocale() { return true; } ArchiveException::ArchiveException(struct ::archive *ar, const char *errorString) : Exception(Error::Archive, qSL("[libarchive] ") + qL1S(errorString) + qSL(": ") + QString::fromLocal8Bit(::archive_error_string(ar))) diff --git a/src/package-lib/packageutilities.h b/src/package-lib/packageutilities.h index ae3395cf..0b7f6ab6 100644 --- a/src/package-lib/packageutilities.h +++ b/src/package-lib/packageutilities.h @@ -11,7 +11,10 @@ QT_BEGIN_NAMESPACE_AM namespace PackageUtilities { +QT_DEPRECATED_X("Not needed anymore starting with 6.7 - will be removed in 6.9") bool ensureCorrectLocale(); + +QT_DEPRECATED_X("Not needed anymore starting with 6.7 - will be removed in 6.9") bool checkCorrectLocale(); } diff --git a/src/tools/package-server/package-server.cpp b/src/tools/package-server/package-server.cpp index 9ef3695a..f43ee2a5 100644 --- a/src/tools/package-server/package-server.cpp +++ b/src/tools/package-server/package-server.cpp @@ -28,8 +28,6 @@ int main(int argc, char **argv) // enable OpenSSL3 to load old certificates Cryptography::enableOpenSsl3LegacyProvider(); - PackageUtilities::ensureCorrectLocale(); - QCoreApplication::setApplicationName(u"Qt ApplicationManager Package Server"_s); QCoreApplication::setOrganizationName(u"QtProject"_s); QCoreApplication::setOrganizationDomain(u"qt-project.org"_s); @@ -38,11 +36,6 @@ int main(int argc, char **argv) QCoreApplication a(argc, argv); try { - if (!PackageUtilities::checkCorrectLocale()) { - throw Exception("the package-server needs a UTF-8 locale to work correctly:\n" - " even automatically switching to C.UTF-8 or en_US.UTF-8 failed."); - } - auto cfg = std::make_unique<PSConfiguration>(); cfg->parse(a.arguments()); diff --git a/src/tools/packager/packager.cpp b/src/tools/packager/packager.cpp index ffda028f..80a3b165 100644 --- a/src/tools/packager/packager.cpp +++ b/src/tools/packager/packager.cpp @@ -68,8 +68,6 @@ int main(int argc, char *argv[]) // enable OpenSSL3 to load old certificates Cryptography::enableOpenSsl3LegacyProvider(); - PackageUtilities::ensureCorrectLocale(); - QCoreApplication::setApplicationName(qSL("Qt ApplicationManager Packager")); QCoreApplication::setOrganizationName(qSL("QtProject")); QCoreApplication::setOrganizationDomain(qSL("qt-project.org")); @@ -77,12 +75,6 @@ int main(int argc, char *argv[]) QCoreApplication a(argc, argv); - if (!PackageUtilities::checkCorrectLocale()) { - fprintf(stderr, "ERROR: the packager needs a UTF-8 locale to work correctly:\n" - " even automatically switching to C.UTF-8 or en_US.UTF-8 failed.\n"); - exit(2); - } - QByteArray desc = "\n\nAvailable commands are:\n"; uint longestName = 0; for (uint i = 0; i < sizeof(commandTable) / sizeof(commandTable[0]); ++i) diff --git a/tests/auto/applicationinstaller/tst_applicationinstaller.cpp b/tests/auto/applicationinstaller/tst_applicationinstaller.cpp index c6e4b6ec..0dd8df74 100644 --- a/tests/auto/applicationinstaller/tst_applicationinstaller.cpp +++ b/tests/auto/applicationinstaller/tst_applicationinstaller.cpp @@ -209,7 +209,6 @@ void tst_PackageManager::initTestCase() spyTimeout *= timeoutFactor(); - QVERIFY(PackageUtilities::checkCorrectLocale()); QVERIFY2(startedSudoServer, qPrintable(sudoServerError)); m_sudo = SudoClient::instance(); QVERIFY(m_sudo); @@ -786,8 +785,6 @@ static tst_PackageManager *tstPackageManager = nullptr; int main(int argc, char **argv) { - PackageUtilities::ensureCorrectLocale(); - try { Sudo::forkServer(Sudo::DropPrivilegesPermanently); startedSudoServer = true; diff --git a/tests/auto/packagecreator/tst_packagecreator.cpp b/tests/auto/packagecreator/tst_packagecreator.cpp index 3218159b..bc748ee0 100644 --- a/tests/auto/packagecreator/tst_packagecreator.cpp +++ b/tests/auto/packagecreator/tst_packagecreator.cpp @@ -56,8 +56,6 @@ void tst_PackageCreator::initTestCase() m_isCygwin = tar.readAllStandardOutput().contains("Cygwin"); - QVERIFY(PackageUtilities::checkCorrectLocale()); - if (!QDir(qL1S(AM_TESTDATA_DIR "/packages")).exists()) QSKIP("No test packages available in the data/ directory"); } @@ -152,7 +150,6 @@ QString tst_PackageCreator::escapeFilename(const QString &name) int main(int argc, char *argv[]) { - PackageUtilities::ensureCorrectLocale(); QCoreApplication app(argc, argv); app.setAttribute(Qt::AA_Use96Dpi, true); tst_PackageCreator tc; diff --git a/tests/auto/packageextractor/tst_packageextractor.cpp b/tests/auto/packageextractor/tst_packageextractor.cpp index 877966ef..43d1fd75 100644 --- a/tests/auto/packageextractor/tst_packageextractor.cpp +++ b/tests/auto/packageextractor/tst_packageextractor.cpp @@ -58,8 +58,6 @@ void tst_PackageExtractor::initTestCase() { if (!QDir(qL1S(AM_TESTDATA_DIR "/packages")).exists()) QSKIP("No test packages available in the data/ directory"); - - QVERIFY(PackageUtilities::checkCorrectLocale()); } void tst_PackageExtractor::init() @@ -279,7 +277,6 @@ void tst_PackageExtractor::extractFromFifo() int main(int argc, char *argv[]) { - PackageUtilities::ensureCorrectLocale(); QCoreApplication app(argc, argv); app.setAttribute(Qt::AA_Use96Dpi, true); tst_PackageExtractor tc; |