mirror of
https://github.com/znc/znc.git
synced 2026-05-03 03:52:33 +02:00
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:
21
src/Chan.cpp
21
src/Chan.cpp
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user