diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-09-15 16:24:17 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-09-15 16:24:17 +0000 |
commit | bdc4f4009052df3a6e7a0532ba6b2859b34cf9e2 (patch) | |
tree | af8ee49a3bbc26ef609af429c16641ffe80c311f /src | |
parent | 6a4b9410c9d4b6ab243bee4cc4ed6380baf948d3 (diff) |
Fix quoting in permchannels DB, discovered by jackmcbarn (could result in command execution)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11726 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src')
-rw-r--r-- | src/modules/m_permchannels.cpp | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/src/modules/m_permchannels.cpp b/src/modules/m_permchannels.cpp index e27b2cf9c..a0b2adea2 100644 --- a/src/modules/m_permchannels.cpp +++ b/src/modules/m_permchannels.cpp @@ -43,16 +43,43 @@ static bool WriteDatabase() } // Now, let's write. - Channel *c = NULL; - for (chan_hash::const_iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++) { - c = i->second; + Channel* chan = i->second; + if (!chan->IsModeSet('P')) + continue; - if (c->IsModeSet('P')) + char line[1024]; + const char* items[] = { - fprintf(f, "<permchannels channel=\"%s\" topic=\"%s\" modes=\"%s\">\n", c->name.c_str(), c->topic.c_str(), c->ChanModes(true)); + "<permchannels channel=", + chan->name.c_str(), + " topic=", + chan->topic.c_str(), + " modes=", + chan->ChanModes(true), + ">\n" + }; + + int lpos = 0, item = 0, ipos = 0; + while (lpos < 1022 && item < 7) + { + char c = items[item][ipos++]; + if (c == 0) + { + // end of this string; hop to next string, insert a quote + item++; + ipos = 0; + c = '"'; + } + else if (c == '\\' || c == '"') + { + line[lpos++] = '\\'; + } + line[lpos++] = c; } + line[--lpos] = 0; + fputs(line, f); } int write_error = 0; |