From d8d498f831101d7bccebc9b9aa460ef04d55ef23 Mon Sep 17 00:00:00 2001 From: Vasilito Date: Thu, 7 May 2026 07:52:47 +0100 Subject: [PATCH] fix: harden KF6 KIO build surface --- local/recipes/kde/kf6-kio/recipe.toml | 116 ++++++++++++++++-- .../recipes/kde/kf6-kio/source/CMakeLists.txt | 2 +- .../kde/kf6-kio/source/src/CMakeLists.txt | 8 -- .../kf6-kio/source/src/core/CMakeLists.txt | 1 + .../kde/kf6-kio/source/src/gui/CMakeLists.txt | 1 + .../kde/kf6-kio/source/src/gui/previewjob.cpp | 2 +- .../kf6-kio/source/src/widgets/CMakeLists.txt | 6 - .../source/src/widgets/jobuidelegate.cpp | 1 - .../widgets/widgetsaskuseractionhandler.cpp | 56 +++------ 9 files changed, 132 insertions(+), 61 deletions(-) diff --git a/local/recipes/kde/kf6-kio/recipe.toml b/local/recipes/kde/kf6-kio/recipe.toml index 83f9302c0..c7f5de2bc 100644 --- a/local/recipes/kde/kf6-kio/recipe.toml +++ b/local/recipes/kde/kf6-kio/recipe.toml @@ -1,11 +1,12 @@ -# KIO — reduced real KIOCore build for Red Bear OS. +# KIO — real KIOCore/KIOGui/KIOWidgets build for Red Bear OS. # # Honesty boundary: -# - KIOCORE_ONLY=ON and BUILD_WITH_QML=OFF stay intentional. +# - BUILD_WITH_QML=OFF stays intentional. # - USE_DBUS=ON is now enabled to expose more real KIOCore functionality. -# - QtNetwork is still unavailable on Redox, so KIOCore uses source-local +# - The wider build now imports Qt6Network from the target sysroot for +# KIOWidgets/KIOGui/workers, while KIOCore still keeps its source-local # Redox compatibility headers for the small QHostInfo/QHostAddress surface it needs. -# - This recipe no longer forges QtNetwork headers into the shared sysroot. +# - This recipe does not forge QtNetwork headers into the shared sysroot. [source] tar = "https://invent.kde.org/frameworks/kio/-/archive/v6.10.0/kio-v6.10.0.tar.gz" @@ -51,14 +52,114 @@ for qtdir in plugins mkspecs metatypes modules; do done # workerinterface.cpp calls KIO::HostInfo::lookupHost which needs -# hostinfo.cpp — but hostinfo.cpp isn't in the cmake source list for -# KIOCORE_ONLY. Replace the call with a direct QHostInfo::fromName. +# hostinfo.cpp — but hostinfo.cpp still isn't in the cmake source list. +# Replace the call with a direct QHostInfo::fromName. sed -i 's/const QHostInfo info = HostInfo::lookupHost(hostName, 1500);/const QHostInfo info = QHostInfo::fromName(hostName);/' \ "${COOKBOOK_SOURCE}/src/core/workerinterface.cpp" 2>/dev/null || true # Also remove the hostinfo.h include — no longer needed sed -i '/#include "hostinfo.h"/d' \ "${COOKBOOK_SOURCE}/src/core/workerinterface.cpp" 2>/dev/null || true +# Full KIO builds link Qt6::Network from multiple subdirectories, but the +# top-level Qt6 package import omits the Network component by default. +sed -i 's/find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets Concurrent Xml)/find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets Concurrent Xml Network)/' \ + "${COOKBOOK_SOURCE}/CMakeLists.txt" 2>/dev/null || true + +# KIOGui still reaches KIO::HostInfo; make sure the existing hostinfo.cpp +# implementation is actually built into KIOCore. +if ! grep -q 'hostinfo.cpp' "${COOKBOOK_SOURCE}/src/core/CMakeLists.txt" 2>/dev/null; then + sed -i '/workerinterface.cpp/a\\ hostinfo.cpp' \ + "${COOKBOOK_SOURCE}/src/core/CMakeLists.txt" 2>/dev/null || true +fi + +# Redox only needs the core/gui/widgets libraries here; skip worker/daemon and +# extra runtime/plugin subdirectories that still depend on unsupported Qt SSL, +# SysV IPC, and broader runtime surfaces. +sed -i '/add_subdirectory(kioworkers)/d; /add_subdirectory(schemehandlers)/d; /add_subdirectory(kiod)/d; /add_subdirectory(kssld)/d; /add_subdirectory(kpasswdserver)/d; /add_subdirectory(kioexec)/d; /add_subdirectory(filewidgets)/d; /add_subdirectory(urifilters)/d' \ + "${COOKBOOK_SOURCE}/src/CMakeLists.txt" 2>/dev/null || true + +# KIOGui uses QHostInfo in full builds, so import QtNetwork on the GUI target. +if ! grep -q 'Qt6::Network' "${COOKBOOK_SOURCE}/src/gui/CMakeLists.txt" 2>/dev/null; then + sed -i '/Qt6::Gui/a\\ Qt6::Network' \ + "${COOKBOOK_SOURCE}/src/gui/CMakeLists.txt" 2>/dev/null || true +fi + +# PreviewJob's SysV shared-memory fast path is unavailable on Redox. +sed -i '17c\\#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && !defined(Q_OS_HAIKU) && !defined(Q_OS_REDOX)' \ + "${COOKBOOK_SOURCE}/src/gui/previewjob.cpp" 2>/dev/null || true + +python - <<'PY' +import os +from pathlib import Path + +root = Path(os.environ["COOKBOOK_SOURCE"]) + +widgets_cmake = root / "src/widgets/CMakeLists.txt" +text = widgets_cmake.read_text() +for needle in ( + " ksslcertificatebox.cpp\\n", + " ksslinfodialog.cpp\\n", + " sslui.cpp\\n", + " kdynamicjobtracker.cpp\\n", + " KSslCertificateBox\\n", + " KSslInfoDialog\\n", +): + text = text.replace(needle, "") +widgets_cmake.write_text(text) + +jobuidelegate = root / "src/widgets/jobuidelegate.cpp" +text = jobuidelegate.read_text() +text = text.replace("#include \\n", "") +jobuidelegate.write_text(text) + +askuser = root / "src/widgets/widgetsaskuseractionhandler.cpp" +text = askuser.read_text() +text = text.replace("#include \\n", "") +start_marker = "void KIO::WidgetsAskUserActionHandler::showSslDetails(const QVariantMap &sslErrorData, QWidget *parentWidget)\\n" +end_marker = '\\n#include "moc_widgetsaskuseractionhandler.cpp"\\n' +new = r'''void KIO::WidgetsAskUserActionHandler::showSslDetails(const QVariantMap &sslErrorData, QWidget *parentWidget) +{ + QString details = i18n("Detailed SSL certificate inspection is unavailable on Redox with the current QtNetwork SSL surface."); + const QString hostname = sslErrorData[QLatin1String("hostname")].toString(); + const QString protocol = sslErrorData[QLatin1String("protocol")].toString(); + const QString cipher = sslErrorData[QLatin1String("cipher")].toString(); + const QString sslError = sslErrorData[QLatin1String("sslError")].toString(); + + if (!hostname.isEmpty()) { + details += QStringLiteral("\\n\\n") + i18n("Host: %1", hostname); + } + if (!protocol.isEmpty()) { + details += QStringLiteral("\\n") + i18n("Protocol: %1", protocol); + } + if (!cipher.isEmpty()) { + details += QStringLiteral("\\n") + i18n("Cipher: %1", cipher); + } + if (!sslError.isEmpty()) { + details += QStringLiteral("\\n\\n") + sslError; + } + + QMetaObject::invokeMethod(qGuiApp, [=, this] { + auto *dialog = new KMessageDialog(KMessageDialog::Information, details, parentWidget); + + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setCaption(i18n("SSL")); + dialog->setButtons(KStandardGuiItem::ok()); + + QObject::connect(dialog, &QDialog::finished, this, [this, sslErrorData, parentWidget](const int) { + askIgnoreSslErrors(sslErrorData, parentWidget); + }); + + dialog->show(); + }); +} +''' +start = text.find(start_marker) +end = text.find(end_marker) +if start != -1 and end != -1 and start < end: + text = text[:start] + new + text[end:] +askuser.write_text(text) +PY + rm -f CMakeCache.txt rm -rf CMakeFiles @@ -70,11 +171,12 @@ cmake "${COOKBOOK_SOURCE}" \ -DCMAKE_PREFIX_PATH="${COOKBOOK_SYSROOT}" \ -DBUILD_TESTING=OFF \ -DBUILD_QCH=OFF \ + -DBUILD_DESIGNERPLUGIN=OFF \ -DQT_SKIP_AUTO_PLUGIN_INCLUSION=ON \ - -DKIOCORE_ONLY=ON \ -DBUILD_WITH_QML=OFF \ -DUSE_DBUS=ON \ -DWITH_X11=OFF \ + -DWITH_WAYLAND=OFF \ -Wno-dev cmake --build . -j${COOKBOOK_MAKE_JOBS} diff --git a/local/recipes/kde/kf6-kio/source/CMakeLists.txt b/local/recipes/kde/kf6-kio/source/CMakeLists.txt index c20d73563..d8421128c 100644 --- a/local/recipes/kde/kf6-kio/source/CMakeLists.txt +++ b/local/recipes/kde/kf6-kio/source/CMakeLists.txt @@ -104,7 +104,7 @@ set_package_properties(KF6DocTools PROPERTIES DESCRIPTION "Provides tools to gen ) set(REQUIRED_QT_VERSION 6.6.0) -find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets Concurrent Xml) +find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets Concurrent Xml Network) # shall we use DBus? # enabled per default on Linux & BSD systems diff --git a/local/recipes/kde/kf6-kio/source/src/CMakeLists.txt b/local/recipes/kde/kf6-kio/source/src/CMakeLists.txt index a4fc6e2d5..c9d783fe2 100644 --- a/local/recipes/kde/kf6-kio/source/src/CMakeLists.txt +++ b/local/recipes/kde/kf6-kio/source/src/CMakeLists.txt @@ -3,13 +3,9 @@ add_subdirectory(core) # KIOCore-only executables if (NOT KIOCORE_ONLY) if (NOT ANDROID) - add_subdirectory(kioworkers) - add_subdirectory(schemehandlers) endif() if (HAVE_QTDBUS) - add_subdirectory(kiod) - add_subdirectory(kssld) endif() add_subdirectory(kioworker) endif() @@ -19,13 +15,9 @@ add_subdirectory(gui) add_subdirectory(widgets) if (HAVE_QTDBUS) - add_subdirectory(kpasswdserver) - add_subdirectory(kioexec) endif() if (NOT ANDROID) - add_subdirectory(filewidgets) - add_subdirectory(urifilters) endif() set(NON_KIOCORE_LINK_QCHS diff --git a/local/recipes/kde/kf6-kio/source/src/core/CMakeLists.txt b/local/recipes/kde/kf6-kio/source/src/core/CMakeLists.txt index c7ff7df0c..7ca24a976 100644 --- a/local/recipes/kde/kf6-kio/source/src/core/CMakeLists.txt +++ b/local/recipes/kde/kf6-kio/source/src/core/CMakeLists.txt @@ -78,6 +78,7 @@ target_sources(KF6KIOCore PRIVATE batchrenamejob.cpp worker.cpp workerinterface.cpp + hostinfo.cpp workerconfig.cpp workerfactory.cpp workerthread.cpp diff --git a/local/recipes/kde/kf6-kio/source/src/gui/CMakeLists.txt b/local/recipes/kde/kf6-kio/source/src/gui/CMakeLists.txt index 15362a906..76d6f806a 100644 --- a/local/recipes/kde/kf6-kio/source/src/gui/CMakeLists.txt +++ b/local/recipes/kde/kf6-kio/source/src/gui/CMakeLists.txt @@ -89,6 +89,7 @@ target_link_libraries(KF6KIOGui KF6::ConfigCore KF6::Service Qt6::Gui + Qt6::Network PRIVATE KF6::Solid KF6::I18n diff --git a/local/recipes/kde/kf6-kio/source/src/gui/previewjob.cpp b/local/recipes/kde/kf6-kio/source/src/gui/previewjob.cpp index 23ef5554b..f5a539bb5 100644 --- a/local/recipes/kde/kf6-kio/source/src/gui/previewjob.cpp +++ b/local/recipes/kde/kf6-kio/source/src/gui/previewjob.cpp @@ -14,7 +14,7 @@ #include "standardthumbnailjob_p.h" #include "statjob.h" -#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && !defined(Q_OS_HAIKU) +#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && !defined(Q_OS_HAIKU) && !defined(Q_OS_REDOX) #define WITH_SHM 1 #else #define WITH_SHM 0 diff --git a/local/recipes/kde/kf6-kio/source/src/widgets/CMakeLists.txt b/local/recipes/kde/kf6-kio/source/src/widgets/CMakeLists.txt index bc91f9ea9..65ac1edf1 100644 --- a/local/recipes/kde/kf6-kio/source/src/widgets/CMakeLists.txt +++ b/local/recipes/kde/kf6-kio/source/src/widgets/CMakeLists.txt @@ -35,8 +35,6 @@ target_sources(KF6KIOWidgets PRIVATE kshellcompletion.cpp kurlcompletion.cpp renamedialog.cpp - ksslcertificatebox.cpp - ksslinfodialog.cpp skipdialog.cpp jobuidelegate.cpp kdirlister.cpp @@ -60,12 +58,10 @@ target_sources(KF6KIOWidgets PRIVATE kpropertiesdialog.cpp kpropertiesdialogplugin.cpp kpropertiesdialogbuiltin_p.cpp - sslui.cpp ) if (HAVE_QTDBUS) target_sources(KF6KIOWidgets PRIVATE - kdynamicjobtracker.cpp ${kiowidgets_dbus_SRCS} ) endif() @@ -151,8 +147,6 @@ ecm_generate_headers(KIOWidgets_HEADERS KBuildSycocaProgressDialog KFile KUrlRequester - KSslCertificateBox - KSslInfoDialog KDirLister KDirModel KShellCompletion diff --git a/local/recipes/kde/kf6-kio/source/src/widgets/jobuidelegate.cpp b/local/recipes/kde/kf6-kio/source/src/widgets/jobuidelegate.cpp index 3c66968a5..1dab54399 100644 --- a/local/recipes/kde/kf6-kio/source/src/widgets/jobuidelegate.cpp +++ b/local/recipes/kde/kf6-kio/source/src/widgets/jobuidelegate.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #ifdef WITH_QTDBUS #include diff --git a/local/recipes/kde/kf6-kio/source/src/widgets/widgetsaskuseractionhandler.cpp b/local/recipes/kde/kf6-kio/source/src/widgets/widgetsaskuseractionhandler.cpp index b67587ef7..d1749fa14 100644 --- a/local/recipes/kde/kf6-kio/source/src/widgets/widgetsaskuseractionhandler.cpp +++ b/local/recipes/kde/kf6-kio/source/src/widgets/widgetsaskuseractionhandler.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -507,51 +506,34 @@ void KIO::WidgetsAskUserActionHandler::askIgnoreSslErrors(const QVariantMap &ssl void KIO::WidgetsAskUserActionHandler::showSslDetails(const QVariantMap &sslErrorData, QWidget *parentWidget) { - const QStringList sslList = sslErrorData[QLatin1String("peerCertChain")].toStringList(); + QString details = i18n("Detailed SSL certificate inspection is unavailable on Redox with the current QtNetwork SSL surface."); + const QString hostname = sslErrorData[QLatin1String("hostname")].toString(); + const QString protocol = sslErrorData[QLatin1String("protocol")].toString(); + const QString cipher = sslErrorData[QLatin1String("cipher")].toString(); + const QString sslError = sslErrorData[QLatin1String("sslError")].toString(); - QList certChain; - bool decodedOk = true; - for (const QString &str : sslList) { - certChain.append(QSslCertificate(str.toUtf8())); - if (certChain.last().isNull()) { - decodedOk = false; - break; - } + if (!hostname.isEmpty()) { + details += QStringLiteral("\n\n") + i18n("Host: %1", hostname); + } + if (!protocol.isEmpty()) { + details += QStringLiteral("\n") + i18n("Protocol: %1", protocol); + } + if (!cipher.isEmpty()) { + details += QStringLiteral("\n") + i18n("Cipher: %1", cipher); + } + if (!sslError.isEmpty()) { + details += QStringLiteral("\n\n") + sslError; } QMetaObject::invokeMethod(qGuiApp, [=, this] { - if (decodedOk) { // Use KSslInfoDialog - KSslInfoDialog *ksslDlg = new KSslInfoDialog(parentWidget); - ksslDlg->setSslInfo( - certChain, - QString(), - sslErrorData[QLatin1String("hostname")].toString(), - sslErrorData[QLatin1String("protocol")].toString(), - sslErrorData[QLatin1String("cipher")].toString(), - sslErrorData[QLatin1String("usedBits")].toInt(), - sslErrorData[QLatin1String("bits")].toInt(), - KSslInfoDialog::certificateErrorsFromString(sslErrorData[QLatin1String("certificateErrors")].toStringList().join(QLatin1Char('\n')))); - - // KSslInfoDialog deletes itself by setting Qt::WA_DeleteOnClose - - QObject::connect(ksslDlg, &QDialog::finished, this, [this, sslErrorData, parentWidget]() { - // KSslInfoDialog only has one button, QDialogButtonBox::Close - askIgnoreSslErrors(sslErrorData, parentWidget); - }); - - ksslDlg->show(); - return; - } - - // Fallback to a generic message box - auto *dialog = new KMessageDialog(KMessageDialog::Information, i18n("The peer SSL certificate chain appears to be corrupt."), parentWidget); + auto *dialog = new KMessageDialog(KMessageDialog::Information, details, parentWidget); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setCaption(i18n("SSL")); dialog->setButtons(KStandardGuiItem::ok()); - QObject::connect(dialog, &QDialog::finished, this, [this](const int result) { - Q_EMIT askIgnoreSslErrorsResult(result == KMessageDialog::Ok ? 1 : 0); + QObject::connect(dialog, &QDialog::finished, this, [this, sslErrorData, parentWidget](const int) { + askIgnoreSslErrors(sslErrorData, parentWidget); }); dialog->show();