From cb48912db6d3dec473d73f1cfa3754547034896f Mon Sep 17 00:00:00 2001 From: James Vega Date: Sun, 3 Oct 2010 14:58:38 -0400 Subject: [PATCH 1/6] Services: Correct formatting of "isn't registered" log. Closes: Sf#3075937 Signed-off-by: James Vega --- plugins/Services/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Services/plugin.py b/plugins/Services/plugin.py index e5882573b..1d17a8085 100644 --- a/plugins/Services/plugin.py +++ b/plugins/Services/plugin.py @@ -244,7 +244,7 @@ class Services(callbacks.Plugin): # You have been unbanned from (oftc) irc.sendMsg(networkGroup.channels.join(channel)) elif 'isn\'t registered' in s: - self.log.warning('Received "%s isn\'t registered" from ChanServ %', + self.log.warning('Received "%s isn\'t registered" from ChanServ %s', channel, on) elif 'this channel has been registered' in s: self.log.debug('Got "Registered channel" from ChanServ %s.', on) From 543e78828b258fe764017e95ebdd30d39fd74555 Mon Sep 17 00:00:00 2001 From: James Vega Date: Mon, 6 Jun 2011 21:44:15 -0400 Subject: [PATCH 2/6] Add utils.net.isIPV4, with utils.net.isIP checking v4 or v6 Signed-off-by: James Vega --- src/conf.py | 4 ++-- src/ircutils.py | 7 ++++--- src/utils/net.py | 20 ++++++++++++++++---- test/test_utils.py | 6 ++---- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/conf.py b/src/conf.py index b00b495c4..efc87aadd 100644 --- a/src/conf.py +++ b/src/conf.py @@ -1,6 +1,6 @@ ### # Copyright (c) 2002-2005, Jeremiah Fincher -# Copyright (c) 2008-2009, James Vega +# Copyright (c) 2008-2009,2011, James Vega # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -1031,7 +1031,7 @@ registerGlobalValue(supybot, 'defaultIgnore', class IP(registry.String): """Value must be a valid IP.""" def setValue(self, v): - if v and not (utils.net.isIP(v) or utils.net.isIPV6(v)): + if v and not utils.net.isIP(v): self.error() else: registry.String.setValue(self, v) diff --git a/src/ircutils.py b/src/ircutils.py index 815259060..7cfa70568 100644 --- a/src/ircutils.py +++ b/src/ircutils.py @@ -1,5 +1,6 @@ ### # Copyright (c) 2002-2005, Jeremiah Fincher +# Copyright (c) 2011, James Vega # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -190,7 +191,7 @@ def banmask(hostmask): """ assert isUserHostmask(hostmask) host = hostFromHostmask(hostmask) - if utils.net.isIP(host): + if utils.net.isIPV4(host): L = host.split('.') L[-1] = '*' return '*!*@' + '.'.join(L) @@ -461,8 +462,8 @@ def replyTo(msg): return msg.nick def dccIP(ip): - """Returns in IP in the proper for DCC.""" - assert utils.net.isIP(ip), \ + """Returns an IP in the proper for DCC.""" + assert utils.net.isIPV4(ip), \ 'argument must be a string ip in xxx.yyy.zzz.www format.' i = 0 x = 256**3 diff --git a/src/utils/net.py b/src/utils/net.py index fa78fdcc3..ffe8c2005 100644 --- a/src/utils/net.py +++ b/src/utils/net.py @@ -1,5 +1,6 @@ ### # Copyright (c) 2002-2005, Jeremiah Fincher +# Copyright (c) 2011, James Vega # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -44,7 +45,7 @@ def getSocket(host): """ addrinfo = socket.getaddrinfo(host, None) host = addrinfo[0][4][0] - if isIP(host): + if isIPV4(host): return socket.socket(socket.AF_INET, socket.SOCK_STREAM) elif isIPV6(host): return socket.socket(socket.AF_INET6, socket.SOCK_STREAM) @@ -52,16 +53,27 @@ def getSocket(host): raise socket.error, 'Something wonky happened.' def isIP(s): - """Returns whether or not a given string is an IPV4 address. + """Returns whether or not a given string is an IP address. >>> isIP('255.255.255.255') 1 - >>> isIP('abc.abc.abc.abc') + >>> isIP('::1') + 0 + """ + return isIPV4(s) or isIPV6(s) + +def isIPV4(s): + """Returns whether or not a given string is an IPV4 address. + + >>> isIPV4('255.255.255.255') + 1 + + >>> isIPV4('abc.abc.abc.abc') 0 """ try: - return bool(socket.inet_aton(s)) + return bool(socket.inet_pton(socket.AF_INET, s)) except socket.error: return False diff --git a/test/test_utils.py b/test/test_utils.py index c61132181..82d8efb3f 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -1,6 +1,6 @@ ### # Copyright (c) 2002-2005, Jeremiah Fincher -# Copyright (c) 2009, James Vega +# Copyright (c) 2009,2011, James Vega # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -510,11 +510,9 @@ class NetTest(SupyTestCase): isIP = utils.net.isIP self.failIf(isIP('a.b.c')) self.failIf(isIP('256.0.0.0')) - self.failUnless(isIP('127.1')) self.failUnless(isIP('0.0.0.0')) self.failUnless(isIP('100.100.100.100')) - # This test is too flaky to bother with. - # self.failUnless(utils.isIP('255.255.255.255')) + self.failUnless(isIP('255.255.255.255')) def testIsIPV6(self): f = utils.net.isIPV6 From d56381436c3dc9e574384a3c935ecf18fbb024f7 Mon Sep 17 00:00:00 2001 From: James Vega Date: Mon, 6 Jun 2011 22:28:35 -0400 Subject: [PATCH 3/6] Update Internet.dns to handle IPv6 IPs and responses Signed-off-by: James Vega --- plugins/Internet/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Internet/plugin.py b/plugins/Internet/plugin.py index 490c9165c..eb5354394 100644 --- a/plugins/Internet/plugin.py +++ b/plugins/Internet/plugin.py @@ -1,6 +1,6 @@ ### # Copyright (c) 2003-2005, Jeremiah Fincher -# Copyright (c) 2010, James Vega +# Copyright (c) 2010-2011, James Vega # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -53,7 +53,7 @@ class Internet(callbacks.Plugin): irc.reply(hostname) else: try: - ip = socket.gethostbyname(host) + ip = socket.getaddrinfo(host, None)[0][4][0] if ip == '64.94.110.11': # Verisign sucks! irc.reply('Host not found.') else: From b0e595fbd2e9b244738f4f8b1b5b88831583ad03 Mon Sep 17 00:00:00 2001 From: James Vega Date: Mon, 6 Jun 2011 22:29:21 -0400 Subject: [PATCH 4/6] Update Internet.hexip to handle IPv6 Signed-off-by: James Vega --- plugins/Internet/plugin.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/Internet/plugin.py b/plugins/Internet/plugin.py index eb5354394..de94afcd9 100644 --- a/plugins/Internet/plugin.py +++ b/plugins/Internet/plugin.py @@ -149,12 +149,22 @@ class Internet(callbacks.Plugin): Returns the hexadecimal IP for that IP. """ - quads = ip.split('.') ret = "" - for quad in quads: - i = int(quad) - ret += '%02x' % i - irc.reply(ret.upper()) + if utils.net.isIPV4(ip): + quads = ip.split('.') + for quad in quads: + i = int(quad) + ret += '%02X' % i + else: + octets = ip.split(':') + for octet in octets: + if octet: + i = int(octet, 16) + ret += '%04X' % i + else: + missing = (8 - len(octets)) * 4 + ret += '0' * missing + irc.reply(ret) hexip = wrap(hexip, ['ip']) From 0cd4939678e5839c85b57460c7c4b000c8fc1751 Mon Sep 17 00:00:00 2001 From: James Vega Date: Tue, 2 Aug 2011 22:19:47 -0400 Subject: [PATCH 5/6] Seen: Anchor nick regexp to ensure valid match. When searching for 'st*ke', 'stryker' would incorrectly match, 'stryke' would be added to the nick set and the subsequent lookup would cause a KeyError. This is fixed both by anchoring the regexp ('^st.*ke$' instead of 'st.*ke') and adding searchNick to the nick set instead of the string that matched the pattern. Closes: Sf#3377381 Signed-off-by: James Vega --- plugins/Seen/plugin.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/plugins/Seen/plugin.py b/plugins/Seen/plugin.py index d5bc6275e..c4255b172 100644 --- a/plugins/Seen/plugin.py +++ b/plugins/Seen/plugin.py @@ -1,6 +1,6 @@ ### # Copyright (c) 2002-2004, Jeremiah Fincher -# Copyright (c) 2010, James Vega +# Copyright (c) 2010-2011, James Vega # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -66,7 +66,7 @@ class SeenDB(plugins.ChannelUserDB): def seenWildcard(self, channel, nick): nicks = ircutils.IrcSet() - nickRe = re.compile('.*'.join(nick.split('*')), re.I) + nickRe = re.compile('^%s$' % '.*'.join(nick.split('*')), re.I) for (searchChan, searchNick) in self.keys(): #print 'chan: %s ... nick: %s' % (searchChan, searchNick) if isinstance(searchNick, int): @@ -75,11 +75,8 @@ class SeenDB(plugins.ChannelUserDB): # are keyed by nick-string continue if ircutils.strEqual(searchChan, channel): - try: - s = nickRe.match(searchNick).group() - except AttributeError: - continue - nicks.add(s) + if nickRe.search(searchNick) is not None: + nicks.add(searchNick) L = [[nick, self.seen(channel, nick)] for nick in nicks] def negativeTime(x): return -x[1][0] From 4661acb3a3e1f6bd5773ead9aa290995cfc2bfa4 Mon Sep 17 00:00:00 2001 From: James Vega Date: Mon, 22 Aug 2011 14:07:39 -0400 Subject: [PATCH 6/6] Honor supybot-test's timeout option and document the units Signed-off-by: James Vega --- scripts/supybot-test | 6 ++++-- src/test.py | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/scripts/supybot-test b/scripts/supybot-test index 2bec1826e..c0a500713 100644 --- a/scripts/supybot-test +++ b/scripts/supybot-test @@ -2,6 +2,7 @@ ### # Copyright (c) 2002-2005, Jeremiah Fincher +# Copyright (c) 2011, James Vega # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -122,9 +123,10 @@ if __name__ == '__main__': parser.add_option('-c', '--clean', action='store_true', default=False, dest='clean', help='Cleans the various data/conf/logs' 'directories before running tests.') - parser.add_option('-t', '--timeout', action='store', type='int', + parser.add_option('-t', '--timeout', action='store', type='float', dest='timeout', - help='Sets the timeout for tests to return responses.') + help='Sets the timeout, in seconds, for tests to return ' + 'responses.') parser.add_option('-v', '--verbose', action='store_true', default=False, help='Sets the verbose flag, logging extra information ' 'about each test that runs.') diff --git a/src/test.py b/src/test.py index f0e2826df..7a3280bbe 100644 --- a/src/test.py +++ b/src/test.py @@ -1,5 +1,6 @@ ### # Copyright (c) 2002-2005, Jeremiah Fincher +# Copyright (c) 2011, James Vega # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -54,6 +55,8 @@ network = True # This is the global list of suites that are to be run. suites = [] +timeout = 10 + originalCallbacksGetHelp = callbacks.getHelp lastGetHelp = 'x'*1000 def cachingGetHelp(method, name=None, doc=None): @@ -110,12 +113,12 @@ class PluginTestCase(SupyTestCase): """Subclass this to write a test case for a plugin. See plugins/Plugin/test.py for an example. """ - timeout = 10 plugins = None cleanConfDir = True cleanDataDir = True config = {} def __init__(self, methodName='runTest'): + self.timeout = timeout originalRunTest = getattr(self, methodName) def runTest(self): run = True