From 28314fec43f27374503416ee2d23f0fb052d7850 Mon Sep 17 00:00:00 2001 From: Lauris Kaplinski Date: Fri, 2 Jan 2026 11:13:04 +0200 Subject: [PATCH 1/4] Remove invalid XML1.0 characters from Role/City... fields --- client/dialogs/RoleAddressDialog.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/client/dialogs/RoleAddressDialog.cpp b/client/dialogs/RoleAddressDialog.cpp index 362e31a2b..6959d8333 100644 --- a/client/dialogs/RoleAddressDialog.cpp +++ b/client/dialogs/RoleAddressDialog.cpp @@ -28,6 +28,18 @@ class RoleAddressDialog::Private: public Ui::RoleAddressDialog {}; +static QString cleanUp(const QString& src) { + QString dst(src.size(), QChar(0)); + size_t dlen = 0; + for (auto s = 0; s < src.size(); s++) { + if ((src[s] <= ' ') && (src[s] != QChar(0x9)) && (src[s] != QChar(0xa)) && (src[s] != QChar(0xd))) continue; + if ((src[s] == QChar(0xfffe)) || (src[s] == QChar(0xffff))) continue; + dst[dlen++] = src[s]; + } + dst.resize(dlen); + return dst; +} + RoleAddressDialog::RoleAddressDialog(QWidget *parent) : QDialog(parent) , d(new Private) @@ -57,8 +69,9 @@ RoleAddressDialog::RoleAddressDialog(QWidget *parent) line->setCompleter(completer); connect(line, &QLineEdit::editingFinished, this, [line, s = std::move(s)] { QStringList list = s; - list.removeAll(line->text()); - list.insert(0, line->text()); + QString text = cleanUp(line->text()); + list.removeAll(text); + list.insert(0, text); if(list.size() > 10) list.removeLast(); s.clear(); // Uses on Windows MULTI_STRING registry @@ -81,10 +94,10 @@ int RoleAddressDialog::get(QString &city, QString &country, QString &state, QStr int result = QDialog::exec(); if(result == QDialog::Rejected) return result; - role = d->Role->text(); - city = d->City->text(); - state = d->State->text(); - country = d->Country->text(); - zip = d->Zip->text(); + role = cleanUp(d->Role->text()); + city = cleanUp(d->City->text()); + state = cleanUp(d->State->text()); + country = cleanUp(d->Country->text()); + zip = cleanUp(d->Zip->text()); return result; } From a562d02417f530b8f87fbd86a07e27fe65203804 Mon Sep 17 00:00:00 2001 From: Lauris Kaplinski Date: Fri, 2 Jan 2026 13:51:53 +0200 Subject: [PATCH 2/4] Use iterator --- client/dialogs/RoleAddressDialog.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/dialogs/RoleAddressDialog.cpp b/client/dialogs/RoleAddressDialog.cpp index 6959d8333..f52fb71b9 100644 --- a/client/dialogs/RoleAddressDialog.cpp +++ b/client/dialogs/RoleAddressDialog.cpp @@ -31,10 +31,10 @@ class RoleAddressDialog::Private: public Ui::RoleAddressDialog {}; static QString cleanUp(const QString& src) { QString dst(src.size(), QChar(0)); size_t dlen = 0; - for (auto s = 0; s < src.size(); s++) { - if ((src[s] <= ' ') && (src[s] != QChar(0x9)) && (src[s] != QChar(0xa)) && (src[s] != QChar(0xd))) continue; - if ((src[s] == QChar(0xfffe)) || (src[s] == QChar(0xffff))) continue; - dst[dlen++] = src[s]; + for (auto s = src.cbegin(); s != src.cend(); s++) { + if ((*s <= ' ') && (*s != QChar(0x9)) && (*s != QChar(0xa)) && (*s != QChar(0xd))) continue; + if ((*s == QChar(0xfffe)) || (*s == QChar(0xffff))) continue; + dst[dlen++] = *s; } dst.resize(dlen); return dst; From 7c5d3306a7fa79f8c7079121d41a0b9df35f6860 Mon Sep 17 00:00:00 2001 From: Lauris Kaplinski Date: Fri, 2 Jan 2026 14:01:55 +0200 Subject: [PATCH 3/4] Use reserve/append instead of resize --- client/dialogs/RoleAddressDialog.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/dialogs/RoleAddressDialog.cpp b/client/dialogs/RoleAddressDialog.cpp index f52fb71b9..1c12e3a33 100644 --- a/client/dialogs/RoleAddressDialog.cpp +++ b/client/dialogs/RoleAddressDialog.cpp @@ -29,12 +29,13 @@ class RoleAddressDialog::Private: public Ui::RoleAddressDialog {}; static QString cleanUp(const QString& src) { - QString dst(src.size(), QChar(0)); + QString dst; + dst.reserve(src.size()); size_t dlen = 0; for (auto s = src.cbegin(); s != src.cend(); s++) { if ((*s <= ' ') && (*s != QChar(0x9)) && (*s != QChar(0xa)) && (*s != QChar(0xd))) continue; if ((*s == QChar(0xfffe)) || (*s == QChar(0xffff))) continue; - dst[dlen++] = *s; + dst.append(*s); } dst.resize(dlen); return dst; From 979b2cd7813ca52311df512cda6d6722d3b21ddc Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Wed, 1 Apr 2026 10:17:31 +0300 Subject: [PATCH 4/4] Use QValidator Signed-off-by: Raul Metsma --- .github/workflows/build.yml | 4 ++-- client/dialogs/RoleAddressDialog.cpp | 32 ++++++++++------------------ 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b897ec295..c7ddee1a2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,7 +70,7 @@ jobs: container: ubuntu:${{ matrix.container }} strategy: matrix: - container: ['22.04', '24.04', '25.04', '25.10'] + container: ['22.04', '24.04', '25.10', '26.04'] arch: ['amd64', 'arm64'] env: DEBIAN_FRONTEND: noninteractive @@ -116,7 +116,7 @@ jobs: container: fedora:${{ matrix.container }} strategy: matrix: - container: [42, 43] + container: [42, 43, 44] steps: - name: Download artifact uses: dawidd6/action-download-artifact@v11 diff --git a/client/dialogs/RoleAddressDialog.cpp b/client/dialogs/RoleAddressDialog.cpp index 1c12e3a33..0ca901f71 100644 --- a/client/dialogs/RoleAddressDialog.cpp +++ b/client/dialogs/RoleAddressDialog.cpp @@ -28,19 +28,6 @@ class RoleAddressDialog::Private: public Ui::RoleAddressDialog {}; -static QString cleanUp(const QString& src) { - QString dst; - dst.reserve(src.size()); - size_t dlen = 0; - for (auto s = src.cbegin(); s != src.cend(); s++) { - if ((*s <= ' ') && (*s != QChar(0x9)) && (*s != QChar(0xa)) && (*s != QChar(0xd))) continue; - if ((*s == QChar(0xfffe)) || (*s == QChar(0xffff))) continue; - dst.append(*s); - } - dst.resize(dlen); - return dst; -} - RoleAddressDialog::RoleAddressDialog(QWidget *parent) : QDialog(parent) , d(new Private) @@ -50,17 +37,20 @@ RoleAddressDialog::RoleAddressDialog(QWidget *parent) d->buttonLayout->setDirection(QBoxLayout::RightToLeft); #endif setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint); - for(QLineEdit *w: findChildren()) - w->setAttribute(Qt::WA_MacShowFocusRect, false); connect( d->cancel, &QPushButton::clicked, this, &RoleAddressDialog::reject ); connect( d->sign, &QPushButton::clicked, this, &RoleAddressDialog::accept ); + auto *validator = new QRegularExpressionValidator( + QRegularExpression(QStringLiteral("[^\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\uFFFE\\uFFFF]*")), + this); auto list = findChildren(); if(!list.isEmpty()) list.first()->setFocus(); for(QLineEdit *line: list) { + line->setAttribute(Qt::WA_MacShowFocusRect, false); + line->setValidator(validator); Settings::Option s{line->objectName(), {}}; auto *completer = new QCompleter(s, line); completer->setMaxVisibleItems(10); @@ -70,7 +60,7 @@ RoleAddressDialog::RoleAddressDialog(QWidget *parent) line->setCompleter(completer); connect(line, &QLineEdit::editingFinished, this, [line, s = std::move(s)] { QStringList list = s; - QString text = cleanUp(line->text()); + QString text = line->text(); list.removeAll(text); list.insert(0, text); if(list.size() > 10) @@ -95,10 +85,10 @@ int RoleAddressDialog::get(QString &city, QString &country, QString &state, QStr int result = QDialog::exec(); if(result == QDialog::Rejected) return result; - role = cleanUp(d->Role->text()); - city = cleanUp(d->City->text()); - state = cleanUp(d->State->text()); - country = cleanUp(d->Country->text()); - zip = cleanUp(d->Zip->text()); + role = d->Role->text(); + city = d->City->text(); + state = d->State->text(); + country = d->Country->text(); + zip = d->Zip->text(); return result; }