Merge pull request #2340 from PhenomRetroShare/Fix_SIGSEGV_InMessage

Fix SIGSEGV in Messages changing junk, start or read status.
This commit is contained in:
defnax 2021-02-19 18:35:54 +01:00 committed by GitHub
commit ddec32ac12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 130 additions and 61 deletions

View file

@ -680,28 +680,93 @@ void RsMessageModel::setMsgReadStatus(const QModelIndex& i,bool read_status)
if(!i.isValid()) if(!i.isValid())
return ; return ;
preMods(); preMods();
rsMsgs->MessageRead(i.data(MsgIdRole).toString().toStdString(),!read_status); rsMsgs->MessageRead(i.data(MsgIdRole).toString().toStdString(),!read_status);
emit dataChanged(i.sibling(i.row(),0),i.sibling(i.row(),COLUMN_THREAD_NB_COLUMNS-1)); emit dataChanged(i,i);
}
void RsMessageModel::setMsgsReadStatus(const QModelIndexList& mil,bool read_status)
{
//Get all msgId before changing model else Index are invalid and provoc SIGSEGV
QVector<std::string> list;
int start = rowCount(), stop = 0;
for(auto& it : mil)
if (it.isValid())
{
list.append(it.data(MsgIdRole).toString().toStdString());
start = std::min(start, it.row());
stop = std::max(stop, it.row());
}
preMods();
for(auto& it : list)
rsMsgs->MessageRead(it,!read_status);
emit dataChanged(createIndex(start,0),createIndex(stop,RsMessageModel::columnCount()-1));
} }
void RsMessageModel::setMsgStar(const QModelIndex& i,bool star) void RsMessageModel::setMsgStar(const QModelIndex& i,bool star)
{ {
preMods(); if(!i.isValid())
rsMsgs->MessageStar(i.data(MsgIdRole).toString().toStdString(),star); return ;
emit dataChanged(i.sibling(i.row(),0),i.sibling(i.row(),COLUMN_THREAD_NB_COLUMNS-1)); preMods();
rsMsgs->MessageStar(i.data(MsgIdRole).toString().toStdString(),star);
emit dataChanged(i,i);
}
void RsMessageModel::setMsgsStar(const QModelIndexList& mil,bool star)
{
//Get all msgId before changing model else Index are invalid and provoc SIGSEGV
QVector<std::string> list;
int start = rowCount(), stop = 0;
for(auto& it : mil)
if (it.isValid())
{
list.append(it.data(MsgIdRole).toString().toStdString());
start = std::min(start, it.row());
stop = std::max(stop, it.row());
}
preMods();
for(auto& it : list)
rsMsgs->MessageStar(it,star);
emit dataChanged(createIndex(start,0),createIndex(stop,RsMessageModel::columnCount()-1));
} }
void RsMessageModel::setMsgJunk(const QModelIndex& i,bool junk) void RsMessageModel::setMsgJunk(const QModelIndex& i,bool junk)
{ {
preMods(); if(!i.isValid())
rsMsgs->MessageJunk(i.data(MsgIdRole).toString().toStdString(),junk); return ;
emit dataChanged(i.sibling(i.row(),0),i.sibling(i.row(),COLUMN_THREAD_NB_COLUMNS-1)); preMods();
rsMsgs->MessageJunk(i.data(MsgIdRole).toString().toStdString(),junk);
emit dataChanged(i,i);
} }
void RsMessageModel::setMsgsJunk(const QModelIndexList& mil,bool junk)
{
//Get all msgId before changing model else Index are invalid and provoc SIGSEGV
QVector<std::string> list;
int start = rowCount(), stop = 0;
for(auto& it : mil)
if (it.isValid())
{
list.append(it.data(MsgIdRole).toString().toStdString());
start = std::min(start, it.row());
stop = std::max(stop, it.row());
}
preMods();
for(auto& it : list)
rsMsgs->MessageJunk(it,junk);
emit dataChanged(createIndex(start,0),createIndex(stop,RsMessageModel::columnCount()-1));
}
QModelIndex RsMessageModel::getIndexOfMessage(const std::string& mid) const QModelIndex RsMessageModel::getIndexOfMessage(const std::string& mid) const
{ {

View file

@ -150,8 +150,11 @@ public:
// control over message flags and so on. This is handled by the model because it will allow it to update accordingly // control over message flags and so on. This is handled by the model because it will allow it to update accordingly
void setMsgReadStatus(const QModelIndex& i, bool read_status); void setMsgReadStatus(const QModelIndex& i, bool read_status);
void setMsgStar(const QModelIndex& index,bool star) ; void setMsgsReadStatus(const QModelIndexList& mil, bool read_status);
void setMsgJunk(const QModelIndex& index,bool junk) ; void setMsgStar(const QModelIndex& i,bool star) ;
void setMsgsStar(const QModelIndexList& mil,bool star) ;
void setMsgJunk(const QModelIndex& i,bool junk) ;
void setMsgsJunk(const QModelIndexList& mil,bool junk) ;
public slots: public slots:
void updateMessages(); void updateMessages();

View file

@ -98,30 +98,34 @@
class MessageSortFilterProxyModel: public QSortFilterProxyModel class MessageSortFilterProxyModel: public QSortFilterProxyModel
{ {
public: public:
MessageSortFilterProxyModel(QObject *parent = NULL): QSortFilterProxyModel(parent), m_sortingEnabled(false) MessageSortFilterProxyModel(QObject *parent = NULL)
{ : QSortFilterProxyModel(parent), m_sortingEnabled(false)
setDynamicSortFilter(false); // causes crashes when true {
} setDynamicSortFilter(false); // causes crashes when true
}
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override
{
return left.data(RsMessageModel::SortRole) < right.data(RsMessageModel::SortRole) ;
}
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
{
return sourceModel()->index(source_row,0,source_parent).data(RsMessageModel::FilterRole).toString() == RsMessageModel::FilterString ;
}
void sort( int column, Qt::SortOrder order = Qt::AscendingOrder ) override void sort( int column, Qt::SortOrder order = Qt::AscendingOrder ) override
{ {
if(m_sortingEnabled) if(m_sortingEnabled)
return QSortFilterProxyModel::sort(column,order) ; return QSortFilterProxyModel::sort(column,order) ;
}
void setSortingEnabled(bool b) { m_sortingEnabled = b ; }
protected:
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override
{
return sourceModel()->data(left, RsMessageModel::SortRole) < sourceModel()->data(right, RsMessageModel::SortRole) ;
}
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
{
//No need Column as Model filter check with filter selection
return sourceModel()->index(source_row,0,source_parent).data(RsMessageModel::FilterRole).toString() == RsMessageModel::FilterString ;
} }
void setSortingEnabled(bool b) { m_sortingEnabled = b ; }
private: private:
bool m_sortingEnabled; bool m_sortingEnabled;
}; };
/** Constructor */ /** Constructor */
@ -260,7 +264,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
<p>Generally, you may use messages to recommend files to your friends by pasting file links, \ <p>Generally, you may use messages to recommend files to your friends by pasting file links, \
or recommend friend nodes to other friend nodes, in order to strengthen your network, or send feedback \ or recommend friend nodes to other friend nodes, in order to strengthen your network, or send feedback \
to a channel's owner.</p> \ to a channel's owner.</p> \
").arg(QString::number(2*S)).arg(QString::number(S)) ; ").arg(QString::number(2*S), QString::number(S)) ;
registerHelpButton(ui.helpButton,help_str,"MessagesDialog") ; registerHelpButton(ui.helpButton,help_str,"MessagesDialog") ;
@ -538,14 +542,14 @@ int MessagesDialog::getSelectedMsgCount (QList<QModelIndex> *items, QList<QModel
{ {
QModelIndexList qmil = ui.messageTreeWidget->selectionModel()->selectedRows(); QModelIndexList qmil = ui.messageTreeWidget->selectionModel()->selectedRows();
if (items) items->clear(); if (items) items->clear();
if (itemsRead) itemsRead->clear(); if (itemsRead) itemsRead->clear();
if (itemsUnread) itemsUnread->clear(); if (itemsUnread) itemsUnread->clear();
if (itemsStar) itemsStar->clear(); if (itemsStar) itemsStar->clear();
if (itemsJunk) itemsJunk->clear(); if (itemsJunk) itemsJunk->clear();
foreach(const QModelIndex& m, qmil) foreach(const QModelIndex& m, qmil)
{ {
if (items) if (items)
items->append(m); items->append(m);
@ -556,9 +560,12 @@ int MessagesDialog::getSelectedMsgCount (QList<QModelIndex> *items, QList<QModel
if (itemsStar && m.data(RsMessageModel::MsgFlagsRole).toInt() & RS_MSG_STAR) if (itemsStar && m.data(RsMessageModel::MsgFlagsRole).toInt() & RS_MSG_STAR)
itemsStar->append(m); itemsStar->append(m);
}
return qmil.size(); if (itemsJunk && m.data(RsMessageModel::MsgFlagsRole).toInt() & RS_MSG_SPAM)
itemsJunk->append(m);
}
return qmil.size();
} }
bool MessagesDialog::isMessageRead(const QModelIndex& real_index) bool MessagesDialog::isMessageRead(const QModelIndex& real_index)
@ -653,7 +660,7 @@ void MessagesDialog::messageTreeWidgetCustomPopupMenu(QPoint /*point*/)
action = contextMnu.addAction(tr("Mark as Junk")); action = contextMnu.addAction(tr("Mark as Junk"));
action->setCheckable(true); action->setCheckable(true);
action->setChecked(itemsStar.size()); action->setChecked(itemsJunk.size());
connect(action, SIGNAL(triggered(bool)), this, SLOT(markWithJunk(bool))); connect(action, SIGNAL(triggered(bool)), this, SLOT(markWithJunk(bool)));
contextMnu.addSeparator(); contextMnu.addSeparator();
@ -1008,40 +1015,34 @@ void MessagesDialog::updateCurrentMessage()
void MessagesDialog::markAsRead() void MessagesDialog::markAsRead()
{ {
QList<QModelIndex> itemsUnread; QModelIndexList lst = ui.messageTreeWidget->selectionModel()->selectedRows();
getSelectedMsgCount (NULL, NULL, &itemsUnread, NULL, NULL);
foreach(const QModelIndex& index,itemsUnread) mMessageModel->setMsgsReadStatus(lst,true);
mMessageModel->setMsgReadStatus(index,true);
updateMessageSummaryList(); updateMessageSummaryList();
} }
void MessagesDialog::markAsUnread() void MessagesDialog::markAsUnread()
{ {
QList<QModelIndex> itemsRead; QModelIndexList lst = ui.messageTreeWidget->selectionModel()->selectedRows();
getSelectedMsgCount (NULL, &itemsRead, NULL, NULL, NULL);
foreach(const QModelIndex& index,itemsRead) mMessageModel->setMsgsReadStatus(lst,false);
mMessageModel->setMsgReadStatus(index,false);
updateMessageSummaryList(); updateMessageSummaryList();
} }
void MessagesDialog::markWithStar(bool checked) void MessagesDialog::markWithStar(bool checked)
{ {
QModelIndexList lst = ui.messageTreeWidget->selectionModel()->selectedRows(); QModelIndexList lst = ui.messageTreeWidget->selectionModel()->selectedRows();
foreach(const QModelIndex& index,lst) mMessageModel->setMsgsStar(lst, checked);
mMessageModel->setMsgStar(index, checked);
} }
void MessagesDialog::markWithJunk(bool checked) void MessagesDialog::markWithJunk(bool checked)
{ {
QModelIndexList lst = ui.messageTreeWidget->selectionModel()->selectedRows(); QModelIndexList lst = ui.messageTreeWidget->selectionModel()->selectedRows();
foreach(const QModelIndex& index,lst) mMessageModel->setMsgsJunk(lst, checked);
mMessageModel->setMsgJunk(index, checked);
} }
void MessagesDialog::insertMsgTxtAndFiles(const QModelIndex& proxy_index) void MessagesDialog::insertMsgTxtAndFiles(const QModelIndex& proxy_index)

View file

@ -48,9 +48,9 @@ public:
/** Default Destructor */ /** Default Destructor */
~MessagesDialog(); ~MessagesDialog();
virtual QIcon iconPixmap() const { return QIcon(IMAGE_MESSAGES) ; } //MainPage virtual QIcon iconPixmap() const override { return QIcon(IMAGE_MESSAGES) ; } //MainPage
virtual QString pageName() const { return tr("Mail") ; } //MainPage virtual QString pageName() const override { return tr("Mail") ; } //MainPage
virtual QString helpText() const { return ""; } //MainPage virtual QString helpText() const override { return ""; } //MainPage
// replaced by shortcut // replaced by shortcut
// virtual void keyPressEvent(QKeyEvent *) ; // virtual void keyPressEvent(QKeyEvent *) ;
@ -60,8 +60,8 @@ public:
void setTextColorInbox(QColor color) { mTextColorInbox = color; } void setTextColorInbox(QColor color) { mTextColorInbox = color; }
protected: protected:
virtual UserNotify *createUserNotify(QObject *parent) override; virtual UserNotify *createUserNotify(QObject *parent) override; //MainPage
bool eventFilter(QObject *obj, QEvent *ev); bool eventFilter(QObject *obj, QEvent *ev) override; //MainPage
int getSelectedMessages(QList<QString>& mid); int getSelectedMessages(QList<QString>& mid);
public slots: public slots: