ChannelLogger + Karka + all DB plugins: Sanitize channel names when used in filenames.

This commit is contained in:
Valentin Lorentz 2019-09-06 20:15:18 +02:00
parent b166f4ad5c
commit 88524beada
6 changed files with 47 additions and 6 deletions

View File

@ -35,6 +35,7 @@ import time
import supybot.conf as conf
import supybot.world as world
import supybot.ircdb as ircdb
import supybot.utils as utils
import supybot.irclib as irclib
import supybot.utils.minisix as minisix
import supybot.ircmsgs as ircmsgs
@ -95,9 +96,10 @@ class ChannelLogger(callbacks.Plugin):
def getLogName(self, channel):
if self.registryValue('rotateLogs', channel):
return '%s.%s.log' % (channel, self.logNameTimestamp(channel))
name = '%s.%s.log' % (channel, self.logNameTimestamp(channel))
else:
return '%s.log' % channel
name = '%s.log' % channel
return utils.file.sanitizeName(name)
def getLogDir(self, irc, channel):
channel = self.normalizeChannel(irc, channel)

View File

@ -32,5 +32,13 @@ from supybot.test import *
class ChannelLoggerTestCase(PluginTestCase):
plugins = ('ChannelLogger',)
def testLogDir(self):
self.assertEqual(
self.irc.getCallback('ChannelLogger').getLogName('#foo'),
'#foo.log')
self.assertEqual(
self.irc.getCallback('ChannelLogger').getLogName('#f/../oo'),
'#f..oo.log')
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -60,14 +60,15 @@ def DB(filename, types):
def junk(*args, **kwargs):
pass
return junk
filename = conf.supybot.directories.data.dirize(filename)
def MakeDB(*args, **kwargs):
for type in conf.supybot.databases():
# Can't do this because Python sucks. Go ahead, try it!
# filename = '.'.join([filename, type, 'db'])
fn = '.'.join([filename, type, 'db'])
fn = utils.file.sanitizeName(fn)
path = conf.supybot.directories.data.dirize(fn)
try:
return types[type](fn, *args, **kwargs)
return types[type](path, *args, **kwargs)
except KeyError:
continue
raise NoSuitableDatabase(types.keys())
@ -78,11 +79,11 @@ def makeChannelFilename(filename, channel=None, dirname=None):
filename = os.path.basename(filename)
channelSpecific = conf.supybot.databases.plugins.channelSpecific
channel = channelSpecific.getChannelLink(channel)
channel = ircutils.toLower(channel)
channel = utils.file.sanitizeName(ircutils.toLower(channel))
if dirname is None:
dirname = conf.supybot.directories.data.dirize(channel)
if not os.path.exists(dirname):
os.makedirs(dirname)
os.makedirs(dirname)
return os.path.join(dirname, filename)
def getChannel(channel):

View File

@ -37,6 +37,16 @@ import os.path
from . import crypt
def sanitizeName(filename):
"""Removes / from filenames and escapes them if they are '.' or '..'."""
filename = filename.replace('/', '')
if filename == '.':
return '_'
elif filename == '..':
return '__'
else:
return filename
def contents(filename):
with open(filename) as fd:
return fd.read()

View File

@ -29,6 +29,22 @@
###
from supybot.test import *
import supybot.conf as conf
import supybot.irclib as irclib
import supybot.plugins as plugins
class PluginsTestCase(SupyTestCase):
def testMakeChannelFilename(self):
self.assertEqual(
plugins.makeChannelFilename('dir', '#foo'),
conf.supybot.directories.data() + '/#foo/dir')
self.assertEqual(
plugins.makeChannelFilename('dir', '#f/../oo'),
conf.supybot.directories.data() + '/#f..oo/dir')
self.assertEqual(
plugins.makeChannelFilename('dir', '/./'),
conf.supybot.directories.data() + '/_/dir')
self.assertEqual(
plugins.makeChannelFilename('dir', '/../'),
conf.supybot.directories.data() + '/__/dir')

View File

@ -504,6 +504,10 @@ class FileTest(SupyTestCase):
self.failUnless(utils.file.mktemp())
self.failUnless(utils.file.mktemp())
def testSanitizeName(self):
self.assertEqual(utils.file.sanitizeName('#foo'), '#foo')
self.assertEqual(utils.file.sanitizeName('#f/../oo'), '#f..oo')
class NetTest(SupyTestCase):
def testEmailRe(self):