On Mon, Jun 29, 2020 at 6:35 PM Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx> wrote: > > 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 were to pass a pointer for a data struct "were" -> "was" ? > 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> This patch does not cause segmentation fault any more. Thanks. > --- > 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 85782da3e464..49f0688fceb8 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 > -- Best Regards Masahiro Yamada