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

View File

@ -32,5 +32,13 @@ from supybot.test import *
class ChannelLoggerTestCase(PluginTestCase): class ChannelLoggerTestCase(PluginTestCase):
plugins = ('ChannelLogger',) 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: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

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

View File

@ -37,6 +37,16 @@ import os.path
from . import crypt 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): def contents(filename):
with open(filename) as fd: with open(filename) as fd:
return fd.read() return fd.read()

View File

@ -29,6 +29,22 @@
### ###
from supybot.test import * from supybot.test import *
import supybot.conf as conf
import supybot.irclib as irclib import supybot.irclib as irclib
import supybot.plugins as plugins 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())
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): class NetTest(SupyTestCase):
def testEmailRe(self): def testEmailRe(self):