ERepublik & OEIS & Redmine: Fix possible denial of service via memory exhaustion (with %(thing)999999999999s for instance).
parent
77cbf1e5b3
commit
7844cacd77
|
@ -31,6 +31,8 @@
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from string import Template
|
||||||
|
|
||||||
import supybot.utils as utils
|
import supybot.utils as utils
|
||||||
from supybot.commands import *
|
from supybot.commands import *
|
||||||
import supybot.plugins as plugins
|
import supybot.plugins as plugins
|
||||||
|
@ -84,7 +86,8 @@ class ERepublik(callbacks.Plugin):
|
||||||
Returns informations about a citizen with advanced formating."""
|
Returns informations about a citizen with advanced formating."""
|
||||||
citizen = flatten_subdicts(getCitizen(irc, name))
|
citizen = flatten_subdicts(getCitizen(irc, name))
|
||||||
try:
|
try:
|
||||||
irc.replies(map(lambda x:x%citizen, format_.split('\\n')))
|
repl = lambda x:Template(x).safe_substitute(citizen)
|
||||||
|
irc.replies(map(repl, format_.split('\\n')))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise
|
raise
|
||||||
irc.error(_('Invalid format.'), Raise=True)
|
irc.error(_('Invalid format.'), Raise=True)
|
||||||
|
@ -99,10 +102,10 @@ class ERepublik(callbacks.Plugin):
|
||||||
%s""" % doc
|
%s""" % doc
|
||||||
return wrap(f, ['text'], name=name)
|
return wrap(f, ['text'], name=name)
|
||||||
|
|
||||||
info = _gen("""Name: %(name)s (ID: %(id)s), Level: %(level)s, Strength:
|
info = _gen("""Name: $name (ID: $id), Level: $level, Strength:
|
||||||
%(strength)s, Residence: %(residence__country__name)s, Citizenship:
|
$strength, Residence: $residence__country__name, Citizenship:
|
||||||
%(citizenship__name)s, Rank: %(rank__name)s, Party: %(party__name)s, MU:
|
$citizenship__name, Rank: $rank__name, Party: $party__name, MU:
|
||||||
%(army__name)s.
|
$army__name.
|
||||||
""",
|
""",
|
||||||
'info',
|
'info',
|
||||||
'Returns general informations about a citizen.')
|
'Returns general informations about a citizen.')
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
from string import Template
|
||||||
|
|
||||||
import supybot.log as log
|
import supybot.log as log
|
||||||
import supybot.utils as utils
|
import supybot.utils as utils
|
||||||
from supybot.commands import *
|
from supybot.commands import *
|
||||||
|
@ -62,7 +64,8 @@ class OEIS(callbacks.Plugin):
|
||||||
except ParseError:
|
except ParseError:
|
||||||
irc.error(_('Could not parse OEIS answer.'), Raise=True)
|
irc.error(_('Could not parse OEIS answer.'), Raise=True)
|
||||||
if results:
|
if results:
|
||||||
irc.reply(format('%L', map(lambda x:format_ % x, results)))
|
repl = Template(format_).safe_substitute
|
||||||
|
irc.reply(format('%L', map(repl, results)))
|
||||||
else:
|
else:
|
||||||
irc.reply(_('No entry matches this sequence.'))
|
irc.reply(_('No entry matches this sequence.'))
|
||||||
advsearch = wrap(_advsearch, ['something', 'somethingWithoutSpaces'])
|
advsearch = wrap(_advsearch, ['something', 'somethingWithoutSpaces'])
|
||||||
|
@ -75,7 +78,7 @@ class OEIS(callbacks.Plugin):
|
||||||
%s""" % doc
|
%s""" % doc
|
||||||
return wrap(f, ['somethingWithoutSpaces'], name=name)
|
return wrap(f, ['somethingWithoutSpaces'], name=name)
|
||||||
|
|
||||||
names = _gen('%(name)s (%(id)s)', 'names',
|
names = _gen('$name ($id)', 'names',
|
||||||
'Return names of matching entries.')
|
'Return names of matching entries.')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,8 @@ class OEISTestCase(PluginTestCase):
|
||||||
self.assertRegexp('names 15454454651,198448,228454456', 'No entry')
|
self.assertRegexp('names 15454454651,198448,228454456', 'No entry')
|
||||||
|
|
||||||
def testAdvsearch(self):
|
def testAdvsearch(self):
|
||||||
self.assertRegexp('advsearch "%(id)s" 1,2,6,24,120', 'A000142')
|
self.assertRegexp('advsearch "$id" 1,2,6,24,120', 'A000142')
|
||||||
self.assertNotRegexp('advsearch "%(id)s" 1,2,6,24,120', 'factorial')
|
self.assertNotRegexp('advsearch "$id" 1,2,6,24,120', 'factorial')
|
||||||
|
|
||||||
|
|
||||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
||||||
|
|
|
@ -56,22 +56,22 @@ conf.registerChannelValue(Redmine, 'defaultsite',
|
||||||
registry.String('', _("""Default site for this channel.""")))
|
registry.String('', _("""Default site for this channel.""")))
|
||||||
conf.registerGroup(Redmine, 'format')
|
conf.registerGroup(Redmine, 'format')
|
||||||
conf.registerChannelValue(Redmine.format, 'projects',
|
conf.registerChannelValue(Redmine.format, 'projects',
|
||||||
registry.String('%(name)s (%(identifier)s)',
|
registry.String('$name ($identifier)',
|
||||||
_("""Format of projects displayed by @projects.""")))
|
_("""Format of projects displayed by @projects.""")))
|
||||||
conf.registerChannelValue(Redmine.format, 'issues',
|
conf.registerChannelValue(Redmine.format, 'issues',
|
||||||
registry.String('\x02#%(id)i: %(subject)s\x02 (last update: '
|
registry.String('\x02#$id)i: $subject\x02 (last update: '
|
||||||
'%(updated_on)s / status: %(status__name)s)',
|
'$updated_on / status: $status__name)',
|
||||||
_("""Format of issues displayed by @issues.""")))
|
_("""Format of issues displayed by @issues.""")))
|
||||||
conf.registerChannelValue(Redmine.format, 'issue',
|
conf.registerChannelValue(Redmine.format, 'issue',
|
||||||
registry.String('\x02#%(id)i (%(status__name)s)\x02: \x02%(subject)s\x02 '
|
registry.String('\x02#$id)i ($status__name)\x02: \x02$subject\x02 '
|
||||||
'in \x02%(project__name)s\x02 (%(project__id)i). Created by '
|
'in \x02$project__name\x02 ($project__id)i). Created by '
|
||||||
'\x02%(author__name)s\x02 (%(author__id)i) on \x02%(created_on)s\x02, '
|
'\x02$author__name\x02 ($author__id)i) on \x02$created_on\x02, '
|
||||||
'last updated on \x02%(updated_on)s',
|
'last updated on \x02$updated_on',
|
||||||
_("""Format of issues displayed by @issue.""")))
|
_("""Format of issues displayed by @issue.""")))
|
||||||
conf.registerGroup(Redmine.format, 'announces')
|
conf.registerGroup(Redmine.format, 'announces')
|
||||||
conf.registerChannelValue(Redmine.format.announces, 'issue',
|
conf.registerChannelValue(Redmine.format.announces, 'issue',
|
||||||
registry.String('Updated issue: \x02#%(id)i (%(status__name)s)\x02: '
|
registry.String('Updated issue: \x02#$id)i ($status__name)\x02: '
|
||||||
'\x02%(subject)s\x02 in \x02%(project__name)s\x02 (%(project__id)i).',
|
'\x02$subject\x02 in \x02$project__name\x02 ($project__id)i).',
|
||||||
_("""Format of issues displayed by @issue.""")))
|
_("""Format of issues displayed by @issue.""")))
|
||||||
|
|
||||||
conf.registerGroup(Redmine, 'announce')
|
conf.registerGroup(Redmine, 'announce')
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
from string import Template
|
||||||
|
|
||||||
import supybot.conf as conf
|
import supybot.conf as conf
|
||||||
import supybot.utils as utils
|
import supybot.utils as utils
|
||||||
|
@ -189,7 +190,8 @@ class Redmine(callbacks.Plugin):
|
||||||
format_ = self.registryValue('format.announces.issue',
|
format_ = self.registryValue('format.announces.issue',
|
||||||
channel)
|
channel)
|
||||||
for issue in announces:
|
for issue in announces:
|
||||||
s = format_ % flatten_subdicts(issue)
|
repl = flatten_subdicts(issue)
|
||||||
|
s = Template(format_).safe_substitute(repl)
|
||||||
if sys.version_info[0] < 3:
|
if sys.version_info[0] < 3:
|
||||||
s = s.encode('utf8', errors='replace')
|
s = s.encode('utf8', errors='replace')
|
||||||
msg = ircmsgs.privmsg(channel, s)
|
msg = ircmsgs.privmsg(channel, s)
|
||||||
|
@ -255,8 +257,8 @@ class Redmine(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Return the list of projects of the Redmine <site>."""
|
Return the list of projects of the Redmine <site>."""
|
||||||
projects = map(lambda x:self.registryValue('format.projects') % x,
|
repl = Template(self.registryValue('format.projects')).safe_substitute
|
||||||
fetch(site, 'projects')['projects'])
|
projects = map(repl, fetch(site, 'projects')['projects'])
|
||||||
irc.reply(format('%L', projects))
|
irc.reply(format('%L', projects))
|
||||||
|
|
||||||
@internationalizeDocstring
|
@internationalizeDocstring
|
||||||
|
@ -285,8 +287,8 @@ class Redmine(callbacks.Plugin):
|
||||||
new_issues = []
|
new_issues = []
|
||||||
for issue in issues:
|
for issue in issues:
|
||||||
new_issues.append(flatten_subdicts(issue))
|
new_issues.append(flatten_subdicts(issue))
|
||||||
issues = map(lambda x:self.registryValue('format.issues') % x,
|
repl = Template(self.registryValue('format.issues')).safe_substitute
|
||||||
new_issues)
|
issues = map(repl, new_issues)
|
||||||
irc.reply(format('%L', issues))
|
irc.reply(format('%L', issues))
|
||||||
|
|
||||||
@internationalizeDocstring
|
@internationalizeDocstring
|
||||||
|
@ -298,7 +300,8 @@ class Redmine(callbacks.Plugin):
|
||||||
try:
|
try:
|
||||||
issue = fetch(site, 'issues/%i' % issueid)['issue']
|
issue = fetch(site, 'issues/%i' % issueid)['issue']
|
||||||
issue = flatten_subdicts(issue)
|
issue = flatten_subdicts(issue)
|
||||||
irc.reply(self.registryValue('format.issue') % issue)
|
irc.reply(Template(self.registryValue('format.issue')) \
|
||||||
|
.safe_substitute(issue))
|
||||||
except ResourceNotFound:
|
except ResourceNotFound:
|
||||||
irc.error(_('Issue not found.'), Raise=True)
|
irc.error(_('Issue not found.'), Raise=True)
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
|
|
Loading…
Reference in New Issue