mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-12-26 12:43:09 +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))
|
return s * (1024//len(s))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.value
|
return self()
|
||||||
|
|
||||||
conf.registerGlobalValue(BadWords, 'nastyChars',
|
conf.registerGlobalValue(BadWords, 'nastyChars',
|
||||||
String256('!@#&', _("""Determines what characters will replace bad words; a
|
String256('!@#&', _("""Determines what characters will replace bad words; a
|
||||||
|
@ -50,6 +50,7 @@ class Smileys(registry.Value):
|
|||||||
self.setValue(L)
|
self.setValue(L)
|
||||||
|
|
||||||
def setValue(self, v):
|
def setValue(self, v):
|
||||||
|
self._lastModified = registry.monotonic_time()
|
||||||
self.s = ' '.join(v)
|
self.s = ' '.join(v)
|
||||||
self.value = re.compile('|'.join(map(re.escape, v)))
|
self.value = re.compile('|'.join(map(re.escape, v)))
|
||||||
|
|
||||||
|
@ -499,12 +499,12 @@ class Config(callbacks.Plugin):
|
|||||||
netgroup = group.get(':' + network.network)
|
netgroup = group.get(':' + network.network)
|
||||||
changroup = netgroup.get(channel)
|
changroup = netgroup.get(channel)
|
||||||
checkCanSetValue(irc, msg, changroup)
|
checkCanSetValue(irc, msg, changroup)
|
||||||
changroup._setValue(netgroup.value, inherited=True)
|
changroup._setValue(netgroup(), inherited=True)
|
||||||
|
|
||||||
# reset group.#channel
|
# reset group.#channel
|
||||||
changroup = group.get(channel)
|
changroup = group.get(channel)
|
||||||
checkCanSetValue(irc, msg, changroup)
|
checkCanSetValue(irc, msg, changroup)
|
||||||
changroup._setValue(group.value, inherited=True)
|
changroup._setValue(group(), inherited=True)
|
||||||
|
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
channel = wrap(channel, [
|
channel = wrap(channel, [
|
||||||
@ -523,7 +523,7 @@ class Config(callbacks.Plugin):
|
|||||||
# reset group.#channel
|
# reset group.#channel
|
||||||
changroup = group.get(':' + network.network)
|
changroup = group.get(':' + network.network)
|
||||||
checkCanSetValue(irc, msg, changroup)
|
checkCanSetValue(irc, msg, changroup)
|
||||||
changroup._setValue(group.value, inherited=True)
|
changroup._setValue(group(), inherited=True)
|
||||||
|
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
network = wrap(network, ['networkIrc', 'settableConfigVar'])
|
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 and '
|
||||||
r'supybot.reply.whenAddressedBy.strings.\:test.#test')
|
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):
|
def testDefault(self):
|
||||||
self.assertNotError('config default '
|
self.assertNotError('config default '
|
||||||
'supybot.replies.genericNoCapability')
|
'supybot.replies.genericNoCapability')
|
||||||
|
@ -43,7 +43,7 @@ class IrcLogLevel(log.ValidLogLevel):
|
|||||||
minimumLevel = logging.INFO
|
minimumLevel = logging.INFO
|
||||||
def setValue(self, v):
|
def setValue(self, v):
|
||||||
log.ValidLogLevel.setValue(self, v)
|
log.ValidLogLevel.setValue(self, v)
|
||||||
_ircHandler.setLevel(self.value)
|
_ircHandler.setLevel(self())
|
||||||
|
|
||||||
class ValidChannelOrNick(registry.String):
|
class ValidChannelOrNick(registry.String):
|
||||||
"""Value must be a valid channel or a valid nick."""
|
"""Value must be a valid channel or a valid nick."""
|
||||||
|
@ -791,7 +791,7 @@ class ValidQuotes(registry.Value):
|
|||||||
super(ValidQuotes, self).setValue(v)
|
super(ValidQuotes, self).setValue(v)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.value)
|
return str(self())
|
||||||
|
|
||||||
registerChannelValue(supybot.commands, 'quotes',
|
registerChannelValue(supybot.commands, 'quotes',
|
||||||
ValidQuotes('"', _("""Determines what characters are valid for quoting
|
ValidQuotes('"', _("""Determines what characters are valid for quoting
|
||||||
@ -1030,7 +1030,7 @@ class Databases(registry.SpaceSeparatedListOfStrings):
|
|||||||
return v
|
return v
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
return ' '.join(self.value)
|
return ' '.join(self())
|
||||||
|
|
||||||
registerGlobalValue(supybot, 'databases',
|
registerGlobalValue(supybot, 'databases',
|
||||||
Databases([], _("""Determines what databases are available for use. If this
|
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:
|
if v < supybot.drivers.poll() or v < 1:
|
||||||
self.error()
|
self.error()
|
||||||
registry.PositiveInteger.setValue(self, v)
|
registry.PositiveInteger.setValue(self, v)
|
||||||
socket.setdefaulttimeout(self.value)
|
socket.setdefaulttimeout(self())
|
||||||
|
|
||||||
registerGlobalValue(supybot, 'defaultSocketTimeout',
|
registerGlobalValue(supybot, 'defaultSocketTimeout',
|
||||||
SocketTimeout(10, _("""Determines what the default timeout for socket
|
SocketTimeout(10, _("""Determines what the default timeout for socket
|
||||||
|
@ -77,12 +77,12 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
self.writeCheckTime = None
|
self.writeCheckTime = None
|
||||||
self.nextReconnectTime = None
|
self.nextReconnectTime = None
|
||||||
self.resetDelay()
|
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 '
|
drivers.log.error('The Socket driver can not connect to SSL '
|
||||||
'servers for your Python version.')
|
'servers for your Python version.')
|
||||||
self.ssl = False
|
self.ssl = False
|
||||||
else:
|
else:
|
||||||
self.ssl = self.networkGroup.get('ssl').value
|
self.ssl = self.networkGroup.get('ssl')()
|
||||||
self.connect()
|
self.connect()
|
||||||
|
|
||||||
def getDelay(self):
|
def getDelay(self):
|
||||||
|
@ -1325,11 +1325,11 @@ class DefaultCapabilities(SpaceSeparatedListOfCapabilities):
|
|||||||
# it's still an improvement, raising the bar for potential crackers.
|
# it's still an improvement, raising the bar for potential crackers.
|
||||||
def setValue(self, v, allowDefaultOwner=conf.allowDefaultOwner):
|
def setValue(self, v, allowDefaultOwner=conf.allowDefaultOwner):
|
||||||
registry.SpaceSeparatedListOfStrings.setValue(self, v)
|
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('*** You must run supybot with the --allow-default-owner')
|
||||||
print('*** option in order to allow a default capability of owner.')
|
print('*** option in order to allow a default capability of owner.')
|
||||||
print('*** Don\'t do that, it\'s dumb.')
|
print('*** Don\'t do that, it\'s dumb.')
|
||||||
self.value.add('-owner')
|
self().add('-owner')
|
||||||
|
|
||||||
conf.registerGlobalValue(conf.supybot, 'capabilities',
|
conf.registerGlobalValue(conf.supybot, 'capabilities',
|
||||||
DefaultCapabilities([
|
DefaultCapabilities([
|
||||||
|
@ -519,7 +519,7 @@ class Value(Group):
|
|||||||
context."""
|
context."""
|
||||||
class Context:
|
class Context:
|
||||||
def __enter__(self2):
|
def __enter__(self2):
|
||||||
self2._old_value = self.value
|
self2._old_value = self()
|
||||||
self.setValue(value)
|
self.setValue(value)
|
||||||
def __exit__(self2, exc_type, exc_value, traceback):
|
def __exit__(self2, exc_type, exc_value, traceback):
|
||||||
self.setValue(self2._old_value)
|
self.setValue(self2._old_value)
|
||||||
@ -559,7 +559,7 @@ class Boolean(Value):
|
|||||||
v = utils.str.toBool(s)
|
v = utils.str.toBool(s)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
if s.strip().lower() == 'toggle':
|
if s.strip().lower() == 'toggle':
|
||||||
v = not self.value
|
v = not self()
|
||||||
else:
|
else:
|
||||||
self.error(s)
|
self.error(s)
|
||||||
self.setValue(v)
|
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
|
return any([x not in self._printable for x in s]) and s.strip() != s
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
s = self.value
|
s = self()
|
||||||
if self._needsQuoting(s):
|
if self._needsQuoting(s):
|
||||||
s = repr(s)
|
s = repr(s)
|
||||||
return s
|
return s
|
||||||
@ -798,16 +798,18 @@ class Regexp(Value):
|
|||||||
super().setValue(v)
|
super().setValue(v)
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
if self.value is None:
|
value = super().__call__()
|
||||||
|
if value is None:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return self.value[1]
|
return value[1]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.value is None:
|
value = super().__call__()
|
||||||
|
if value is None:
|
||||||
return ''
|
return ''
|
||||||
else:
|
else:
|
||||||
return self.value[0]
|
return value[0]
|
||||||
|
|
||||||
class SeparatedListOf(Value):
|
class SeparatedListOf(Value):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
Loading…
Reference in New Issue
Block a user