diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index b1d21378..30f39f26 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -5,126 +5,127 @@ PROJECT(Cockatrice VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") SET(cockatrice_SOURCES + src/abstractcarddragitem.cpp + src/abstractcarditem.cpp + src/abstractclient.cpp src/abstractcounter.cpp + src/abstractgraphicsitem.cpp + src/arrowitem.cpp + src/arrowtarget.cpp + src/carddatabase.cpp + src/carddatabasemodel.cpp + src/carddbparser/carddatabaseparser.cpp + src/carddbparser/cockatricexml3.cpp + src/carddbparser/cockatricexml4.cpp + src/carddragitem.cpp + src/cardfilter.cpp + src/cardframe.cpp + src/cardinfopicture.cpp + src/cardinfotext.cpp + src/cardinfowidget.cpp + src/carditem.cpp + src/cardlist.cpp + src/cardzone.cpp + src/chatview/chatview.cpp src/counter_general.cpp - src/dlg_creategame.cpp - src/dlg_filter_games.cpp + src/customlineedit.cpp + src/deck_loader.cpp + src/decklistmodel.cpp + src/deckstats_interface.cpp + src/deckview.cpp src/dlg_connect.cpp src/dlg_create_token.cpp + src/dlg_creategame.cpp src/dlg_edit_avatar.cpp src/dlg_edit_password.cpp src/dlg_edit_tokens.cpp src/dlg_edit_user.cpp + src/dlg_filter_games.cpp + src/dlg_forgotpasswordchallenge.cpp src/dlg_forgotpasswordrequest.cpp src/dlg_forgotpasswordreset.cpp - src/dlg_forgotpasswordchallenge.cpp - src/dlg_manage_sets.cpp - src/dlg_register.cpp - src/dlg_tip_of_the_day.cpp - src/tip_of_the_day.cpp - src/dlg_update.cpp - src/dlg_viewlog.cpp - src/abstractclient.cpp - src/remoteclient.cpp - src/main.cpp - src/window_main.cpp - src/gamesmodel.cpp - src/player.cpp - src/playertarget.cpp - src/cardzone.cpp - src/selectzone.cpp - src/cardlist.cpp - src/abstractcarditem.cpp - src/carditem.cpp - src/tablezone.cpp - src/handzone.cpp - src/handcounter.cpp - src/carddatabase.cpp - src/keysignals.cpp - src/gameview.cpp - src/gameselector.cpp - src/decklistmodel.cpp - src/deck_loader.cpp src/dlg_load_deck_from_clipboard.cpp src/dlg_load_remote_deck.cpp - src/cardinfowidget.cpp - src/cardframe.cpp - src/cardinfopicture.cpp - src/cardinfotext.cpp - src/filterbuilder.cpp - src/cardfilter.cpp - src/filtertreemodel.cpp - src/filtertree.cpp - src/messagelogwidget.cpp - src/zoneviewzone.cpp - src/zoneviewwidget.cpp - src/pilezone.cpp - src/stackzone.cpp - src/carddragitem.cpp - src/carddatabasemodel.cpp - src/setsmodel.cpp - src/abstractgraphicsitem.cpp - src/abstractcarddragitem.cpp + src/dlg_manage_sets.cpp + src/dlg_register.cpp src/dlg_settings.cpp - src/phasestoolbar.cpp + src/dlg_tip_of_the_day.cpp + src/dlg_update.cpp + src/dlg_viewlog.cpp + src/filter_string.cpp + src/filterbuilder.cpp + src/filtertree.cpp + src/filtertreemodel.cpp src/gamescene.cpp - src/arrowitem.cpp - src/arrowtarget.cpp - src/tab.cpp - src/tab_server.cpp - src/tab_room.cpp - src/tab_message.cpp - src/tab_game.cpp - src/tab_deck_storage.cpp - src/tab_replays.cpp - src/tab_supervisor.cpp - src/tab_admin.cpp - src/tab_account.cpp - src/tab_deck_editor.cpp - src/tab_logs.cpp - src/replay_timeline_widget.cpp - src/deckstats_interface.cpp - src/tappedout_interface.cpp - src/chatview/chatview.cpp - src/userlist.cpp - src/userinfobox.cpp - src/user_context_menu.cpp - src/remotedecklist_treewidget.cpp - src/remotereplaylist_treewidget.cpp - src/deckview.cpp - src/playerlistwidget.cpp - src/pixmapgenerator.cpp - src/settingscache.cpp - src/thememanager.cpp + src/gameselector.cpp + src/gamesmodel.cpp + src/gameview.cpp + src/gettextwithmax.cpp + src/handcounter.cpp + src/handle_public_servers.cpp + src/handzone.cpp + src/keysignals.cpp + src/lineeditcompleter.cpp + src/localclient.cpp src/localserver.cpp src/localserverinterface.cpp - src/localclient.cpp - src/soundengine.cpp + src/logger.cpp + src/main.cpp + src/messagelogwidget.cpp src/pending_command.cpp + src/phase.cpp + src/phasestoolbar.cpp src/pictureloader.cpp - src/shortcutssettings.cpp + src/pilezone.cpp + src/pixmapgenerator.cpp + src/player.cpp + src/playerlistwidget.cpp + src/playertarget.cpp + src/releasechannel.cpp + src/remoteclient.cpp + src/remotedecklist_treewidget.cpp + src/remotereplaylist_treewidget.cpp + src/replay_timeline_widget.cpp + src/selectzone.cpp src/sequenceEdit/sequenceedit.cpp - src/lineeditcompleter.cpp - src/settings/settingsmanager.cpp + src/setsmodel.cpp src/settings/carddatabasesettings.cpp - src/settings/serverssettings.cpp - src/settings/messagesettings.cpp + src/settings/downloadsettings.cpp src/settings/gamefilterssettings.cpp src/settings/layoutssettings.cpp - src/settings/downloadsettings.cpp - src/update_downloader.cpp - src/logger.cpp - src/releasechannel.cpp - src/userconnection_information.cpp + src/settings/messagesettings.cpp + src/settings/serverssettings.cpp + src/settings/settingsmanager.cpp + src/settingscache.cpp + src/shortcutssettings.cpp + src/soundengine.cpp src/spoilerbackgroundupdater.cpp - src/handle_public_servers.cpp - src/carddbparser/carddatabaseparser.cpp - src/carddbparser/cockatricexml3.cpp - src/carddbparser/cockatricexml4.cpp - src/filter_string.cpp - src/phase.cpp - src/customlineedit.cpp + src/stackzone.cpp + src/tab.cpp + src/tab_account.cpp + src/tab_admin.cpp + src/tab_deck_editor.cpp + src/tab_deck_storage.cpp + src/tab_game.cpp + src/tab_logs.cpp + src/tab_message.cpp + src/tab_replays.cpp + src/tab_room.cpp + src/tab_server.cpp + src/tab_supervisor.cpp + src/tablezone.cpp + src/tappedout_interface.cpp + src/thememanager.cpp + src/tip_of_the_day.cpp src/translatecountername.cpp + src/update_downloader.cpp + src/user_context_menu.cpp + src/userconnection_information.cpp + src/userinfobox.cpp + src/userlist.cpp + src/window_main.cpp + src/zoneviewwidget.cpp + src/zoneviewzone.cpp ${VERSION_STRING_CPP} ) diff --git a/cockatrice/src/chatview/chatview.cpp b/cockatrice/src/chatview/chatview.cpp index 72baed39..d323495c 100644 --- a/cockatrice/src/chatview/chatview.cpp +++ b/cockatrice/src/chatview/chatview.cpp @@ -12,8 +12,6 @@ #include #include #include -#include -#include const QColor DEFAULT_MENTION_COLOR = QColor(194, 31, 47); diff --git a/cockatrice/src/customlineedit.cpp b/cockatrice/src/customlineedit.cpp index c0dbc0a7..0afdac3a 100644 --- a/cockatrice/src/customlineedit.cpp +++ b/cockatrice/src/customlineedit.cpp @@ -1,4 +1,3 @@ - #include "customlineedit.h" #include "settingscache.h" @@ -38,8 +37,8 @@ bool LineEditUnfocusable::isUnfocusShortcut(QKeyEvent *event) QKeySequence key(modifier + keyNoMod); QList unfocusShortcut = SettingsCache::instance().shortcuts().getShortcut("Textbox/unfocusTextBox"); - for (QList::iterator i = unfocusShortcut.begin(); i != unfocusShortcut.end(); ++i) { - if (key.matches(*i) == QKeySequence::ExactMatch) + for (const auto &unfocusKey : unfocusShortcut) { + if (key.matches(unfocusKey) == QKeySequence::ExactMatch) return true; } return false; diff --git a/cockatrice/src/customlineedit.h b/cockatrice/src/customlineedit.h index fcd824e0..510c0f3d 100644 --- a/cockatrice/src/customlineedit.h +++ b/cockatrice/src/customlineedit.h @@ -12,12 +12,13 @@ class QString; // shortcuts and other shortcuts class LineEditUnfocusable : public QLineEdit { + Q_OBJECT public: - LineEditUnfocusable(QWidget *parent = nullptr); - LineEditUnfocusable(const QString &contents, QWidget *parent = nullptr); + explicit LineEditUnfocusable(QWidget *parent = nullptr); + explicit LineEditUnfocusable(const QString &contents, QWidget *parent = nullptr); private: - bool isUnfocusShortcut(QKeyEvent *key); + static bool isUnfocusShortcut(QKeyEvent *key); protected: void keyPressEvent(QKeyEvent *event) override; diff --git a/cockatrice/src/dlg_connect.cpp b/cockatrice/src/dlg_connect.cpp index 4f29b390..e63a7a87 100644 --- a/cockatrice/src/dlg_connect.cpp +++ b/cockatrice/src/dlg_connect.cpp @@ -1,6 +1,7 @@ #include "dlg_connect.h" #include "settingscache.h" +#include "stringsizes.h" #include "userconnection_information.h" #include @@ -39,22 +40,27 @@ DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent) saveLabel = new QLabel(tr("Name:")); saveEdit = new QLineEdit; + saveEdit->setMaxLength(MAX_NAME_LENGTH); saveLabel->setBuddy(saveEdit); hostLabel = new QLabel(tr("&Host:")); hostEdit = new QLineEdit; + hostEdit->setMaxLength(MAX_NAME_LENGTH); hostLabel->setBuddy(hostEdit); portLabel = new QLabel(tr("&Port:")); portEdit = new QLineEdit; + portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit)); portLabel->setBuddy(portEdit); playernameLabel = new QLabel(tr("Player &name:")); playernameEdit = new QLineEdit; + playernameEdit->setMaxLength(MAX_NAME_LENGTH); playernameLabel->setBuddy(playernameEdit); passwordLabel = new QLabel(tr("P&assword:")); passwordEdit = new QLineEdit; + passwordEdit->setMaxLength(MAX_NAME_LENGTH); passwordLabel->setBuddy(passwordEdit); passwordEdit->setEchoMode(QLineEdit::Password); diff --git a/cockatrice/src/dlg_create_token.cpp b/cockatrice/src/dlg_create_token.cpp index 510c400a..3a7c86de 100644 --- a/cockatrice/src/dlg_create_token.cpp +++ b/cockatrice/src/dlg_create_token.cpp @@ -5,6 +5,7 @@ #include "decklist.h" #include "main.h" #include "settingscache.h" +#include "stringsizes.h" #include #include @@ -28,6 +29,7 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa nameLabel = new QLabel(tr("&Name:")); nameEdit = new QLineEdit(tr("Token")); + nameEdit->setMaxLength(MAX_NAME_LENGTH); nameEdit->selectAll(); connect(nameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(updateSearch(const QString &))); nameLabel->setBuddy(nameEdit); @@ -45,10 +47,12 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa ptLabel = new QLabel(tr("&P/T:")); ptEdit = new QLineEdit; + ptEdit->setMaxLength(MAX_NAME_LENGTH); ptLabel->setBuddy(ptEdit); annotationLabel = new QLabel(tr("&Annotation:")); annotationEdit = new QLineEdit; + annotationEdit->setMaxLength(MAX_NAME_LENGTH); annotationLabel->setBuddy(annotationEdit); destroyCheckBox = new QCheckBox(tr("&Destroy token when it leaves the table")); diff --git a/cockatrice/src/dlg_creategame.cpp b/cockatrice/src/dlg_creategame.cpp index 654cf97e..11fc0510 100644 --- a/cockatrice/src/dlg_creategame.cpp +++ b/cockatrice/src/dlg_creategame.cpp @@ -3,6 +3,7 @@ #include "pb/serverinfo_game.pb.h" #include "pending_command.h" #include "settingscache.h" +#include "stringsizes.h" #include "tab_room.h" #include @@ -24,8 +25,8 @@ void DlgCreateGame::sharedCtor() rememberGameSettings = new QCheckBox(tr("Re&member settings")); descriptionLabel = new QLabel(tr("&Description:")); descriptionEdit = new QLineEdit; + descriptionEdit->setMaxLength(MAX_NAME_LENGTH); descriptionLabel->setBuddy(descriptionEdit); - descriptionEdit->setMaxLength(60); maxPlayersLabel = new QLabel(tr("P&layers:")); maxPlayersEdit = new QSpinBox(); @@ -57,6 +58,7 @@ void DlgCreateGame::sharedCtor() passwordLabel = new QLabel(tr("&Password:")); passwordEdit = new QLineEdit; + passwordEdit->setMaxLength(MAX_NAME_LENGTH); passwordLabel->setBuddy(passwordEdit); onlyBuddiesCheckBox = new QCheckBox(tr("Only &buddies can join")); diff --git a/cockatrice/src/dlg_edit_avatar.cpp b/cockatrice/src/dlg_edit_avatar.cpp index cbdd89b5..38f6fa20 100644 --- a/cockatrice/src/dlg_edit_avatar.cpp +++ b/cockatrice/src/dlg_edit_avatar.cpp @@ -1,5 +1,7 @@ #include "dlg_edit_avatar.h" +#include "stringsizes.h" + #include #include #include @@ -75,6 +77,13 @@ QByteArray DlgEditAvatar::getImage() QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); - image.save(&buffer, "JPG"); - return ba; + for (;;) { + image.save(&buffer, "JPG"); + if (ba.length() > MAX_FILE_LENGTH) { + ba.clear(); + image = image.scaledToWidth(image.width() / 2); // divide the amount of pixels in four to get the size down + } else { + return ba; + } + } } diff --git a/cockatrice/src/dlg_edit_password.cpp b/cockatrice/src/dlg_edit_password.cpp index 6bc1f382..abec2cf9 100644 --- a/cockatrice/src/dlg_edit_password.cpp +++ b/cockatrice/src/dlg_edit_password.cpp @@ -1,6 +1,7 @@ #include "dlg_edit_password.h" #include "settingscache.h" +#include "stringsizes.h" #include #include @@ -12,6 +13,7 @@ DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent) { oldPasswordLabel = new QLabel(tr("Old password:")); oldPasswordEdit = new QLineEdit(); + oldPasswordEdit->setMaxLength(MAX_NAME_LENGTH); auto &servers = SettingsCache::instance().servers(); if (servers.getSavePassword()) { @@ -23,11 +25,13 @@ DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent) newPasswordLabel = new QLabel(tr("New password:")); newPasswordEdit = new QLineEdit(); + newPasswordEdit->setMaxLength(MAX_NAME_LENGTH); newPasswordLabel->setBuddy(newPasswordLabel); newPasswordEdit->setEchoMode(QLineEdit::Password); newPasswordLabel2 = new QLabel(tr("Confirm new password:")); newPasswordEdit2 = new QLineEdit(); + newPasswordEdit2->setMaxLength(MAX_NAME_LENGTH); newPasswordLabel2->setBuddy(newPasswordLabel2); newPasswordEdit2->setEchoMode(QLineEdit::Password); diff --git a/cockatrice/src/dlg_edit_tokens.cpp b/cockatrice/src/dlg_edit_tokens.cpp index a8836837..9e724b97 100644 --- a/cockatrice/src/dlg_edit_tokens.cpp +++ b/cockatrice/src/dlg_edit_tokens.cpp @@ -2,7 +2,9 @@ #include "carddatabase.h" #include "carddatabasemodel.h" +#include "gettextwithmax.h" #include "main.h" +#include "stringsizes.h" #include #include @@ -23,6 +25,7 @@ DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(nul { nameLabel = new QLabel(tr("&Name:")); nameEdit = new QLineEdit; + nameEdit->setMaxLength(MAX_NAME_LENGTH); nameEdit->setEnabled(false); nameLabel->setBuddy(nameEdit); @@ -40,11 +43,13 @@ DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(nul ptLabel = new QLabel(tr("&P/T:")); ptEdit = new QLineEdit; + ptEdit->setMaxLength(MAX_NAME_LENGTH); ptLabel->setBuddy(ptEdit); connect(ptEdit, SIGNAL(textChanged(QString)), this, SLOT(ptChanged(QString))); annotationLabel = new QLabel(tr("&Annotation:")); annotationEdit = new QLineEdit; + annotationEdit->setMaxLength(MAX_NAME_LENGTH); annotationLabel->setBuddy(annotationEdit); connect(annotationEdit, SIGNAL(textChanged(QString)), this, SLOT(annotationChanged(QString))); @@ -142,9 +147,8 @@ void DlgEditTokens::tokenSelectionChanged(const QModelIndex ¤t, const QMod void DlgEditTokens::actAddToken() { QString name; - bool askAgain = true; - do { - name = QInputDialog::getText(this, tr("Add token"), tr("Please enter the name of the token:")); + for (;;) { + name = getTextWithMax(this, tr("Add token"), tr("Please enter the name of the token:")); if (name.isEmpty()) return; if (databaseModel->getDatabase()->getCard(name)) { @@ -152,9 +156,9 @@ void DlgEditTokens::actAddToken() tr("The chosen name conflicts with an existing card or token.\nMake sure to enable " "the 'Token' set in the \"Manage sets\" dialog to display them correctly.")); } else { - askAgain = false; + break; } - } while (askAgain); + } QString setName = CardDatabase::TOKENS_SETNAME; CardInfoPerSetMap sets; diff --git a/cockatrice/src/dlg_edit_user.cpp b/cockatrice/src/dlg_edit_user.cpp index a2ec6a7c..819d0352 100644 --- a/cockatrice/src/dlg_edit_user.cpp +++ b/cockatrice/src/dlg_edit_user.cpp @@ -1,6 +1,7 @@ #include "dlg_edit_user.h" #include "settingscache.h" +#include "stringsizes.h" #include #include @@ -12,6 +13,7 @@ DlgEditUser::DlgEditUser(QWidget *parent, QString email, QString country, QStrin { emailLabel = new QLabel(tr("Email:")); emailEdit = new QLineEdit(); + emailEdit->setMaxLength(MAX_NAME_LENGTH); emailLabel->setBuddy(emailEdit); emailEdit->setText(email); @@ -33,6 +35,7 @@ DlgEditUser::DlgEditUser(QWidget *parent, QString email, QString country, QStrin realnameLabel = new QLabel(tr("Real name:")); realnameEdit = new QLineEdit(); + realnameEdit->setMaxLength(MAX_NAME_LENGTH); realnameLabel->setBuddy(realnameEdit); realnameEdit->setText(realName); diff --git a/cockatrice/src/dlg_forgotpasswordchallenge.cpp b/cockatrice/src/dlg_forgotpasswordchallenge.cpp index 44a18258..8de5afae 100644 --- a/cockatrice/src/dlg_forgotpasswordchallenge.cpp +++ b/cockatrice/src/dlg_forgotpasswordchallenge.cpp @@ -1,6 +1,7 @@ #include "dlg_forgotpasswordchallenge.h" #include "settingscache.h" +#include "stringsizes.h" #include #include @@ -38,18 +39,22 @@ DlgForgotPasswordChallenge::DlgForgotPasswordChallenge(QWidget *parent) : QDialo hostLabel = new QLabel(tr("&Host:")); hostEdit = new QLineEdit(lastfphost); + hostEdit->setMaxLength(MAX_NAME_LENGTH); hostLabel->setBuddy(hostEdit); portLabel = new QLabel(tr("&Port:")); portEdit = new QLineEdit(lastfpport); + portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit)); portLabel->setBuddy(portEdit); playernameLabel = new QLabel(tr("Player &name:")); playernameEdit = new QLineEdit(lastfpplayername); + playernameEdit->setMaxLength(MAX_NAME_LENGTH); playernameLabel->setBuddy(playernameEdit); emailLabel = new QLabel(tr("Email:")); emailEdit = new QLineEdit(); + emailEdit->setMaxLength(MAX_NAME_LENGTH); emailLabel->setBuddy(emailLabel); if (!servers.getFPHostname().isEmpty() && !servers.getFPPort().isEmpty() && !servers.getFPPlayerName().isEmpty()) { diff --git a/cockatrice/src/dlg_forgotpasswordrequest.cpp b/cockatrice/src/dlg_forgotpasswordrequest.cpp index e12bd1f0..c92b28d3 100644 --- a/cockatrice/src/dlg_forgotpasswordrequest.cpp +++ b/cockatrice/src/dlg_forgotpasswordrequest.cpp @@ -1,6 +1,7 @@ #include "dlg_forgotpasswordrequest.h" #include "settingscache.h" +#include "stringsizes.h" #include #include @@ -31,14 +32,17 @@ DlgForgotPasswordRequest::DlgForgotPasswordRequest(QWidget *parent) : QDialog(pa hostLabel = new QLabel(tr("&Host:")); hostEdit = new QLineEdit(lastfphost); + hostEdit->setMaxLength(MAX_NAME_LENGTH); hostLabel->setBuddy(hostEdit); portLabel = new QLabel(tr("&Port:")); portEdit = new QLineEdit(lastfpport); + portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit)); portLabel->setBuddy(portEdit); playernameLabel = new QLabel(tr("Player &name:")); playernameEdit = new QLineEdit(lastfpplayername); + playernameEdit->setMaxLength(MAX_NAME_LENGTH); playernameLabel->setBuddy(playernameEdit); QGridLayout *grid = new QGridLayout; diff --git a/cockatrice/src/dlg_forgotpasswordreset.cpp b/cockatrice/src/dlg_forgotpasswordreset.cpp index 6945eee0..bf9ea5a8 100644 --- a/cockatrice/src/dlg_forgotpasswordreset.cpp +++ b/cockatrice/src/dlg_forgotpasswordreset.cpp @@ -1,6 +1,7 @@ #include "dlg_forgotpasswordreset.h" #include "settingscache.h" +#include "stringsizes.h" #include #include @@ -37,27 +38,33 @@ DlgForgotPasswordReset::DlgForgotPasswordReset(QWidget *parent) : QDialog(parent hostLabel = new QLabel(tr("&Host:")); hostEdit = new QLineEdit(lastfphost); + hostEdit->setMaxLength(MAX_NAME_LENGTH); hostLabel->setBuddy(hostEdit); portLabel = new QLabel(tr("&Port:")); portEdit = new QLineEdit(lastfpport); + portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit)); portLabel->setBuddy(portEdit); playernameLabel = new QLabel(tr("Player &name:")); playernameEdit = new QLineEdit(lastfpplayername); + playernameEdit->setMaxLength(MAX_NAME_LENGTH); playernameLabel->setBuddy(playernameEdit); tokenLabel = new QLabel(tr("Token:")); tokenEdit = new QLineEdit(); + tokenEdit->setMaxLength(MAX_NAME_LENGTH); tokenLabel->setBuddy(tokenLabel); newpasswordLabel = new QLabel(tr("New Password:")); newpasswordEdit = new QLineEdit(); + newpasswordEdit->setMaxLength(MAX_NAME_LENGTH); newpasswordLabel->setBuddy(newpasswordEdit); newpasswordEdit->setEchoMode(QLineEdit::Password); newpasswordverifyLabel = new QLabel(tr("New Password:")); newpasswordverifyEdit = new QLineEdit(); + newpasswordverifyEdit->setMaxLength(MAX_NAME_LENGTH); newpasswordverifyLabel->setBuddy(newpasswordEdit); newpasswordverifyEdit->setEchoMode(QLineEdit::Password); diff --git a/cockatrice/src/dlg_register.cpp b/cockatrice/src/dlg_register.cpp index 2af05af6..adf6ba6e 100644 --- a/cockatrice/src/dlg_register.cpp +++ b/cockatrice/src/dlg_register.cpp @@ -2,6 +2,7 @@ #include "pb/serverinfo_user.pb.h" #include "settingscache.h" +#include "stringsizes.h" #include #include @@ -20,32 +21,39 @@ DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent) hostLabel = new QLabel(tr("&Host:")); hostEdit = new QLineEdit(servers.getHostname()); + hostEdit->setMaxLength(MAX_NAME_LENGTH); hostLabel->setBuddy(hostEdit); portLabel = new QLabel(tr("&Port:")); portEdit = new QLineEdit(servers.getPort()); + portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit)); portLabel->setBuddy(portEdit); playernameLabel = new QLabel(tr("Player &name:")); playernameEdit = new QLineEdit(servers.getPlayerName()); + playernameEdit->setMaxLength(MAX_NAME_LENGTH); playernameLabel->setBuddy(playernameEdit); passwordLabel = new QLabel(tr("P&assword:")); passwordEdit = new QLineEdit(); + passwordEdit->setMaxLength(MAX_NAME_LENGTH); passwordLabel->setBuddy(passwordEdit); passwordEdit->setEchoMode(QLineEdit::Password); passwordConfirmationLabel = new QLabel(tr("Password (again):")); passwordConfirmationEdit = new QLineEdit(); + passwordConfirmationEdit->setMaxLength(MAX_NAME_LENGTH); passwordConfirmationLabel->setBuddy(passwordConfirmationEdit); passwordConfirmationEdit->setEchoMode(QLineEdit::Password); emailLabel = new QLabel(tr("Email:")); emailEdit = new QLineEdit(); + emailEdit->setMaxLength(MAX_NAME_LENGTH); emailLabel->setBuddy(emailEdit); emailConfirmationLabel = new QLabel(tr("Email (again):")); emailConfirmationEdit = new QLineEdit(); + emailConfirmationEdit->setMaxLength(MAX_NAME_LENGTH); emailConfirmationLabel->setBuddy(emailConfirmationEdit); countryLabel = new QLabel(tr("Country:")); @@ -308,6 +316,7 @@ DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent) realnameLabel = new QLabel(tr("Real name:")); realnameEdit = new QLineEdit(); + realnameEdit->setMaxLength(MAX_NAME_LENGTH); realnameLabel->setBuddy(realnameEdit); QGridLayout *grid = new QGridLayout; diff --git a/cockatrice/src/dlg_settings.cpp b/cockatrice/src/dlg_settings.cpp index bfea023a..4261244e 100644 --- a/cockatrice/src/dlg_settings.cpp +++ b/cockatrice/src/dlg_settings.cpp @@ -1,6 +1,7 @@ #include "dlg_settings.h" #include "carddatabase.h" +#include "gettextwithmax.h" #include "main.h" #include "releasechannel.h" #include "sequenceEdit/sequenceedit.h" @@ -76,12 +77,9 @@ GeneralSettingsPage::GeneralSettingsPage() connect(&languageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(languageBoxChanged(int))); connect(&pixmapCacheEdit, SIGNAL(valueChanged(int)), &settings, SLOT(setPixmapCacheSize(int))); - connect(&updateReleaseChannelBox, SIGNAL(currentIndexChanged(int)), &settings, - SLOT(setUpdateReleaseChannel(int))); - connect(&updateNotificationCheckBox, SIGNAL(stateChanged(int)), &settings, - SLOT(setNotifyAboutUpdate(int))); - connect(&newVersionOracleCheckBox, SIGNAL(stateChanged(int)), &settings, - SLOT(setNotifyAboutNewVersion(int))); + connect(&updateReleaseChannelBox, SIGNAL(currentIndexChanged(int)), &settings, SLOT(setUpdateReleaseChannel(int))); + connect(&updateNotificationCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setNotifyAboutUpdate(int))); + connect(&newVersionOracleCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setNotifyAboutNewVersion(int))); connect(&showTipsOnStartup, SIGNAL(clicked(bool)), &settings, SLOT(setShowTipsOnStartup(bool))); auto *personalGrid = new QGridLayout; @@ -949,7 +947,8 @@ void MessagesSettingsPage::storeSettings() void MessagesSettingsPage::actAdd() { bool ok; - QString msg = QInputDialog::getText(this, tr("Add message"), tr("Message:"), QLineEdit::Normal, QString(), &ok); + QString msg = + getTextWithMax(this, tr("Add message"), tr("Message:"), QLineEdit::Normal, QString(), &ok, MAX_TEXT_LENGTH); if (ok) { messageList->addItem(msg); storeSettings(); @@ -961,7 +960,8 @@ void MessagesSettingsPage::actEdit() if (messageList->currentItem()) { QString oldText = messageList->currentItem()->text(); bool ok; - QString msg = QInputDialog::getText(this, tr("Edit message"), tr("Message:"), QLineEdit::Normal, oldText, &ok); + QString msg = + getTextWithMax(this, tr("Edit message"), tr("Message:"), QLineEdit::Normal, oldText, &ok, MAX_TEXT_LENGTH); if (ok) { messageList->currentItem()->setText(msg); storeSettings(); diff --git a/cockatrice/src/gameselector.cpp b/cockatrice/src/gameselector.cpp index 036a1817..53c2c1f6 100644 --- a/cockatrice/src/gameselector.cpp +++ b/cockatrice/src/gameselector.cpp @@ -4,6 +4,7 @@ #include "dlg_creategame.h" #include "dlg_filter_games.h" #include "gamesmodel.h" +#include "gettextwithmax.h" #include "pb/response.pb.h" #include "pb/room_commands.pb.h" #include "pb/serverinfo_game.pb.h" @@ -243,7 +244,7 @@ void GameSelector::actJoin() QString password; if (game.with_password() && !(spectator && !game.spectators_need_password()) && !overrideRestrictions) { bool ok; - password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok); + password = getTextWithMax(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok); if (!ok) return; } diff --git a/cockatrice/src/gettextwithmax.cpp b/cockatrice/src/gettextwithmax.cpp new file mode 100644 index 00000000..200661bb --- /dev/null +++ b/cockatrice/src/gettextwithmax.cpp @@ -0,0 +1,32 @@ +#include "gettextwithmax.h" + +QString getTextWithMax(QWidget *parent, + const QString &title, + const QString &label, + QLineEdit::EchoMode mode, + const QString &text, + bool *ok, + int max, + Qt::WindowFlags flags, + Qt::InputMethodHints inputMethodHints) +{ + auto *dialog = new QInputDialog(parent, flags); + dialog->setWindowTitle(title); + dialog->setLabelText(label); + dialog->setTextValue(text); + dialog->setTextEchoMode(mode); + dialog->setInputMethodHints(inputMethodHints); + + // find the qlineedit that this dialog holds, there should be only one + dialog->findChild()->setMaxLength(max); + + const int ret = dialog->exec(); + if (ok != nullptr) { + *ok = !!ret; + } + if (ret) { + return dialog->textValue(); + } else { + return QString(); + } +} diff --git a/cockatrice/src/gettextwithmax.h b/cockatrice/src/gettextwithmax.h new file mode 100644 index 00000000..84e00a7e --- /dev/null +++ b/cockatrice/src/gettextwithmax.h @@ -0,0 +1,23 @@ +// custom QInputDialog::getText implementation that allows configuration of the max length +#ifndef GETTEXTWITHMAX_H +#define GETTEXTWITHMAX_H + +#include "stringsizes.h" + +#include + +QString getTextWithMax(QWidget *parent, + const QString &title, + const QString &label, + QLineEdit::EchoMode echo = QLineEdit::Normal, + const QString &text = QString(), + bool *ok = nullptr, + int max = MAX_NAME_LENGTH, + Qt::WindowFlags flags = Qt::WindowFlags(), + Qt::InputMethodHints inputMethodHints = Qt::ImhNone); +static inline QString getTextWithMax(QWidget *parent, const QString &title, const QString &label, int max) +{ + return getTextWithMax(parent, title, label, QLineEdit::Normal, QString(), nullptr, max); +} + +#endif // GETTEXTWITHMAX_H diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 9fe823c8..fe193bc5 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -10,6 +10,7 @@ #include "deck_loader.h" #include "dlg_create_token.h" #include "gamescene.h" +#include "gettextwithmax.h" #include "handcounter.h" #include "handzone.h" #include "main.h" @@ -56,6 +57,7 @@ #include "playertarget.h" #include "settingscache.h" #include "stackzone.h" +#include "stringsizes.h" #include "tab_game.h" #include "tablezone.h" #include "thememanager.h" @@ -3034,8 +3036,8 @@ void Player::actSetPT() } bool ok; dialogSemaphore = true; - QString pt = QInputDialog::getText(game, tr("Change power/toughness"), tr("Change stats to:"), QLineEdit::Normal, - oldPT, &ok); + QString pt = + getTextWithMax(game, tr("Change power/toughness"), tr("Change stats to:"), QLineEdit::Normal, oldPT, &ok); dialogSemaphore = false; if (clearCardsToDelete() || !ok) { return; @@ -3141,7 +3143,8 @@ void Player::actSetAnnotation() bool ok; dialogSemaphore = true; QString annotation = QInputDialog::getMultiLineText(game, tr("Set annotation"), - tr("Please enter the new annotation:"), oldAnnotation, &ok); + tr("Please enter the new annotation:"), oldAnnotation, &ok) + .left(MAX_NAME_LENGTH); dialogSemaphore = false; if (clearCardsToDelete() || !ok) { return; diff --git a/cockatrice/src/tab_account.cpp b/cockatrice/src/tab_account.cpp index 4da8dc4b..c845ebb2 100644 --- a/cockatrice/src/tab_account.cpp +++ b/cockatrice/src/tab_account.cpp @@ -10,6 +10,7 @@ #include "pb/session_commands.pb.h" #include "pending_command.h" #include "soundengine.h" +#include "stringsizes.h" #include "userinfobox.h" #include "userlist.h" @@ -60,6 +61,7 @@ TabUserLists::TabUserLists(TabSupervisor *_tabSupervisor, QHBoxLayout *addToBuddyList = new QHBoxLayout; addBuddyEdit = new LineEditUnfocusable; + addBuddyEdit->setMaxLength(MAX_NAME_LENGTH); addBuddyEdit->setPlaceholderText(tr("Add to Buddy List")); connect(addBuddyEdit, SIGNAL(returnPressed()), this, SLOT(addToBuddyList())); QPushButton *addBuddyButton = new QPushButton("Add"); @@ -69,6 +71,7 @@ TabUserLists::TabUserLists(TabSupervisor *_tabSupervisor, QHBoxLayout *addToIgnoreList = new QHBoxLayout; addIgnoreEdit = new LineEditUnfocusable; + addIgnoreEdit->setMaxLength(MAX_NAME_LENGTH); addIgnoreEdit->setPlaceholderText(tr("Add to Ignore List")); connect(addIgnoreEdit, SIGNAL(returnPressed()), this, SLOT(addToIgnoreList())); QPushButton *addIgnoreButton = new QPushButton("Add"); diff --git a/cockatrice/src/tab_admin.cpp b/cockatrice/src/tab_admin.cpp index 9c94272a..010bdfef 100644 --- a/cockatrice/src/tab_admin.cpp +++ b/cockatrice/src/tab_admin.cpp @@ -2,6 +2,7 @@ #include "abstractclient.h" #include "pb/admin_commands.pb.h" +#include "stringsizes.h" #include #include @@ -18,6 +19,7 @@ ShutdownDialog::ShutdownDialog(QWidget *parent) : QDialog(parent) { QLabel *reasonLabel = new QLabel(tr("&Reason for shutdown:")); reasonEdit = new QLineEdit; + reasonEdit->setMaxLength(MAX_TEXT_LENGTH); reasonLabel->setBuddy(reasonEdit); QLabel *minutesLabel = new QLabel(tr("&Time until shutdown (minutes):")); minutesEdit = new QSpinBox; diff --git a/cockatrice/src/tab_deck_editor.cpp b/cockatrice/src/tab_deck_editor.cpp index eb403415..ac72a17d 100644 --- a/cockatrice/src/tab_deck_editor.cpp +++ b/cockatrice/src/tab_deck_editor.cpp @@ -15,6 +15,7 @@ #include "pictureloader.h" #include "pixmapgenerator.h" #include "settingscache.h" +#include "stringsizes.h" #include "tab_supervisor.h" #include "tappedout_interface.h" @@ -81,6 +82,7 @@ void TabDeckEditor::createDeckDock() nameLabel = new QLabel(); nameLabel->setObjectName("nameLabel"); nameEdit = new LineEditUnfocusable; + nameEdit->setMaxLength(MAX_NAME_LENGTH); nameEdit->setObjectName("nameEdit"); nameLabel->setBuddy(nameEdit); connect(nameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(updateName(const QString &))); @@ -798,9 +800,15 @@ bool TabDeckEditor::actSaveDeck() { DeckLoader *const deck = deckModel->getDeckList(); if (deck->getLastRemoteDeckId() != -1) { + QString deckString = deck->writeToString_Native(); + if (deckString.length() > MAX_FILE_LENGTH) { + QMessageBox::critical(this, tr("Error"), tr("Could not save remote deck")); + return false; + } + Command_DeckUpload cmd; cmd.set_deck_id(static_cast(deck->getLastRemoteDeckId())); - cmd.set_deck_list(deck->writeToString_Native().toStdString()); + cmd.set_deck_list(deckString.toStdString()); PendingCommand *pend = AbstractClient::prepareSessionCommand(cmd); connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, diff --git a/cockatrice/src/tab_deck_storage.cpp b/cockatrice/src/tab_deck_storage.cpp index 096faec2..fb52e3a6 100644 --- a/cockatrice/src/tab_deck_storage.cpp +++ b/cockatrice/src/tab_deck_storage.cpp @@ -3,6 +3,7 @@ #include "abstractclient.h" #include "deck_loader.h" #include "decklist.h" +#include "gettextwithmax.h" #include "pb/command_deck_del.pb.h" #include "pb/command_deck_del_dir.pb.h" #include "pb/command_deck_download.pb.h" @@ -17,6 +18,7 @@ #include #include +#include #include #include #include @@ -127,6 +129,24 @@ void TabDeckStorage::retranslateUi() aDeleteRemoteDeck->setText(tr("Delete")); } +QString TabDeckStorage::getTargetPath() const +{ + RemoteDeckList_TreeModel::Node *curRight = serverDirView->getCurrentItem(); + if (curRight == nullptr) + return {}; + auto *dir = dynamic_cast(curRight); + if (dir == nullptr) { + dir = dynamic_cast(curRight->getParent()); + if (dir != nullptr) { + return dir->getPath(); + } else { + return {}; + } + } else { + return dir->getPath(); + } +} + void TabDeckStorage::actOpenLocalDeck() { QModelIndex curLeft = localDirView->selectionModel()->currentIndex(); @@ -146,35 +166,45 @@ void TabDeckStorage::actUpload() QModelIndex curLeft = localDirView->selectionModel()->currentIndex(); if (localDirModel->isDir(curLeft)) return; + QString targetPath = getTargetPath(); + if (targetPath.length() > MAX_NAME_LENGTH) { + qCritical() << "target path to upload to is too long" << targetPath; + return; + } + QString filePath = localDirModel->filePath(curLeft); QFile deckFile(filePath); QFileInfo deckFileInfo(deckFile); + + QString deckString; DeckLoader deck; - if (!deck.loadFromFile(filePath, DeckLoader::CockatriceFormat)) + bool error = !deck.loadFromFile(filePath, DeckLoader::CockatriceFormat); + if (!error) { + deckString = deck.writeToString_Native(); + error = deckString.length() > MAX_FILE_LENGTH; + } + if (error) { + QMessageBox::critical(this, tr("Error"), tr("Invalid deck file")); return; + } + if (deck.getName().isEmpty()) { bool ok; - QString deckName = QInputDialog::getText(this, tr("Enter deck name"), - tr("This decklist does not have a name.\nPlease enter a name:"), - QLineEdit::Normal, deckFileInfo.completeBaseName(), &ok); + QString deckName = + getTextWithMax(this, tr("Enter deck name"), tr("This decklist does not have a name.\nPlease enter a name:"), + QLineEdit::Normal, deckFileInfo.completeBaseName(), &ok); if (!ok) return; if (deckName.isEmpty()) deckName = tr("Unnamed deck"); deck.setName(deckName); + } else { + deck.setName(deck.getName().left(MAX_NAME_LENGTH)); } - QString targetPath; - RemoteDeckList_TreeModel::Node *curRight = serverDirView->getCurrentItem(); - if (!curRight) - return; - if (!dynamic_cast(curRight)) - curRight = curRight->getParent(); - targetPath = dynamic_cast(curRight)->getPath(); - Command_DeckUpload cmd; cmd.set_path(targetPath.toStdString()); - cmd.set_deck_list(deck.writeToString_Native().toStdString()); + cmd.set_deck_list(deckString.toStdString()); PendingCommand *pend = client->prepareSessionCommand(cmd); connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, @@ -184,8 +214,11 @@ void TabDeckStorage::actUpload() void TabDeckStorage::uploadFinished(const Response &r, const CommandContainer &commandContainer) { - if (r.response_code() != Response::RespOk) + if (r.response_code() != Response::RespOk) { + qCritical() << "failed to upload deck:" << r.response_code(); + QMessageBox::critical(this, tr("Error"), tr("Failed to upload deck to server")); return; + } const Response_DeckUpload &resp = r.GetExtension(Response_DeckUpload::ext); const Command_DeckUpload &cmd = commandContainer.session_command(0).GetExtension(Command_DeckUpload::ext); @@ -282,7 +315,13 @@ void TabDeckStorage::downloadFinished(const Response &r, void TabDeckStorage::actNewFolder() { - QString folderName = QInputDialog::getText(this, tr("New folder"), tr("Name of new folder:")); + QString targetPath = getTargetPath(); + int max_length = MAX_NAME_LENGTH - targetPath.length() - 1; // generated length would be path + / + name + + if (max_length < 1) // can't create path that's short enough + return; + + QString folderName = getTextWithMax(this, tr("New folder"), tr("Name of new folder:"), max_length); if (folderName.isEmpty()) return; @@ -291,15 +330,6 @@ void TabDeckStorage::actNewFolder() std::string folder = folderName.toStdString(); std::replace(folder.begin(), folder.end(), '/', '-'); - QString targetPath; - RemoteDeckList_TreeModel::Node *curRight = serverDirView->getCurrentItem(); - if (!curRight) - return; - if (!dynamic_cast(curRight)) - curRight = curRight->getParent(); - RemoteDeckList_TreeModel::DirectoryNode *dir = dynamic_cast(curRight); - targetPath = dir->getPath(); - Command_DeckNewDir cmd; cmd.set_path(targetPath.toStdString()); cmd.set_dir_name(folder); @@ -328,15 +358,19 @@ void TabDeckStorage::actDeleteRemoteDeck() return; RemoteDeckList_TreeModel::DirectoryNode *dir = dynamic_cast(curRight); if (dir) { - QString path = dir->getPath(); - if (path.isEmpty()) + QString targetPath = dir->getPath(); + if (targetPath.isEmpty()) return; + if (targetPath.length() > MAX_NAME_LENGTH) { + qCritical() << "target path to delete is too long" << targetPath; + return; + } if (QMessageBox::warning(this, tr("Delete remote folder"), - tr("Are you sure you want to delete \"%1\"?").arg(path), + tr("Are you sure you want to delete \"%1\"?").arg(targetPath), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; Command_DeckDelDir cmd; - cmd.set_path(path.toStdString()); + cmd.set_path(targetPath.toStdString()); pend = client->prepareSessionCommand(cmd); connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(deleteFolderFinished(Response, CommandContainer))); diff --git a/cockatrice/src/tab_deck_storage.h b/cockatrice/src/tab_deck_storage.h index 1deb0845..2c7d1e72 100644 --- a/cockatrice/src/tab_deck_storage.h +++ b/cockatrice/src/tab_deck_storage.h @@ -27,6 +27,7 @@ private: QGroupBox *leftGroupBox, *rightGroupBox; QAction *aOpenLocalDeck, *aUpload, *aDeleteLocalDeck, *aOpenRemoteDeck, *aDownload, *aNewFolder, *aDeleteRemoteDeck; + QString getTargetPath() const; private slots: void actOpenLocalDeck(); diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index 79d1a5db..b57d0028 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -52,6 +52,7 @@ #include "playerlistwidget.h" #include "replay_timeline_widget.h" #include "settingscache.h" +#include "stringsizes.h" #include "tab_supervisor.h" #include "window_main.h" #include "zoneviewwidget.h" @@ -268,14 +269,21 @@ void DeckViewContainer::loadLocalDeck() QString fileName = dialog.selectedFiles().at(0); DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(fileName); + QString deckString; DeckLoader deck; - if (!deck.loadFromFile(fileName, fmt)) { + + bool error = !deck.loadFromFile(fileName, fmt); + if (!error) { + deckString = deck.writeToString_Native(); + error = deckString.length() > MAX_FILE_LENGTH; + } + if (error) { QMessageBox::critical(this, tr("Error"), tr("The selected file could not be loaded.")); return; } Command_DeckSelect cmd; - cmd.set_deck(deck.writeToString_Native().toStdString()); + cmd.set_deck(deckString.toStdString()); PendingCommand *pend = parentGame->prepareGameCommand(cmd); connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(deckSelectFinished(const Response &))); @@ -1823,6 +1831,7 @@ void TabGame::createMessageDock(bool bReplay) sayLabel = new QLabel; sayEdit = new LineEditCompleter; + sayEdit->setMaxLength(MAX_TEXT_LENGTH); sayLabel->setBuddy(sayEdit); completer = new QCompleter(autocompleteUserList, sayEdit); completer->setCaseSensitivity(Qt::CaseInsensitive); diff --git a/cockatrice/src/tab_logs.cpp b/cockatrice/src/tab_logs.cpp index 9799c8f5..02a8e86f 100644 --- a/cockatrice/src/tab_logs.cpp +++ b/cockatrice/src/tab_logs.cpp @@ -6,6 +6,7 @@ #include "pb/moderator_commands.pb.h" #include "pb/response_viewlog_history.pb.h" #include "pending_command.h" +#include "stringsizes.h" #include #include @@ -148,18 +149,23 @@ void TabLog::createDock() { labelFindUserName = new QLabel(tr("Username: ")); findUsername = new LineEditUnfocusable(""); + findUsername->setMaxLength(MAX_NAME_LENGTH); findUsername->setAlignment(Qt::AlignCenter); labelFindIPAddress = new QLabel(tr("IP Address: ")); findIPAddress = new LineEditUnfocusable(""); + findIPAddress->setMaxLength(MAX_NAME_LENGTH); findIPAddress->setAlignment(Qt::AlignCenter); labelFindGameName = new QLabel(tr("Game Name: ")); findGameName = new LineEditUnfocusable(""); + findGameName->setMaxLength(MAX_NAME_LENGTH); findGameName->setAlignment(Qt::AlignCenter); labelFindGameID = new QLabel(tr("GameID: ")); findGameID = new LineEditUnfocusable(""); + findGameID->setMaxLength(MAX_NAME_LENGTH); findGameID->setAlignment(Qt::AlignCenter); labelMessage = new QLabel(tr("Message: ")); findMessage = new LineEditUnfocusable(""); + findMessage->setMaxLength(MAX_TEXT_LENGTH); findMessage->setAlignment(Qt::AlignCenter); mainRoom = new QCheckBox(tr("Main Room")); diff --git a/cockatrice/src/tab_message.cpp b/cockatrice/src/tab_message.cpp index 92d62d10..d8beed54 100644 --- a/cockatrice/src/tab_message.cpp +++ b/cockatrice/src/tab_message.cpp @@ -10,6 +10,7 @@ #include "pending_command.h" #include "settingscache.h" #include "soundengine.h" +#include "stringsizes.h" #include #include @@ -29,6 +30,7 @@ TabMessage::TabMessage(TabSupervisor *_tabSupervisor, connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString))); connect(chatView, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString))); sayEdit = new LineEditUnfocusable; + sayEdit->setMaxLength(MAX_TEXT_LENGTH); connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage())); QVBoxLayout *vbox = new QVBoxLayout; diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp index 7b125299..f7e2bbf9 100644 --- a/cockatrice/src/tab_room.cpp +++ b/cockatrice/src/tab_room.cpp @@ -15,6 +15,7 @@ #include "pb/serverinfo_room.pb.h" #include "pending_command.h" #include "settingscache.h" +#include "stringsizes.h" #include "tab_account.h" #include "tab_supervisor.h" #include "userlist.h" @@ -60,6 +61,7 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, connect(&SettingsCache::instance(), SIGNAL(chatMentionCompleterChanged()), this, SLOT(actCompleterChanged())); sayLabel = new QLabel; sayEdit = new LineEditCompleter; + sayEdit->setMaxLength(MAX_TEXT_LENGTH); sayLabel->setBuddy(sayEdit); connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage())); diff --git a/cockatrice/src/userlist.cpp b/cockatrice/src/userlist.cpp index bbc6a010..80b62174 100644 --- a/cockatrice/src/userlist.cpp +++ b/cockatrice/src/userlist.cpp @@ -8,6 +8,7 @@ #include "pb/session_commands.pb.h" #include "pending_command.h" #include "pixmapgenerator.h" +#include "stringsizes.h" #include "tab_account.h" #include "tab_supervisor.h" #include "user_context_menu.h" @@ -36,12 +37,15 @@ BanDialog::BanDialog(const ServerInfo_User &info, QWidget *parent) : QDialog(par nameBanCheckBox = new QCheckBox(tr("ban &user name")); nameBanCheckBox->setChecked(true); nameBanEdit = new QLineEdit(QString::fromStdString(info.name())); + nameBanEdit->setMaxLength(MAX_NAME_LENGTH); ipBanCheckBox = new QCheckBox(tr("ban &IP address")); ipBanCheckBox->setChecked(true); ipBanEdit = new QLineEdit(QString::fromStdString(info.address())); + ipBanEdit->setMaxLength(MAX_NAME_LENGTH); idBanCheckBox = new QCheckBox(tr("ban client I&D")); idBanCheckBox->setChecked(true); idBanEdit = new QLineEdit(QString::fromStdString(info.clientid())); + idBanEdit->setMaxLength(MAX_NAME_LENGTH); if (QString::fromStdString(info.clientid()).isEmpty()) idBanCheckBox->setChecked(false); @@ -129,7 +133,9 @@ WarningDialog::WarningDialog(const QString userName, const QString clientID, QWi setAttribute(Qt::WA_DeleteOnClose); descriptionLabel = new QLabel(tr("Which warning would you like to send?")); nameWarning = new QLineEdit(userName); + nameWarning->setMaxLength(MAX_NAME_LENGTH); warnClientID = new QLineEdit(clientID); + warnClientID->setMaxLength(MAX_NAME_LENGTH); warningOption = new QComboBox(); warningOption->addItem(""); diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index 482029a7..4098f77b 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -31,6 +31,7 @@ #include "dlg_tip_of_the_day.h" #include "dlg_update.h" #include "dlg_viewlog.h" +#include "gettextwithmax.h" #include "localclient.h" #include "localserver.h" #include "localserverinterface.h" @@ -426,10 +427,10 @@ void MainWindow::loginError(Response::ResponseCode r, break; case Response::RespAccountNotActivated: { bool ok = false; - QString token = QInputDialog::getText(this, tr("Account activation"), - tr("Your account has not been activated yet.\nYou need to provide " - "the activation token received in the activation email."), - QLineEdit::Normal, QString(), &ok); + QString token = getTextWithMax(this, tr("Account activation"), + tr("Your account has not been activated yet.\nYou need to provide " + "the activation token received in the activation email."), + QLineEdit::Normal, QString(), &ok); if (ok && !token.isEmpty()) { client->activateToServer(token); return; diff --git a/common/server_player.cpp b/common/server_player.cpp index 83267978..d2cd8f05 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -79,6 +79,7 @@ #include "server_database_interface.h" #include "server_game.h" #include "server_room.h" +#include "stringsizes.h" #include #include @@ -214,8 +215,8 @@ void Server_Player::setupZones() const QList &sideboardPlan = deck->getCurrentSideboardPlan(); for (const auto &m : sideboardPlan) { - const QString startZone = QString::fromStdString(m.start_zone()); - const QString targetZone = QString::fromStdString(m.target_zone()); + const QString startZone = nameFromStdString(m.start_zone()); + const QString targetZone = nameFromStdString(m.target_zone()); Server_CardZone *start, *target; if (startZone == DECK_ZONE_MAIN) { @@ -234,7 +235,7 @@ void Server_Player::setupZones() } for (int j = 0; j < start->getCards().size(); ++j) { - if (start->getCards()[j]->getName() == QString::fromStdString(m.card_name())) { + if (start->getCards()[j]->getName() == nameFromStdString(m.card_name())) { Server_Card *card = start->getCard(j, nullptr, true); target->insertCard(card, -1, 0); break; @@ -715,7 +716,7 @@ Server_Player::cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &r return r; } } else { - newDeck = new DeckList(QString::fromStdString(cmd.deck())); + newDeck = new DeckList(fileFromStdString(cmd.deck())); } if (!newDeck) { @@ -928,7 +929,7 @@ Server_Player::cmdGameSay(const Command_GameSay &cmd, ResponseContainer & /*rc*/ game->getRoom()->getServer()->getDatabaseInterface()->logMessage( userInfo->id(), QString::fromStdString(userInfo->name()), QString::fromStdString(userInfo->address()), - QString::fromStdString(cmd.message()), Server_DatabaseInterface::MessageTargetGame, game->getGameId(), + textFromStdString(cmd.message()), Server_DatabaseInterface::MessageTargetGame, game->getGameId(), game->getDescription()); return Response::RespOk; @@ -1092,7 +1093,7 @@ Server_Player::cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer & /*rc if (!startPlayer) { return Response::RespNameNotFound; } - Server_CardZone *startZone = startPlayer->getZones().value(QString::fromStdString(cmd.start_zone())); + Server_CardZone *startZone = startPlayer->getZones().value(nameFromStdString(cmd.start_zone())); if (!startZone) { return Response::RespNameNotFound; } @@ -1105,7 +1106,7 @@ Server_Player::cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer & /*rc if (!targetPlayer) { return Response::RespNameNotFound; } - Server_CardZone *targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + Server_CardZone *targetZone = targetPlayer->getZones().value(nameFromStdString(cmd.target_zone())); if (!targetZone) { return Response::RespNameNotFound; } @@ -1136,7 +1137,7 @@ Server_Player::cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer & /*rc return Response::RespContextError; } - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + Server_CardZone *zone = zones.value(nameFromStdString(cmd.zone())); if (!zone) { return Response::RespNameNotFound; } @@ -1165,7 +1166,7 @@ Server_Player::cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer & /*rc event.set_face_down(faceDown); ges.enqueueGameEvent(event, playerId); - QString ptString = QString::fromStdString(cmd.pt()); + QString ptString = nameFromStdString(cmd.pt()); if (!ptString.isEmpty() && !faceDown) { setCardAttrHelper(ges, playerId, zone->getName(), card->getId(), AttrPT, ptString); } @@ -1187,7 +1188,7 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & return Response::RespContextError; } - Server_CardZone *startzone = zones.value(QString::fromStdString(cmd.start_zone())); + Server_CardZone *startzone = zones.value(nameFromStdString(cmd.start_zone())); if (!startzone) { return Response::RespNameNotFound; } @@ -1210,7 +1211,7 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & return Response::RespContextError; } if (targetPlayer) { - targetzone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + targetzone = targetPlayer->getZones().value(nameFromStdString(cmd.target_zone())); } if (targetzone) { // This is currently enough to make sure cards don't get attached to a card that is not on the table. @@ -1305,12 +1306,12 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer return Response::RespContextError; } - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + Server_CardZone *zone = zones.value(nameFromStdString(cmd.zone())); if (!zone) { return Response::RespNameNotFound; } - QString cardName = QString::fromStdString(cmd.card_name()); + QString cardName = nameFromStdString(cmd.card_name()); int xCoord = cmd.x(); int yCoord = cmd.y(); if (zone->hasCoords()) { @@ -1325,9 +1326,9 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer auto *card = new Server_Card(cardName, newCardId(), xCoord, yCoord); card->moveToThread(thread()); - card->setPT(QString::fromStdString(cmd.pt())); - card->setColor(QString::fromStdString(cmd.color())); - card->setAnnotation(QString::fromStdString(cmd.annotation())); + card->setPT(nameFromStdString(cmd.pt())); + card->setColor(nameFromStdString(cmd.color())); + card->setAnnotation(nameFromStdString(cmd.annotation())); card->setDestroyOnZoneChange(cmd.destroy_on_zone_change()); zone->insertCard(card, xCoord, yCoord); @@ -1379,12 +1380,12 @@ Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer if (!startPlayer || !targetPlayer) { return Response::RespNameNotFound; } - QString startZoneName = QString::fromStdString(cmd.start_zone()); + QString startZoneName = nameFromStdString(cmd.start_zone()); Server_CardZone *startZone = startPlayer->getZones().value(startZoneName); bool playerTarget = !cmd.has_target_zone(); Server_CardZone *targetZone = nullptr; if (!playerTarget) { - targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + targetZone = targetPlayer->getZones().value(nameFromStdString(cmd.target_zone())); } if (!startZone || (!targetZone && !playerTarget)) { return Response::RespNameNotFound; @@ -1481,8 +1482,8 @@ Server_Player::cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer return Response::RespContextError; } - return setCardAttrHelper(ges, playerId, QString::fromStdString(cmd.zone()), cmd.card_id(), cmd.attribute(), - QString::fromStdString(cmd.attr_value())); + return setCardAttrHelper(ges, playerId, nameFromStdString(cmd.zone()), cmd.card_id(), cmd.attribute(), + nameFromStdString(cmd.attr_value())); } Response::ResponseCode @@ -1499,7 +1500,7 @@ Server_Player::cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseCont return Response::RespContextError; } - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + Server_CardZone *zone = zones.value(nameFromStdString(cmd.zone())); if (!zone) { return Response::RespNameNotFound; } @@ -1538,7 +1539,7 @@ Server_Player::cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseCont return Response::RespContextError; } - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + Server_CardZone *zone = zones.value(nameFromStdString(cmd.zone())); if (!zone) { return Response::RespNameNotFound; } @@ -1607,7 +1608,7 @@ Server_Player::cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContai return Response::RespContextError; } - auto *c = new Server_Counter(newCounterId(), QString::fromStdString(cmd.counter_name()), cmd.counter_color(), + auto *c = new Server_Counter(newCounterId(), nameFromStdString(cmd.counter_name()), cmd.counter_color(), cmd.radius(), cmd.value()); addCounter(c); @@ -1739,7 +1740,7 @@ Server_Player::cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, G if (!otherPlayer) { return Response::RespNameNotFound; } - Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); + Server_CardZone *zone = otherPlayer->getZones().value(nameFromStdString(cmd.zone_name())); if (!zone) { return Response::RespNameNotFound; } @@ -1824,7 +1825,7 @@ Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer if (!otherPlayer) return Response::RespNameNotFound; } - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); + Server_CardZone *zone = zones.value(nameFromStdString(cmd.zone_name())); if (!zone) { return Response::RespNameNotFound; } @@ -1922,7 +1923,7 @@ Response::ResponseCode Server_Player::cmdChangeZoneProperties(const Command_Chan ResponseContainer & /* rc */, GameEventStorage &ges) { - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); + Server_CardZone *zone = zones.value(nameFromStdString(cmd.zone_name())); if (!zone) { return Response::RespNameNotFound; } diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index af37836a..a560d84e 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -20,6 +20,7 @@ #include "server_game.h" #include "server_player.h" #include "server_room.h" +#include "stringsizes.h" #include #include @@ -440,16 +441,16 @@ Response::ResponseCode Server_ProtocolHandler::cmdPing(const Command_Ping & /*cm Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd, ResponseContainer &rc) { - QString userName = QString::fromStdString(cmd.user_name()).simplified(); - QString clientId = QString::fromStdString(cmd.clientid()).simplified(); - QString clientVersion = QString::fromStdString(cmd.clientver()).simplified(); + QString userName = nameFromStdString(cmd.user_name()).simplified(); + QString clientId = nameFromStdString(cmd.clientid()).simplified(); + QString clientVersion = nameFromStdString(cmd.clientver()).simplified(); QString password; bool needsHash = false; if (cmd.has_password()) { - password = QString::fromStdString(cmd.password()); + password = nameFromStdString(cmd.password()); needsHash = true; } else { - password = QString::fromStdString(cmd.hashed_password()); + password = nameFromStdString(cmd.hashed_password()); } if (userInfo != 0) { @@ -461,8 +462,9 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd QMap receivedClientFeatures; QMap missingClientFeatures; - for (int i = 0; i < cmd.clientfeatures().size(); ++i) { - receivedClientFeatures.insert(QString::fromStdString(cmd.clientfeatures(i)).simplified(), false); + int featureCount = qMin(cmd.clientfeatures().size(), MAX_NAME_LENGTH); + for (int i = 0; i < featureCount; ++i) { + receivedClientFeatures.insert(nameFromStdString(cmd.clientfeatures(i)).simplified(), false); } missingClientFeatures = @@ -563,7 +565,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message QReadLocker locker(&server->clientsLock); - QString receiver = QString::fromStdString(cmd.user_name()); + QString receiver = nameFromStdString(cmd.user_name()); Server_AbstractUserInterface *userInterface = server->findUser(receiver); if (!userInterface) { return Response::RespNameNotFound; @@ -577,7 +579,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message Event_UserMessage event; event.set_sender_name(userInfo->name()); - event.set_receiver_name(cmd.user_name()); + event.set_receiver_name(receiver.toStdString()); event.set_message(cmd.message()); SessionEvent *se = prepareSessionEvent(event); @@ -608,7 +610,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(const Command_G Server_Room *room = roomIterator.next().value(); room->gamesLock.lockForRead(); room->getInfo(*re->add_room_list(), false, true); - QListIterator gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name()))); + QListIterator gameIterator(room->getGamesOfUser(nameFromStdString(cmd.user_name()))); while (gameIterator.hasNext()) re->add_game_list()->CopyFrom(gameIterator.next()); room->gamesLock.unlock(); @@ -624,7 +626,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdGetUserInfo(const Command_GetU if (authState == NotLoggedIn) return Response::RespLoginNeeded; - QString userName = QString::fromStdString(cmd.user_name()); + QString userName = nameFromStdString(cmd.user_name()); Response_GetUserInfo *re = new Response_GetUserInfo; if (userName.isEmpty()) re->mutable_user_info()->CopyFrom(*userInfo); @@ -765,11 +767,11 @@ bool Server_ProtocolHandler::addSaidMessageSize(int size) Response::ResponseCode Server_ProtocolHandler::cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer & /*rc*/) { - QString msg = QString::fromStdString(cmd.message()); - - if (!addSaidMessageSize(msg.size())) { + if (!addSaidMessageSize(cmd.message().size())) { return Response::RespChatFlood; } + QString msg = QString::fromStdString(cmd.message()); + msg.replace(QChar('\n'), QChar(' ')); room->say(QString::fromStdString(userInfo->name()), msg); @@ -807,18 +809,19 @@ Server_ProtocolHandler::cmdCreateGame(const Command_CreateGame &cmd, Server_Room } QList gameTypes; - for (int i = cmd.game_type_ids_size() - 1; i >= 0; --i) { // FIXME: why are these iterated in reverse? + int gameTypeCount = qMin(cmd.game_type_ids().size(), MAX_NAME_LENGTH); + for (int i = 0; i < gameTypeCount; ++i) { // the client actually only sends one of these gameTypes.append(cmd.game_type_ids(i)); } - QString description = QString::fromStdString(cmd.description()).left(60); + QString description = nameFromStdString(cmd.description()); // When server doesn't permit registered users to exist, do not honor only-reg setting bool onlyRegisteredUsers = cmd.only_registered() && (server->permitUnregisteredUsers()); - Server_Game *game = new Server_Game( - copyUserInfo(false), gameId, description, QString::fromStdString(cmd.password()), cmd.max_players(), gameTypes, - cmd.only_buddies(), onlyRegisteredUsers, cmd.spectators_allowed(), cmd.spectators_need_password(), - cmd.spectators_can_talk(), cmd.spectators_see_everything(), room); + Server_Game *game = new Server_Game(copyUserInfo(false), gameId, description, nameFromStdString(cmd.password()), + cmd.max_players(), gameTypes, cmd.only_buddies(), onlyRegisteredUsers, + cmd.spectators_allowed(), cmd.spectators_need_password(), + cmd.spectators_can_talk(), cmd.spectators_see_everything(), room); game->addPlayer(this, rc, asSpectator, asJudge, false); room->addGame(game); diff --git a/common/server_room.cpp b/common/server_room.cpp index 82cb0ae2..84428690 100644 --- a/common/server_room.cpp +++ b/common/server_room.cpp @@ -11,6 +11,7 @@ #include "pb/serverinfo_room.pb.h" #include "server_game.h" #include "server_protocolhandler.h" +#include "stringsizes.h" #include #include @@ -264,9 +265,8 @@ Response::ResponseCode Server_Room::processJoinGameCommand(const Command_JoinGam QMutexLocker gameLocker(&game->gameMutex); - Response::ResponseCode result = - game->checkJoin(userInterface->getUserInfo(), QString::fromStdString(cmd.password()), cmd.spectator(), - cmd.override_restrictions(), cmd.join_as_judge()); + Response::ResponseCode result = game->checkJoin(userInterface->getUserInfo(), nameFromStdString(cmd.password()), + cmd.spectator(), cmd.override_restrictions(), cmd.join_as_judge()); if (result == Response::RespOk) game->addPlayer(userInterface, rc, cmd.spectator(), cmd.join_as_judge()); diff --git a/common/stringsizes.h b/common/stringsizes.h new file mode 100644 index 00000000..56fba626 --- /dev/null +++ b/common/stringsizes.h @@ -0,0 +1,29 @@ +// max sizes of strings used in the protocol +#ifndef STRINGSIZES_H +#define STRINGSIZES_H + +#include +#include + +// max size for short strings, like names and things that are generally a single phrase +constexpr int MAX_NAME_LENGTH = 0xff; +// max size for chat messages and text contents +constexpr int MAX_TEXT_LENGTH = 0xfff; +// max size for deck files and pictures +constexpr int MAX_FILE_LENGTH = 0xfffff; // about a megabyte + +// optimized functions to get qstrings that are at most that long +static inline QString nameFromStdString(const std::string &_string) +{ + return QString::fromUtf8(_string.data(), std::min(int(_string.size()), MAX_NAME_LENGTH)); +} +static inline QString textFromStdString(const std::string &_string) +{ + return QString::fromUtf8(_string.data(), std::min(int(_string.size()), MAX_TEXT_LENGTH)); +} +static inline QString fileFromStdString(const std::string &_string) +{ + return QString::fromUtf8(_string.data(), std::min(int(_string.size()), MAX_FILE_LENGTH)); +} + +#endif // STRINGSIZES_H diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index d6baea7a..47fbe8fb 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -64,6 +64,7 @@ #include "server_response_containers.h" #include "server_room.h" #include "settingscache.h" +#include "stringsizes.h" #include "version_string.h" #include @@ -73,6 +74,7 @@ #include #include #include +#include #include #include @@ -249,8 +251,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAddToList(const Command if (authState != PasswordRight) return Response::RespFunctionNotAllowed; - QString list = QString::fromStdString(cmd.list()); - QString user = QString::fromStdString(cmd.user_name()); + QString list = nameFromStdString(cmd.list()); + QString user = nameFromStdString(cmd.user_name()); if ((list != "buddy") && (list != "ignore")) return Response::RespContextError; @@ -290,8 +292,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRemoveFromList(const Co if (authState != PasswordRight) return Response::RespFunctionNotAllowed; - QString list = QString::fromStdString(cmd.list()); - QString user = QString::fromStdString(cmd.user_name()); + QString list = nameFromStdString(cmd.list()); + QString user = nameFromStdString(cmd.user_name()); if ((list != "buddy") && (list != "ignore")) return Response::RespContextError; @@ -421,15 +423,20 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckNewDir(const Comman sqlInterface->checkSql(); - int folderId = getDeckPathId(QString::fromStdString(cmd.path())); + QString path = nameFromStdString(cmd.path()); + int folderId = getDeckPathId(path); if (folderId == -1) return Response::RespNameNotFound; + QString name = nameFromStdString(cmd.dir_name()); + if (path.length() + name.length() + 1 > MAX_NAME_LENGTH) + return Response::RespContextError; // do not allow creation of paths that would be too long to delete + QSqlQuery *query = sqlInterface->prepareQuery( "insert into {prefix}_decklist_folders (id_parent, id_user, name) values(:id_parent, :id_user, :name)"); query->bindValue(":id_parent", folderId); query->bindValue(":id_user", userInfo->id()); - query->bindValue(":name", QString::fromStdString(cmd.dir_name())); + query->bindValue(":name", name); if (!sqlInterface->execSqlQuery(query)) return Response::RespContextError; return Response::RespOk; @@ -478,7 +485,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckDelDir(const Comman sqlInterface->checkSql(); - int basePathId = getDeckPathId(QString::fromStdString(cmd.path())); + int basePathId = getDeckPathId(nameFromStdString(cmd.path())); if ((basePathId == -1) || (basePathId == 0)) return Response::RespNameNotFound; deckDelDirHelper(basePathId); @@ -517,15 +524,17 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckUpload(const Comman sqlInterface->checkSql(); - QString deckStr = QString::fromStdString(cmd.deck_list()); - DeckList deck(deckStr); + QString deckStr = fileFromStdString(cmd.deck_list()); + DeckList deck; + if (!deck.loadFromString_Native(deckStr)) + return Response::RespContextError; QString deckName = deck.getName(); if (deckName.isEmpty()) deckName = "Unnamed deck"; if (cmd.has_path()) { - int folderId = getDeckPathId(QString::fromStdString(cmd.path())); + int folderId = getDeckPathId(nameFromStdString(cmd.path())); if (folderId == -1) return Response::RespNameNotFound; @@ -724,21 +733,21 @@ Response::ResponseCode AbstractServerSocketInterface::cmdGetLogHistory(const Com { QList messageList; - QString userName = QString::fromStdString(cmd.user_name()); - QString ipAddress = QString::fromStdString(cmd.ip_address()); - QString gameName = QString::fromStdString(cmd.game_name()); - QString gameID = QString::fromStdString(cmd.game_id()); - QString message = QString::fromStdString(cmd.message()); + QString userName = nameFromStdString(cmd.user_name()); + QString ipAddress = nameFromStdString(cmd.ip_address()); + QString gameName = nameFromStdString(cmd.game_name()); + QString gameID = nameFromStdString(cmd.game_id()); + QString message = textFromStdString(cmd.message()); bool chatType = false; bool gameType = false; bool roomType = false; for (int i = 0; i != cmd.log_location_size(); ++i) { - if (QString::fromStdString(cmd.log_location(i)).simplified() == "room") + if (nameFromStdString(cmd.log_location(i)).simplified() == "room") roomType = true; - if (QString::fromStdString(cmd.log_location(i)).simplified() == "game") + if (nameFromStdString(cmd.log_location(i)).simplified() == "game") gameType = true; - if (QString::fromStdString(cmd.log_location(i)).simplified() == "chat") + if (nameFromStdString(cmd.log_location(i)).simplified() == "chat") chatType = true; } @@ -801,7 +810,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdGetBanHistory(const Com ResponseContainer &rc) { QList banList; - QString userName = QString::fromStdString(cmd.user_name()); + QString userName = nameFromStdString(cmd.user_name()); Response_BanHistory *re = new Response_BanHistory; QListIterator banIterator(sqlInterface->getUserBanHistory(userName)); @@ -825,8 +834,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdGetWarnList(const Comma foreach (QString warning, warningsList) { re->add_warning(warning.toStdString()); } - re->set_user_name(cmd.user_name()); - re->set_user_clientid(cmd.user_clientid()); + re->set_user_name(nameFromStdString(cmd.user_name()).toStdString()); + re->set_user_clientid(nameFromStdString(cmd.user_clientid()).toStdString()); rc.setResponseExtension(re); return Response::RespOk; } @@ -835,7 +844,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdGetWarnHistory(const Co ResponseContainer &rc) { QList warnList; - QString userName = QString::fromStdString(cmd.user_name()); + QString userName = nameFromStdString(cmd.user_name()); Response_WarnHistory *re = new Response_WarnHistory; QListIterator warnIterator(sqlInterface->getUserWarnHistory(userName)); @@ -859,16 +868,16 @@ Response::ResponseCode AbstractServerSocketInterface::cmdWarnUser(const Command_ return Response::RespInternalError; } - QString userName = QString::fromStdString(cmd.user_name()).simplified(); - QString warningReason = QString::fromStdString(cmd.reason()).simplified(); - QString clientID = QString::fromStdString(cmd.clientid()).simplified(); + QString userName = nameFromStdString(cmd.user_name()).simplified(); + QString warningReason = textFromStdString(cmd.reason()).simplified(); + QString clientId = nameFromStdString(cmd.clientid()).simplified(); QString sendingModerator = QString::fromStdString(userInfo->name()).simplified(); int amountRemove = cmd.remove_messages(); if (amountRemove != 0) { removeSaidMessages(userName, amountRemove); } - if (sqlInterface->addWarning(userName, sendingModerator, warningReason, clientID)) { + if (sqlInterface->addWarning(userName, sendingModerator, warningReason, clientId)) { servatrice->clientsLock.lockForRead(); AbstractServerSocketInterface *user = static_cast(server->getUsers().value(userName)); @@ -878,7 +887,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdWarnUser(const Command_ if (user != nullptr) { Event_NotifyUser event; event.set_type(Event_NotifyUser::WARNING); - event.set_warning_reason(cmd.reason()); + event.set_warning_reason(warningReason.toStdString()); SessionEvent *se = user->prepareSessionEvent(event); user->sendProtocolItem(*se); delete se; @@ -904,11 +913,12 @@ Response::ResponseCode AbstractServerSocketInterface::cmdBanFromServer(const Com if (!sqlInterface->checkSql()) return Response::RespInternalError; - QString userName = QString::fromStdString(cmd.user_name()).simplified(); - QString address = QString::fromStdString(cmd.address()).simplified(); - QString clientID = QString::fromStdString(cmd.clientid()).simplified(); + QString userName = nameFromStdString(cmd.user_name()).simplified(); + QString address = nameFromStdString(cmd.address()).simplified(); + QString clientId = nameFromStdString(cmd.clientid()).simplified(); + QString visibleReason = textFromStdString(cmd.visible_reason()); - if (userName.isEmpty() && address.isEmpty() && clientID.isEmpty()) + if (userName.isEmpty() && address.isEmpty() && clientId.isEmpty()) return Response::RespOk; int amountRemove = cmd.remove_messages(); @@ -927,9 +937,9 @@ Response::ResponseCode AbstractServerSocketInterface::cmdBanFromServer(const Com query->bindValue(":ip_address", address); query->bindValue(":id_admin", userInfo->id()); query->bindValue(":minutes", minutes); - query->bindValue(":reason", QString::fromStdString(cmd.reason())); - query->bindValue(":visible_reason", QString::fromStdString(cmd.visible_reason())); - query->bindValue(":client_id", QString::fromStdString(cmd.clientid())); + query->bindValue(":reason", textFromStdString(cmd.reason())); + query->bindValue(":visible_reason", visibleReason); + query->bindValue(":client_id", nameFromStdString(cmd.clientid())); sqlInterface->execSqlQuery(query); servatrice->clientsLock.lockForRead(); @@ -943,10 +953,10 @@ Response::ResponseCode AbstractServerSocketInterface::cmdBanFromServer(const Com userList.append(user); } - if (userName.isEmpty() && address.isEmpty() && (!clientID.isEmpty())) { + if (userName.isEmpty() && address.isEmpty() && (!clientId.isEmpty())) { QSqlQuery *clientIdQuery = sqlInterface->prepareQuery("select name from {prefix}_users where clientid = :client_id"); - clientIdQuery->bindValue(":client_id", QString::fromStdString(cmd.clientid())); + clientIdQuery->bindValue(":client_id", nameFromStdString(cmd.clientid())); sqlInterface->execSqlQuery(clientIdQuery); if (!sqlInterface->execSqlQuery(clientIdQuery)) { qDebug("ClientID username ban lookup failed: SQL Error"); @@ -966,7 +976,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdBanFromServer(const Com Event_ConnectionClosed event; event.set_reason(Event_ConnectionClosed::BANNED); if (cmd.has_visible_reason()) - event.set_reason_str(cmd.visible_reason()); + event.set_reason_str(visibleReason.toStdString()); if (minutes) event.set_end_time(QDateTime::currentDateTime().addSecs(60 * minutes).toTime_t()); for (int i = 0; i < userList.size(); ++i) { @@ -985,22 +995,20 @@ Response::ResponseCode AbstractServerSocketInterface::cmdBanFromServer(const Com notificationMessage.append("\n Username: " + userName); if (!address.isEmpty()) notificationMessage.append("\n IP Address: " + address); - if (!clientID.isEmpty()) - notificationMessage.append("\n Client ID: " + clientID); + if (!clientId.isEmpty()) + notificationMessage.append("\n Client ID: " + clientId); notificationMessage.append("\n Length: " + QString::number(minutes) + " minute(s)"); - notificationMessage.append("\n Internal Reason: " + QString::fromStdString(cmd.reason())); - notificationMessage.append("\n Visible Reason: " + QString::fromStdString(cmd.visible_reason())); + notificationMessage.append("\n Internal Reason: " + textFromStdString(cmd.reason())); + notificationMessage.append("\n Visible Reason: " + textFromStdString(cmd.visible_reason())); sendServerMessage(moderator.simplified(), notificationMessage); } return Response::RespOk; } -QPair AbstractServerSocketInterface::parseEmailAddress(const std::string &stdEmailAddress) +QPair AbstractServerSocketInterface::parseEmailAddress(const QString &emailAddress) { - QString emailAddress = QString::fromStdString(stdEmailAddress); - // https://www.regular-expressions.info/email.html static const QRegularExpression emailRegex(R"(^([A-Z0-9._%+-]+)@([A-Z0-9.-]+\.[A-Z]{2,})$)", QRegularExpression::CaseInsensitiveOption); @@ -1039,23 +1047,22 @@ QPair AbstractServerSocketInterface::parseEmailAddress(const s Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc) { - QString userName = QString::fromStdString(cmd.user_name()); - QString clientId = QString::fromStdString(cmd.clientid()); + QString userName = nameFromStdString(cmd.user_name()); + QString clientId = nameFromStdString(cmd.clientid()); qDebug() << "Got register command: " << userName; bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool(); if (!registrationEnabled) { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "Server functionality disabled", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "Server functionality disabled", false); return Response::RespRegistrationDisabled; } const QString emailBlackList = servatrice->getEmailBlackList(); const QString emailWhiteList = servatrice->getEmailWhiteList(); - auto parsedEmailAddress = parseEmailAddress(cmd.email()); + auto parsedEmailAddress = parseEmailAddress(nameFromStdString(cmd.email())); const QString emailUser = parsedEmailAddress.first; const QString emailDomain = parsedEmailAddress.second; #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) @@ -1074,9 +1081,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C // If a whitelist exists, ensure the email address domain IS in the whitelist if (!emailWhiteListFilters.isEmpty() && !emailWhiteListFilters.contains(emailDomain, Qt::CaseInsensitive)) { if (servatrice->getEnableRegistrationAudit()) { - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "Email used is not whitelisted", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "Email used is not whitelisted", false); } auto *re = new Response_Register; re->set_denied_reason_str( @@ -1088,9 +1094,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C // If a blacklist exists, ensure the email address domain is NOT in the blacklist if (!emailBlackListFilters.isEmpty() && emailBlackListFilters.contains(emailDomain, Qt::CaseInsensitive)) { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "Email used is blacklisted", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "Email used is blacklisted", false); return Response::RespEmailBlackListed; } @@ -1099,9 +1104,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C QString errorString; if (!sqlInterface->usernameIsValid(userName, errorString)) { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "Username is invalid", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "Username is invalid", false); Response_Register *re = new Response_Register; re->set_denied_reason_str(errorString.toStdString()); @@ -1111,18 +1115,16 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C if (userName.toLower().simplified() == "servatrice") { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "Username is invalid", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "Username is invalid", false); return Response::RespUsernameInvalid; } if (sqlInterface->userExists(userName)) { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "Username already exists", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "Username already exists", false); return Response::RespUserAlreadyExists; } @@ -1131,9 +1133,9 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C if (servatrice->getMaxAccountsPerEmail() > 0 && sqlInterface->checkNumberOfUserAccounts(emailAddress) >= servatrice->getMaxAccountsPerEmail()) { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "Too many usernames registered with this email address", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "Too many usernames registered with this email address", + false); return Response::RespTooManyRequests; } @@ -1142,9 +1144,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C int banSecondsRemaining; if (sqlInterface->checkUserIsBanned(this->getAddress(), userName, clientId, banReason, banSecondsRemaining)) { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "User is banned", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "User is banned", false); Response_Register *re = new Response_Register; re->set_denied_reason_str(banReason.toStdString()); @@ -1156,22 +1157,21 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C if (tooManyRegistrationAttempts(this->getAddress())) { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "Too many registration attempts from this ip address", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "Too many registration attempts from this ip address", + false); return Response::RespTooManyRequests; } - QString realName = QString::fromStdString(cmd.real_name()); - QString country = QString::fromStdString(cmd.country()); - QString password = QString::fromStdString(cmd.password()); + QString realName = nameFromStdString(cmd.real_name()); + QString country = nameFromStdString(cmd.country()); + QString password = nameFromStdString(cmd.password()); if (!isPasswordLongEnough(password.length())) { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "Password is too short", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "Password is too short", false); return Response::RespPasswordTooShort; } @@ -1190,25 +1190,22 @@ Response::ResponseCode AbstractServerSocketInterface::cmdRegisterAccount(const C return Response::RespRegistrationFailed; if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "", true); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "", true); return Response::RespRegistrationAcceptedNeedsActivation; } else { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "", true); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "", true); return Response::RespRegistrationAccepted; } } else { if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "REGISTER_ACCOUNT", - "Unknown reason for failure", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "REGISTER_ACCOUNT", "Unknown reason for failure", false); return Response::RespRegistrationFailed; } @@ -1224,28 +1221,28 @@ bool AbstractServerSocketInterface::tooManyRegistrationAttempts(const QString &i Response::ResponseCode AbstractServerSocketInterface::cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /*rc*/) { - QString userName = QString::fromStdString(cmd.user_name()); - QString token = QString::fromStdString(cmd.token()); - QString clientID = QString::fromStdString(cmd.clientid()); + QString userName = nameFromStdString(cmd.user_name()); + QString token = nameFromStdString(cmd.token()); + QString clientId = nameFromStdString(cmd.clientid()); - if (clientID.isEmpty()) - clientID = "UNKNOWN"; + if (clientId.isEmpty()) + clientId = "UNKNOWN"; if (sqlInterface->activateUser(userName, token)) { - qDebug() << "Accepted activation for user" << QString::fromStdString(cmd.user_name()); + qDebug() << "Accepted activation for user" << userName; if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - clientID, "ACTIVATE_ACCOUNT", "", true); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "ACTIVATE_ACCOUNT", "", true); return Response::RespActivationAccepted; } else { - qDebug() << "Failed activation for user" << QString::fromStdString(cmd.user_name()); + qDebug() << "Failed activation for user" << userName; if (servatrice->getEnableRegistrationAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - clientID, "ACTIVATE_ACCOUNT", - "Failed to activate account, incorrect activation token", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "ACTIVATE_ACCOUNT", "Failed to activate account, incorrect activation token", + false); return Response::RespActivationFailed; } @@ -1257,9 +1254,9 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountEdit(const Comma if (authState != PasswordRight) return Response::RespFunctionNotAllowed; - QString realName = QString::fromStdString(cmd.real_name()); - QString emailAddress = QString::fromStdString(cmd.email()); - QString country = QString::fromStdString(cmd.country()); + QString realName = nameFromStdString(cmd.real_name()); + QString emailAddress = nameFromStdString(cmd.email()); + QString country = nameFromStdString(cmd.country()); QString userName = QString::fromStdString(userInfo->name()); @@ -1272,9 +1269,9 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountEdit(const Comma if (!sqlInterface->execSqlQuery(query)) return Response::RespInternalError; - userInfo->set_real_name(cmd.real_name()); - userInfo->set_email(cmd.email()); - userInfo->set_country(cmd.country()); + userInfo->set_real_name(realName.toStdString()); + userInfo->set_email(emailAddress.toStdString()); + userInfo->set_country(country.toStdString()); return Response::RespOk; } @@ -1285,7 +1282,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountImage(const Comm if (authState != PasswordRight) return Response::RespFunctionNotAllowed; - QByteArray image(cmd.image().c_str(), cmd.image().length()); + size_t length = qMin(cmd.image().length(), (size_t)MAX_FILE_LENGTH); + QByteArray image(cmd.image().c_str(), length); int id = userInfo->id(); QSqlQuery *query = sqlInterface->prepareQuery("update {prefix}_users set avatar_bmp=:image where id=:id"); @@ -1294,7 +1292,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountImage(const Comm if (!sqlInterface->execSqlQuery(query)) return Response::RespInternalError; - userInfo->set_avatar_bmp(cmd.image().c_str(), cmd.image().length()); + userInfo->set_avatar_bmp(cmd.image().c_str(), length); return Response::RespOk; } @@ -1304,8 +1302,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountPassword(const C if (authState != PasswordRight) return Response::RespFunctionNotAllowed; - QString oldPassword = QString::fromStdString(cmd.old_password()); - QString newPassword = QString::fromStdString(cmd.new_password()); + QString oldPassword = nameFromStdString(cmd.old_password()); + QString newPassword = nameFromStdString(cmd.new_password()); if (!isPasswordLongEnough(newPassword.length())) return Response::RespPasswordTooShort; @@ -1321,8 +1319,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAccountPassword(const C Response::ResponseCode AbstractServerSocketInterface::cmdForgotPasswordRequest(const Command_ForgotPasswordRequest &cmd, ResponseContainer &rc) { - const QString userName = QString::fromStdString(cmd.user_name()); - const QString clientId = QString::fromStdString(cmd.clientid()); + const QString userName = nameFromStdString(cmd.user_name()); + const QString clientId = nameFromStdString(cmd.clientid()); qDebug() << "Received reset password request from user: " << userName; @@ -1404,35 +1402,33 @@ Response::ResponseCode AbstractServerSocketInterface::cmdForgotPasswordReset(con ResponseContainer &rc) { Q_UNUSED(rc); - qDebug() << "Received reset password reset from user: " << QString::fromStdString(cmd.user_name()); + QString userName = nameFromStdString(cmd.user_name()); + QString clientId = nameFromStdString(cmd.clientid()); + qDebug() << "Received reset password reset from user: " << userName; - if (!sqlInterface->doesForgotPasswordExist(QString::fromStdString(cmd.user_name()))) { + if (!sqlInterface->doesForgotPasswordExist(userName)) { if (servatrice->getEnableForgotPasswordAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET", - "Request does not exist for user", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "PASSWORD_RESET", "Request does not exist for user", false); return Response::RespFunctionNotAllowed; } - if (!sqlInterface->validateTableColumnStringData("{prefix}_users", "token", QString::fromStdString(cmd.user_name()), - QString::fromStdString(cmd.token()))) { + if (!sqlInterface->validateTableColumnStringData("{prefix}_users", "token", userName, + nameFromStdString(cmd.token()))) { if (servatrice->getEnableForgotPasswordAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET", - "Failed token validation", false); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), userName.simplified(), + "PASSWORD_RESET", "Failed token validation", false); return Response::RespFunctionNotAllowed; } - if (sqlInterface->changeUserPassword(QString::fromStdString(cmd.user_name()), "", - QString::fromStdString(cmd.new_password()), true)) { + if (sqlInterface->changeUserPassword(userName, "", nameFromStdString(cmd.new_password()), true)) { if (servatrice->getEnableForgotPasswordAudit()) - sqlInterface->addAuditRecord(QString::fromStdString(cmd.user_name()).simplified(), this->getAddress(), - QString::fromStdString(cmd.clientid()).simplified(), "PASSWORD_RESET", "", - true); + sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), + "PASSWORD_RESET", "", true); - sqlInterface->removeForgotPassword(QString::fromStdString(cmd.user_name())); + sqlInterface->removeForgotPassword(nameFromStdString(cmd.user_name())); return Response::RespOk; } @@ -1443,8 +1439,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdForgotPasswordChallenge(const Command_ForgotPasswordChallenge &cmd, ResponseContainer &rc) { - const QString userName = QString::fromStdString(cmd.user_name()); - const QString clientId = QString::fromStdString(cmd.clientid()); + const QString userName = nameFromStdString(cmd.user_name()); + const QString clientId = nameFromStdString(cmd.clientid()); qDebug() << "Received reset password challenge from user: " << userName; @@ -1465,7 +1461,7 @@ AbstractServerSocketInterface::cmdForgotPasswordChallenge(const Command_ForgotPa } if (!sqlInterface->validateTableColumnStringData("{prefix}_users", "email", userName, - QString::fromStdString(cmd.email()))) { + nameFromStdString(cmd.email()))) { if (servatrice->getEnableForgotPasswordAudit()) { sqlInterface->addAuditRecord(userName.simplified(), this->getAddress(), clientId.simplified(), "PASSWORD_RESET_CHALLENGE", "Failed to answer email challenge question", @@ -1484,7 +1480,7 @@ AbstractServerSocketInterface::cmdForgotPasswordChallenge(const Command_ForgotPa Response::ResponseCode AbstractServerSocketInterface::cmdRequestPasswordSalt(const Command_RequestPasswordSalt &cmd, ResponseContainer &rc) { - const QString userName = QString::fromStdString(cmd.user_name()); + const QString userName = nameFromStdString(cmd.user_name()); QString passwordSalt = sqlInterface->getUserSalt(userName); if (passwordSalt.isEmpty()) { if (server->getRegOnlyServerEnabled()) { @@ -1514,7 +1510,7 @@ AbstractServerSocketInterface::cmdUpdateServerMessage(const Command_UpdateServer Response::ResponseCode AbstractServerSocketInterface::cmdShutdownServer(const Command_ShutdownServer &cmd, ResponseContainer & /*rc*/) { - QMetaObject::invokeMethod(server, "scheduleShutdown", Q_ARG(QString, QString::fromStdString(cmd.reason())), + QMetaObject::invokeMethod(server, "scheduleShutdown", Q_ARG(QString, textFromStdString(cmd.reason())), Q_ARG(int, cmd.minutes())); return Response::RespOk; } @@ -1535,8 +1531,7 @@ bool AbstractServerSocketInterface::addAdminFlagToUser(const QString &userName, query->bindValue(":adminlevel", flag); query->bindValue(":username", userName); if (!sqlInterface->execSqlQuery(query)) { - logger->logMessage( - QString::fromStdString("Failed to promote user %1: %2").arg(userName).arg(query->lastError().text())); + logger->logMessage(QString("Failed to promote user %1: %2").arg(userName).arg(query->lastError().text())); return false; } @@ -1560,8 +1555,7 @@ bool AbstractServerSocketInterface::removeAdminFlagFromUser(const QString &userN query->bindValue(":adminlevel", flag); query->bindValue(":username", userName); if (!sqlInterface->execSqlQuery(query)) { - logger->logMessage( - QString::fromStdString("Failed to demote user %1: %2").arg(userName).arg(query->lastError().text())); + logger->logMessage(QString("Failed to demote user %1: %2").arg(userName).arg(query->lastError().text())); return false; } @@ -1586,7 +1580,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAdjustMod(const Command ResponseContainer & /*rc*/) { - QString userName = QString::fromStdString(cmd.user_name()); + QString userName = nameFromStdString(cmd.user_name()); if (cmd.has_should_be_mod()) { if (cmd.should_be_mod()) { diff --git a/servatrice/src/serversocketinterface.h b/servatrice/src/serversocketinterface.h index 502985fa..55d452ea 100644 --- a/servatrice/src/serversocketinterface.h +++ b/servatrice/src/serversocketinterface.h @@ -130,7 +130,7 @@ private: bool removeAdminFlagFromUser(const QString &user, int flag); bool isPasswordLongEnough(const int passwordLength); - static QPair parseEmailAddress(const std::string &stdEmailAddress); + static QPair parseEmailAddress(const QString &emailAddress); void removeSaidMessages(const QString &userName, int amount); public: