From 8c627883b815ea9bfeb65dafa3a1d9517c17ad5a Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Sun, 8 Oct 2023 09:26:19 +0200 Subject: [PATCH 1/4] Sanitize bookmarks saving with percent-encoded strings, fixes #1117 --- src/qtgui/bookmarks.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/qtgui/bookmarks.cpp b/src/qtgui/bookmarks.cpp index d4593e5ac..8dd179a0a 100644 --- a/src/qtgui/bookmarks.cpp +++ b/src/qtgui/bookmarks.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include "bookmarks.h" @@ -71,6 +72,12 @@ void Bookmarks::remove(int index) bool Bookmarks::load() { + // define a lambda for loading percent-encoded string + auto loadEncoded = [](const QString &input){ + return QUrl::fromPercentEncoding(input.toUtf8()); + }; + + QFile file(m_bookmarksFile); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -94,7 +101,7 @@ bool Bookmarks::load() QStringList strings = line.split(";"); if(strings.count() == 2) { - TagInfo::sptr info = findOrAddTag(strings[0]); + TagInfo::sptr info = findOrAddTag(loadEncoded(strings[0])); info->color = QColor(strings[1].trimmed()); } else @@ -117,7 +124,7 @@ bool Bookmarks::load() { BookmarkInfo info; info.frequency = strings[0].toLongLong(); - info.name = strings[1].trimmed(); + info.name = loadEncoded(strings[1].trimmed()); info.modulation = strings[2].trimmed(); info.bandwidth = strings[3].toInt(); // Multiple Tags may be separated by comma. @@ -125,7 +132,7 @@ bool Bookmarks::load() QStringList TagList = strTags.split(","); for(int iTag=0; iTag::iterator i = usedTags.begin(); i != usedTags.end(); i++) { TagInfo::sptr info = *i; - stream << info->name.leftJustified(20) + "; " + info->color.name() << '\n'; + stream << saveEncoded(info->name).leftJustified(20) + "; " + info->color.name() << '\n'; } stream << '\n'; @@ -184,7 +195,7 @@ bool Bookmarks::save() { BookmarkInfo& info = m_BookmarkList[i]; QString line = QString::number(info.frequency).rightJustified(12) + - "; " + info.name.leftJustified(25) + "; " + + "; " + saveEncoded(info.name).leftJustified(25) + "; " + info.modulation.leftJustified(20)+ "; " + QString::number(info.bandwidth).rightJustified(10) + "; "; for(int iTag = 0; iTagname); + line.append(saveEncoded(tag->name)); } stream << line << '\n'; From 8aec71cfde3b23ed1ae3f41c314fe2dfc44a914f Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Sun, 8 Oct 2023 09:58:34 +0200 Subject: [PATCH 2/4] Refactor bookmarks save using range-based for loops --- src/qtgui/bookmarks.cpp | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/qtgui/bookmarks.cpp b/src/qtgui/bookmarks.cpp index 8dd179a0a..aa8f60ace 100644 --- a/src/qtgui/bookmarks.cpp +++ b/src/qtgui/bookmarks.cpp @@ -167,20 +167,19 @@ bool Bookmarks::save() stream << QString("# Tag name").leftJustified(20) + "; " + QString(" color") << '\n'; - QMap usedTags; - for (int iBookmark = 0; iBookmark < m_BookmarkList.size(); iBookmark++) + std::map usedTags; + for (const auto &bookmarkInfo: m_BookmarkList) { - BookmarkInfo& info = m_BookmarkList[iBookmark]; - for (QList::iterator iTag = info.tags.begin(); iTag < info.tags.end(); ++iTag) + for (const auto &tag: bookmarkInfo.tags) { - usedTags.insert((*iTag)->name, *iTag); + usedTags.emplace(tag->name, tag); } } - for (QMap::iterator i = usedTags.begin(); i != usedTags.end(); i++) + for (const auto &tag: usedTags) { - TagInfo::sptr info = *i; - stream << saveEncoded(info->name).leftJustified(20) + "; " + info->color.name() << '\n'; + auto tagInfo = tag.second; + stream << saveEncoded(tagInfo->name).leftJustified(20) + "; " + tagInfo->color.name() << '\n'; } stream << '\n'; @@ -191,22 +190,18 @@ bool Bookmarks::save() QString("Bandwidth").rightJustified(10) + "; " + QString("Tags") << '\n'; - for (int i = 0; i < m_BookmarkList.size(); i++) + for (const auto &bookmarkInfo: m_BookmarkList) { - BookmarkInfo& info = m_BookmarkList[i]; - QString line = QString::number(info.frequency).rightJustified(12) + - "; " + saveEncoded(info.name).leftJustified(25) + "; " + - info.modulation.leftJustified(20)+ "; " + - QString::number(info.bandwidth).rightJustified(10) + "; "; - for(int iTag = 0; iTagname)); + tags.append(saveEncoded(tagInfo->name)); } + line.append(tags.join(',')); stream << line << '\n'; } From 691ba1d56304b7323f10c111cc0031fa8bc4714b Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Fri, 27 Oct 2023 18:36:19 +0200 Subject: [PATCH 3/4] Revert "Sanitize bookmarks saving with percent-encoded strings, fixes #1117" This reverts commit 8c627883b815ea9bfeb65dafa3a1d9517c17ad5a. --- src/qtgui/bookmarks.cpp | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/qtgui/bookmarks.cpp b/src/qtgui/bookmarks.cpp index aa8f60ace..c4549651e 100644 --- a/src/qtgui/bookmarks.cpp +++ b/src/qtgui/bookmarks.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include "bookmarks.h" @@ -72,12 +71,6 @@ void Bookmarks::remove(int index) bool Bookmarks::load() { - // define a lambda for loading percent-encoded string - auto loadEncoded = [](const QString &input){ - return QUrl::fromPercentEncoding(input.toUtf8()); - }; - - QFile file(m_bookmarksFile); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -101,7 +94,7 @@ bool Bookmarks::load() QStringList strings = line.split(";"); if(strings.count() == 2) { - TagInfo::sptr info = findOrAddTag(loadEncoded(strings[0])); + TagInfo::sptr info = findOrAddTag(strings[0]); info->color = QColor(strings[1].trimmed()); } else @@ -124,7 +117,7 @@ bool Bookmarks::load() { BookmarkInfo info; info.frequency = strings[0].toLongLong(); - info.name = loadEncoded(strings[1].trimmed()); + info.name = strings[1].trimmed(); info.modulation = strings[2].trimmed(); info.bandwidth = strings[3].toInt(); // Multiple Tags may be separated by comma. @@ -132,7 +125,7 @@ bool Bookmarks::load() QStringList TagList = strTags.split(","); for(int iTag=0; iTagname).leftJustified(20) + "; " + tagInfo->color.name() << '\n'; + stream << tagInfo->name.leftJustified(20) + "; " + tagInfo->color.name() << '\n'; } stream << '\n'; @@ -193,13 +182,13 @@ bool Bookmarks::save() for (const auto &bookmarkInfo: m_BookmarkList) { QString line = QString::number(bookmarkInfo.frequency).rightJustified(12) + - "; " + saveEncoded(bookmarkInfo.name).leftJustified(25) + "; " + + "; " + bookmarkInfo.name.leftJustified(25) + "; " + bookmarkInfo.modulation.leftJustified(20)+ "; " + QString::number(bookmarkInfo.bandwidth).rightJustified(10) + "; "; QStringList tags; for(const auto &tagInfo: bookmarkInfo.tags) { - tags.append(saveEncoded(tagInfo->name)); + tags.append(tagInfo->name); } line.append(tags.join(',')); From 8be3dc3856f9aea5670e37da1509be969e29a70b Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Fri, 27 Oct 2023 19:36:17 +0200 Subject: [PATCH 4/4] Sanitize bookmark and tag names by preventing use of forbidden characters --- src/qtgui/CMakeLists.txt | 2 + src/qtgui/bookmarkstaglist.cpp | 4 ++ src/qtgui/dlg_saveablestring.cpp | 64 ++++++++++++++++++++++++++++++++ src/qtgui/dlg_saveablestring.h | 47 +++++++++++++++++++++++ src/qtgui/dockbookmarks.cpp | 4 ++ 5 files changed, 121 insertions(+) create mode 100644 src/qtgui/dlg_saveablestring.cpp create mode 100644 src/qtgui/dlg_saveablestring.h diff --git a/src/qtgui/CMakeLists.txt b/src/qtgui/CMakeLists.txt index a525a6d30..6945d4193 100644 --- a/src/qtgui/CMakeLists.txt +++ b/src/qtgui/CMakeLists.txt @@ -20,6 +20,8 @@ add_source_files(SRCS_LIST ctk/ctkRangeSlider.h demod_options.cpp demod_options.h + dlg_saveablestring.cpp + dlg_saveablestring.h dockaudio.cpp dockaudio.h dockbookmarks.cpp diff --git a/src/qtgui/bookmarkstaglist.cpp b/src/qtgui/bookmarkstaglist.cpp index 791f48d93..9793815e7 100644 --- a/src/qtgui/bookmarkstaglist.cpp +++ b/src/qtgui/bookmarkstaglist.cpp @@ -22,6 +22,7 @@ */ #include "bookmarkstaglist.h" #include "bookmarks.h" +#include "dlg_saveablestring.h" #include #include #include @@ -48,6 +49,9 @@ BookmarksTagList::BookmarksTagList(QWidget *parent, bool bShowUntagged ) setSelectionMode(QAbstractItemView::SingleSelection); setSelectionBehavior(QAbstractItemView::SelectRows); setSortingEnabled(true); + + LineEditDelegateSaveableString* DelegateTagName = new LineEditDelegateSaveableString(this); + this->setItemDelegateForColumn(1, DelegateTagName); } void BookmarksTagList::on_cellClicked(int row, int column) diff --git a/src/qtgui/dlg_saveablestring.cpp b/src/qtgui/dlg_saveablestring.cpp new file mode 100644 index 000000000..ea859f4fe --- /dev/null +++ b/src/qtgui/dlg_saveablestring.cpp @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt + * https://gqrx.dk/ + * + * Copyright 2023 0penBrain + * + * Gqrx is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * Gqrx is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Gqrx; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "dlg_saveablestring.h" + +#include +#include + +LineEditDelegateSaveableString::LineEditDelegateSaveableString(QObject *parent) +:QStyledItemDelegate(parent) +{ + +} + +#include +QWidget *LineEditDelegateSaveableString::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + auto* editor = QStyledItemDelegate::createEditor(parent, option, index); + auto* lineedit = qobject_cast(editor); + if (!lineedit) + { + qWarning() << __FUNCTION__ << " : " << "Editor cannot be cast to LineEdit, entry will not be validated"; + } + else + { + lineedit->setValidator(new SaveableStringValidator(lineedit)); + } + return editor; +} + +SaveableStringValidator::SaveableStringValidator(QObject *parent) +:QValidator(parent) +{ + +} + +QValidator::State SaveableStringValidator::validate(QString &input, int &pos) const +{ + if (input.contains(';') || input.contains(',')) + { + return QValidator::Invalid; + } + return QValidator::Acceptable; +} diff --git a/src/qtgui/dlg_saveablestring.h b/src/qtgui/dlg_saveablestring.h new file mode 100644 index 000000000..964ac0894 --- /dev/null +++ b/src/qtgui/dlg_saveablestring.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt + * https://gqrx.dk/ + * + * Copyright 2023 0penBrain + * + * Gqrx is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * Gqrx is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Gqrx; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef DLG_SAVEABLESTRING_H +#define DLG_SAVEABLESTRING_H + +#include +#include + +class LineEditDelegateSaveableString : public QStyledItemDelegate +{ +Q_OBJECT +public: + LineEditDelegateSaveableString(QObject *parent = 0); + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + //void setEditorData(QWidget *editor, const QModelIndex &index) const; + //void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; +}; + +class SaveableStringValidator : public QValidator +{ +Q_OBJECT +public: + SaveableStringValidator(QObject *parent = 0); + QValidator::State validate(QString &input, int &pos) const; +}; + +#endif // DLG_SAVEABLESTRING_H diff --git a/src/qtgui/dockbookmarks.cpp b/src/qtgui/dockbookmarks.cpp index ff518588d..3e41430a1 100644 --- a/src/qtgui/dockbookmarks.cpp +++ b/src/qtgui/dockbookmarks.cpp @@ -31,6 +31,7 @@ #include "bookmarks.h" #include "bookmarkstaglist.h" +#include "dlg_saveablestring.h" #include "dockbookmarks.h" #include "dockrxopt.h" #include "qtcolorpicker.h" @@ -56,6 +57,9 @@ DockBookmarks::DockBookmarks(QWidget *parent) : ComboBoxDelegateModulation* delegateModulation = new ComboBoxDelegateModulation(this); ui->tableViewFrequencyList->setItemDelegateForColumn(2, delegateModulation); + LineEditDelegateSaveableString* delegateBookmarkName = new LineEditDelegateSaveableString(this); + ui->tableViewFrequencyList->setItemDelegateForColumn(1, delegateBookmarkName); + // Bookmarks Context menu contextmenu = new QMenu(this); // MenuItem Delete