The Qt5 conversion broke support for debug info links. Restore the behaviour added by changeset ab45d190fd4a ("kconfig: create links in info window"). The original approach was to pass a pointer for a data struct via an <a href>. That doesn't sound a good idea, as, if something gets wrong, the app could crash. So, instead, pass the name of the symbol, and validate such symbol at the hyperlink handling logic. Link: https://lore.kernel.org/lkml/20200628125421.12458086@xxxxxxxx/ Reported-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx> --- scripts/kconfig/qconf.cc | 75 +++++++++++++++++++++++++++++++++++++--- scripts/kconfig/qconf.h | 1 + 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 9def59423743..1fddbdfa58b4 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -7,6 +7,7 @@ #include <QAction> #include <QApplication> #include <QCloseEvent> +#include <QDebug> #include <QDesktopWidget> #include <QFileDialog> #include <QLabel> @@ -1012,7 +1013,7 @@ ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) : Parent(parent), sym(0), _menu(0) { setObjectName(name); - + setOpenLinks(false); if (!objectName().isEmpty()) { configSettings->beginGroup(objectName()); @@ -1085,7 +1086,7 @@ void ConfigInfoView::menuInfo(void) if (sym->name) { head += " ("; if (showDebug()) - head += QString().sprintf("<a href=\"s%p\">", sym); + head += QString().sprintf("<a href=\"s%s\">", sym->name); head += print_filter(sym->name); if (showDebug()) head += "</a>"; @@ -1094,7 +1095,7 @@ void ConfigInfoView::menuInfo(void) } else if (sym->name) { head += "<big><b>"; if (showDebug()) - head += QString().sprintf("<a href=\"s%p\">", sym); + head += QString().sprintf("<a href=\"s%s\">", sym->name); head += print_filter(sym->name); if (showDebug()) head += "</a>"; @@ -1145,7 +1146,7 @@ QString ConfigInfoView::debug_info(struct symbol *sym) switch (prop->type) { case P_PROMPT: case P_MENU: - debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu); + debug += QString().sprintf("prompt: <a href=\"m%s\">", sym->name); debug += print_filter(prop->text); debug += "</a><br>"; break; @@ -1217,13 +1218,74 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char QString str2 = print_filter(str); if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) { - *text += QString().sprintf("<a href=\"s%p\">", sym); + *text += QString().sprintf("<a href=\"s%s\">", sym->name); *text += str2; *text += "</a>"; } else *text += str2; } +void ConfigInfoView::clicked(const QUrl &url) +{ + QByteArray str = url.toEncoded(); + const std::size_t count = str.size(); + char *data = new char[count + 1]; + struct symbol **result; + struct menu *m = NULL; + char type; + + if (count < 1) { + qInfo() << "Clicked link is empty"; + delete data; + return; + } + + memcpy(data, str.constData(), count); + data[count] = '\0'; + type = data[0]; + + /* Seek for exact match */ + data[0] = '^'; + strcat(data, "$"); + result = sym_re_search(data); + if (!result) { + qInfo() << "Clicked symbol is invalid:" << data; + delete data; + return; + } + + sym = *result; + if (type == 's') { + symbolInfo(); + emit showDebugChanged(true); + free(result); + delete data; + return; + } + + /* URL is a menu */ + for (struct property *prop = sym->prop; prop; prop = prop->next) { + if (prop->type != P_PROMPT && prop->type != P_MENU) + continue; + m = prop->menu; + break; + } + + if (!m) { + qInfo() << "Clicked menu is invalid:" << data; + free(result); + delete data; + return; + } + + _menu = m; + menuInfo(); + + emit showDebugChanged(true); + free(result); + delete data; +} + QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos) { QMenu* popup = Parent::createStandardContextMenu(pos); @@ -1497,6 +1559,9 @@ ConfigMainWindow::ConfigMainWindow(void) helpMenu->addAction(showIntroAction); helpMenu->addAction(showAboutAction); + connect (helpText, SIGNAL (anchorClicked (const QUrl &)), + helpText, SLOT (clicked (const QUrl &)) ); + connect(configList, SIGNAL(menuChanged(struct menu *)), helpText, SLOT(setInfo(struct menu *))); connect(configList, SIGNAL(menuSelected(struct menu *)), diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index d913a02967ae..a193137f2314 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -250,6 +250,7 @@ public slots: void setInfo(struct menu *menu); void saveSettings(void); void setShowDebug(bool); + void clicked (const QUrl &url); signals: void showDebugChanged(bool); -- 2.26.2