mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	kconfig: qconf: make debug links work again
The Qt5 conversion broke support for debug info links.
Restore the behaviour added by changeset
ab45d190fd ("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@coco.lan/
Reported-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									c699eaaba9
								
							
						
					
					
						commit
						c4f7398bee
					
				
					 2 changed files with 71 additions and 5 deletions
				
			
		| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
#include <QAction>
 | 
					#include <QAction>
 | 
				
			||||||
#include <QApplication>
 | 
					#include <QApplication>
 | 
				
			||||||
#include <QCloseEvent>
 | 
					#include <QCloseEvent>
 | 
				
			||||||
 | 
					#include <QDebug>
 | 
				
			||||||
#include <QDesktopWidget>
 | 
					#include <QDesktopWidget>
 | 
				
			||||||
#include <QFileDialog>
 | 
					#include <QFileDialog>
 | 
				
			||||||
#include <QLabel>
 | 
					#include <QLabel>
 | 
				
			||||||
| 
						 | 
					@ -1012,7 +1013,7 @@ ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
 | 
				
			||||||
	: Parent(parent), sym(0), _menu(0)
 | 
						: Parent(parent), sym(0), _menu(0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setObjectName(name);
 | 
						setObjectName(name);
 | 
				
			||||||
 | 
						setOpenLinks(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!objectName().isEmpty()) {
 | 
						if (!objectName().isEmpty()) {
 | 
				
			||||||
		configSettings->beginGroup(objectName());
 | 
							configSettings->beginGroup(objectName());
 | 
				
			||||||
| 
						 | 
					@ -1085,7 +1086,7 @@ void ConfigInfoView::menuInfo(void)
 | 
				
			||||||
			if (sym->name) {
 | 
								if (sym->name) {
 | 
				
			||||||
				head += " (";
 | 
									head += " (";
 | 
				
			||||||
				if (showDebug())
 | 
									if (showDebug())
 | 
				
			||||||
					head += QString().sprintf("<a href=\"s%p\">", sym);
 | 
										head += QString().sprintf("<a href=\"s%s\">", sym->name);
 | 
				
			||||||
				head += print_filter(sym->name);
 | 
									head += print_filter(sym->name);
 | 
				
			||||||
				if (showDebug())
 | 
									if (showDebug())
 | 
				
			||||||
					head += "</a>";
 | 
										head += "</a>";
 | 
				
			||||||
| 
						 | 
					@ -1094,7 +1095,7 @@ void ConfigInfoView::menuInfo(void)
 | 
				
			||||||
		} else if (sym->name) {
 | 
							} else if (sym->name) {
 | 
				
			||||||
			head += "<big><b>";
 | 
								head += "<big><b>";
 | 
				
			||||||
			if (showDebug())
 | 
								if (showDebug())
 | 
				
			||||||
				head += QString().sprintf("<a href=\"s%p\">", sym);
 | 
									head += QString().sprintf("<a href=\"s%s\">", sym->name);
 | 
				
			||||||
			head += print_filter(sym->name);
 | 
								head += print_filter(sym->name);
 | 
				
			||||||
			if (showDebug())
 | 
								if (showDebug())
 | 
				
			||||||
				head += "</a>";
 | 
									head += "</a>";
 | 
				
			||||||
| 
						 | 
					@ -1145,7 +1146,7 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
 | 
				
			||||||
		switch (prop->type) {
 | 
							switch (prop->type) {
 | 
				
			||||||
		case P_PROMPT:
 | 
							case P_PROMPT:
 | 
				
			||||||
		case P_MENU:
 | 
							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 += print_filter(prop->text);
 | 
				
			||||||
			debug += "</a><br>";
 | 
								debug += "</a><br>";
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -1217,13 +1218,74 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
 | 
				
			||||||
	QString str2 = print_filter(str);
 | 
						QString str2 = print_filter(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
 | 
						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 += str2;
 | 
				
			||||||
		*text += "</a>";
 | 
							*text += "</a>";
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		*text += str2;
 | 
							*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* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QMenu* popup = Parent::createStandardContextMenu(pos);
 | 
						QMenu* popup = Parent::createStandardContextMenu(pos);
 | 
				
			||||||
| 
						 | 
					@ -1497,6 +1559,9 @@ ConfigMainWindow::ConfigMainWindow(void)
 | 
				
			||||||
	helpMenu->addAction(showIntroAction);
 | 
						helpMenu->addAction(showIntroAction);
 | 
				
			||||||
	helpMenu->addAction(showAboutAction);
 | 
						helpMenu->addAction(showAboutAction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						connect (helpText, SIGNAL (anchorClicked (const QUrl &)),
 | 
				
			||||||
 | 
							 helpText, SLOT (clicked (const QUrl &)) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	connect(configList, SIGNAL(menuChanged(struct menu *)),
 | 
						connect(configList, SIGNAL(menuChanged(struct menu *)),
 | 
				
			||||||
		helpText, SLOT(setInfo(struct menu *)));
 | 
							helpText, SLOT(setInfo(struct menu *)));
 | 
				
			||||||
	connect(configList, SIGNAL(menuSelected(struct menu *)),
 | 
						connect(configList, SIGNAL(menuSelected(struct menu *)),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -250,6 +250,7 @@ public slots:
 | 
				
			||||||
	void setInfo(struct menu *menu);
 | 
						void setInfo(struct menu *menu);
 | 
				
			||||||
	void saveSettings(void);
 | 
						void saveSettings(void);
 | 
				
			||||||
	void setShowDebug(bool);
 | 
						void setShowDebug(bool);
 | 
				
			||||||
 | 
						void clicked (const QUrl &url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
	void showDebugChanged(bool);
 | 
						void showDebugChanged(bool);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue