mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-12-25 12:12:54 +01:00
Fix bypassed cache invalidation checks, causing '@config reload' to be partially ignored
`registry.Value.__call__()` is a wrapper around access to `registry.Value.value`, that checks if the value was set before the latest call to `registry.open_registry`; and updates the `value` if needed. When accessing `registry.Value.value` directly, this cache can't be invalidated, causing the old value to still be used, until the next call to `registry.Value.__call__()`.
This commit is contained in:
parent
c0d033ff84
commit
baa8cda814
@ -85,7 +85,7 @@ class String256(registry.String):
|
||||
return s * (1024//len(s))
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
return self()
|
||||
|
||||
conf.registerGlobalValue(BadWords, 'nastyChars',
|
||||
String256('!@#&', _("""Determines what characters will replace bad words; a
|
||||
|
@ -50,6 +50,7 @@ class Smileys(registry.Value):
|
||||
self.setValue(L)
|
||||
|
||||
def setValue(self, v):
|
||||
self._lastModified = registry.monotonic_time()
|
||||
self.s = ' '.join(v)
|
||||
self.value = re.compile('|'.join(map(re.escape, v)))
|
||||
|
||||
|
@ -499,12 +499,12 @@ class Config(callbacks.Plugin):
|
||||
netgroup = group.get(':' + network.network)
|
||||
changroup = netgroup.get(channel)
|
||||
checkCanSetValue(irc, msg, changroup)
|
||||
changroup._setValue(netgroup.value, inherited=True)
|
||||
changroup._setValue(netgroup(), inherited=True)
|
||||
|
||||
# reset group.#channel
|
||||
changroup = group.get(channel)
|
||||
checkCanSetValue(irc, msg, changroup)
|
||||
changroup._setValue(group.value, inherited=True)
|
||||
changroup._setValue(group(), inherited=True)
|
||||
|
||||
irc.replySuccess()
|
||||
channel = wrap(channel, [
|
||||
@ -523,7 +523,7 @@ class Config(callbacks.Plugin):
|
||||
# reset group.#channel
|
||||
changroup = group.get(':' + network.network)
|
||||
checkCanSetValue(irc, msg, changroup)
|
||||
changroup._setValue(group.value, inherited=True)
|
||||
changroup._setValue(group(), inherited=True)
|
||||
|
||||
irc.replySuccess()
|
||||
network = wrap(network, ['networkIrc', 'settableConfigVar'])
|
||||
|
@ -107,6 +107,24 @@ class ConfigTestCase(ChannelPluginTestCase):
|
||||
r'supybot.reply.whenAddressedBy.strings.#test and '
|
||||
r'supybot.reply.whenAddressedBy.strings.\:test.#test')
|
||||
|
||||
def testReload(self):
|
||||
old_password = 'pjfoizjoifjfoii_old'
|
||||
new_password = 'pjfoizjoifjfoii_new'
|
||||
with conf.supybot.networks.test.password.context(old_password):
|
||||
self.assertResponse('config conf.supybot.networks.test.password',
|
||||
old_password)
|
||||
filename = conf.supybot.directories.conf.dirize('Config_testReload.conf')
|
||||
registry.close(conf.supybot, filename)
|
||||
|
||||
content = open(filename).read()
|
||||
assert old_password in content
|
||||
open(filename, 'wt').write(content.replace(old_password,
|
||||
new_password))
|
||||
|
||||
registry.open_registry(filename)
|
||||
self.assertResponse('config conf.supybot.networks.test.password',
|
||||
new_password)
|
||||
|
||||
def testDefault(self):
|
||||
self.assertNotError('config default '
|
||||
'supybot.replies.genericNoCapability')
|
||||
|
@ -43,7 +43,7 @@ class IrcLogLevel(log.ValidLogLevel):
|
||||
minimumLevel = logging.INFO
|
||||
def setValue(self, v):
|
||||
log.ValidLogLevel.setValue(self, v)
|
||||
_ircHandler.setLevel(self.value)
|
||||
_ircHandler.setLevel(self())
|
||||
|
||||
class ValidChannelOrNick(registry.String):
|
||||
"""Value must be a valid channel or a valid nick."""
|
||||
|
@ -791,7 +791,7 @@ class ValidQuotes(registry.Value):
|
||||
super(ValidQuotes, self).setValue(v)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.value)
|
||||
return str(self())
|
||||
|
||||
registerChannelValue(supybot.commands, 'quotes',
|
||||
ValidQuotes('"', _("""Determines what characters are valid for quoting
|
||||
@ -1030,7 +1030,7 @@ class Databases(registry.SpaceSeparatedListOfStrings):
|
||||
return v
|
||||
|
||||
def serialize(self):
|
||||
return ' '.join(self.value)
|
||||
return ' '.join(self())
|
||||
|
||||
registerGlobalValue(supybot, 'databases',
|
||||
Databases([], _("""Determines what databases are available for use. If this
|
||||
@ -1466,7 +1466,7 @@ class SocketTimeout(registry.PositiveInteger):
|
||||
if v < supybot.drivers.poll() or v < 1:
|
||||
self.error()
|
||||
registry.PositiveInteger.setValue(self, v)
|
||||
socket.setdefaulttimeout(self.value)
|
||||
socket.setdefaulttimeout(self())
|
||||
|
||||
registerGlobalValue(supybot, 'defaultSocketTimeout',
|
||||
SocketTimeout(10, _("""Determines what the default timeout for socket
|
||||
|
@ -77,12 +77,12 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||
self.writeCheckTime = None
|
||||
self.nextReconnectTime = None
|
||||
self.resetDelay()
|
||||
if self.networkGroup.get('ssl').value and 'ssl' not in globals():
|
||||
if self.networkGroup.get('ssl')() and 'ssl' not in globals():
|
||||
drivers.log.error('The Socket driver can not connect to SSL '
|
||||
'servers for your Python version.')
|
||||
self.ssl = False
|
||||
else:
|
||||
self.ssl = self.networkGroup.get('ssl').value
|
||||
self.ssl = self.networkGroup.get('ssl')()
|
||||
self.connect()
|
||||
|
||||
def getDelay(self):
|
||||
|
@ -1325,11 +1325,11 @@ class DefaultCapabilities(SpaceSeparatedListOfCapabilities):
|
||||
# it's still an improvement, raising the bar for potential crackers.
|
||||
def setValue(self, v, allowDefaultOwner=conf.allowDefaultOwner):
|
||||
registry.SpaceSeparatedListOfStrings.setValue(self, v)
|
||||
if '-owner' not in self.value and not allowDefaultOwner:
|
||||
if '-owner' not in self() and not allowDefaultOwner:
|
||||
print('*** You must run supybot with the --allow-default-owner')
|
||||
print('*** option in order to allow a default capability of owner.')
|
||||
print('*** Don\'t do that, it\'s dumb.')
|
||||
self.value.add('-owner')
|
||||
self().add('-owner')
|
||||
|
||||
conf.registerGlobalValue(conf.supybot, 'capabilities',
|
||||
DefaultCapabilities([
|
||||
|
@ -519,7 +519,7 @@ class Value(Group):
|
||||
context."""
|
||||
class Context:
|
||||
def __enter__(self2):
|
||||
self2._old_value = self.value
|
||||
self2._old_value = self()
|
||||
self.setValue(value)
|
||||
def __exit__(self2, exc_type, exc_value, traceback):
|
||||
self.setValue(self2._old_value)
|
||||
@ -559,7 +559,7 @@ class Boolean(Value):
|
||||
v = utils.str.toBool(s)
|
||||
except ValueError:
|
||||
if s.strip().lower() == 'toggle':
|
||||
v = not self.value
|
||||
v = not self()
|
||||
else:
|
||||
self.error(s)
|
||||
self.setValue(v)
|
||||
@ -660,7 +660,7 @@ class String(Value):
|
||||
return any([x not in self._printable for x in s]) and s.strip() != s
|
||||
|
||||
def __str__(self):
|
||||
s = self.value
|
||||
s = self()
|
||||
if self._needsQuoting(s):
|
||||
s = repr(s)
|
||||
return s
|
||||
@ -798,16 +798,18 @@ class Regexp(Value):
|
||||
super().setValue(v)
|
||||
|
||||
def __call__(self):
|
||||
if self.value is None:
|
||||
value = super().__call__()
|
||||
if value is None:
|
||||
return None
|
||||
else:
|
||||
return self.value[1]
|
||||
return value[1]
|
||||
|
||||
def __str__(self):
|
||||
if self.value is None:
|
||||
value = super().__call__()
|
||||
if value is None:
|
||||
return ''
|
||||
else:
|
||||
return self.value[0]
|
||||
return value[0]
|
||||
|
||||
class SeparatedListOf(Value):
|
||||
__slots__ = ()
|
||||
|
Loading…
Reference in New Issue
Block a user