Fix crash when parsing incorrect channel modes sent by server.

Sometimes certain servers don't send a argument for modes which it
declared as ones which need an argument.

No released version is affected.

Close #1684
This commit is contained in:
Alexey Sokolov
2019-11-07 08:36:41 +00:00
parent b8b62a14ab
commit 16c849daac
2 changed files with 26 additions and 8 deletions

View File

@@ -300,7 +300,8 @@ void CChan::OnWho(const CString& sNick, const CString& sIdent,
}
}
void CChan::ModeChange(const CString& sModes, const VCString& vsModes, const CNick* pOpNick) {
void CChan::ModeChange(const CString& sModes, const VCString& vsModes,
const CNick* pOpNick) {
bool bAdd = true;
/* Try to find a CNick* from this channel so that pOpNick->HasPerm()
@@ -319,6 +320,13 @@ void CChan::ModeChange(const CString& sModes, const VCString& vsModes, const CNi
}
VCString::const_iterator argIter = vsModes.begin();
const CString sEmpty;
auto nextArg = [&]() -> const CString& {
if (argIter == vsModes.end()) {
return sEmpty;
}
return *argIter++;
};
for (unsigned int a = 0; a < sModes.size(); a++) {
const char& cMode = sModes[a];
@@ -327,11 +335,10 @@ void CChan::ModeChange(const CString& sModes, const VCString& vsModes, const CNi
} else if (cMode == '-') {
bAdd = false;
} else if (m_pNetwork->GetIRCSock()->IsPermMode(cMode)) {
CString sArg = *argIter++;
const CString& sArg = nextArg();
CNick* pNick = FindNick(sArg);
if (pNick) {
char cPerm =
m_pNetwork->GetIRCSock()->GetPermFromMode(cMode);
char cPerm = m_pNetwork->GetIRCSock()->GetPermFromMode(cMode);
if (cPerm) {
bool bNoChange = (pNick->HasPerm(cPerm) == bAdd);
@@ -389,16 +396,16 @@ void CChan::ModeChange(const CString& sModes, const VCString& vsModes, const CNi
switch (m_pNetwork->GetIRCSock()->GetModeType(cMode)) {
case CIRCSock::ListArg:
bList = true;
sArg = *argIter++;
sArg = nextArg();
break;
case CIRCSock::HasArg:
sArg = *argIter++;
sArg = nextArg();
break;
case CIRCSock::NoArg:
break;
case CIRCSock::ArgWhenSet:
if (bAdd) {
sArg = *argIter++;
sArg = nextArg();
}
break;